]> granicus.if.org Git - postgresql/commitdiff
This patch moves some code for preprocessing FOR UPDATE from
authorNeil Conway <neilc@samurai.com>
Thu, 17 Mar 2005 23:45:09 +0000 (23:45 +0000)
committerNeil Conway <neilc@samurai.com>
Thu, 17 Mar 2005 23:45:09 +0000 (23:45 +0000)
grouping_planner() to preprocess_targetlist(), according to a comment
in grouping_planner(). I think the refactoring makes sense, and moves
some extraneous details out of grouping_planner().

src/backend/optimizer/plan/planner.c
src/backend/optimizer/prep/preptlist.c
src/include/optimizer/prep.h

index d9e3ad0f84d06fabc423a7b6f985d02c892d5f20..969f3711389e252a8eb52bac9462bf64a10b8ca0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.179 2005/03/10 23:21:22 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.180 2005/03/17 23:44:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,7 +36,6 @@
 #include "optimizer/subselect.h"
 #include "optimizer/tlist.h"
 #include "optimizer/var.h"
-#include "parser/analyze.h"
 #include "parser/parsetree.h"
 #include "parser/parse_expr.h"
 #include "parser/parse_oper.h"
@@ -698,65 +697,8 @@ grouping_planner(Query *parse, double tuple_fraction)
 
                MemSet(&agg_counts, 0, sizeof(AggClauseCounts));
 
-               /* Preprocess targetlist in case we are inside an INSERT/UPDATE. */
-               tlist = preprocess_targetlist(tlist,
-                                                                         parse->commandType,
-                                                                         parse->resultRelation,
-                                                                         parse->rtable);
-
-               /*
-                * Add TID targets for rels selected FOR UPDATE (should this be
-                * done in preprocess_targetlist?).  The executor uses the TID to
-                * know which rows to lock, much as for UPDATE or DELETE.
-                */
-               if (parse->rowMarks)
-               {
-                       ListCell   *l;
-
-                       /*
-                        * We've got trouble if the FOR UPDATE appears inside
-                        * grouping, since grouping renders a reference to individual
-                        * tuple CTIDs invalid.  This is also checked at parse time,
-                        * but that's insufficient because of rule substitution, query
-                        * pullup, etc.
-                        */
-                       CheckSelectForUpdate(parse);
-
-                       /*
-                        * Currently the executor only supports FOR UPDATE at top
-                        * level
-                        */
-                       if (PlannerQueryLevel > 1)
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                errmsg("SELECT FOR UPDATE is not allowed in subqueries")));
-
-                       foreach(l, parse->rowMarks)
-                       {
-                               Index           rti = lfirst_int(l);
-                               char       *resname;
-                               Resdom     *resdom;
-                               Var                *var;
-                               TargetEntry *ctid;
-
-                               resname = (char *) palloc(32);
-                               snprintf(resname, 32, "ctid%u", rti);
-                               resdom = makeResdom(list_length(tlist) + 1,
-                                                                       TIDOID,
-                                                                       -1,
-                                                                       resname,
-                                                                       true);
-
-                               var = makeVar(rti,
-                                                         SelfItemPointerAttributeNumber,
-                                                         TIDOID,
-                                                         -1,
-                                                         0);
-
-                               ctid = makeTargetEntry(resdom, (Expr *) var);
-                               tlist = lappend(tlist, ctid);
-                       }
-               }
+               /* Preprocess targetlist */
+               tlist = preprocess_targetlist(parse, tlist);
 
                /*
                 * Generate appropriate target list for subplan; may be different
index 3ca5195e7cb7a7fcde9683748d700944385b0f80..69dc30c63d5da7a8735eda1c74e532806ae06834 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.72 2004/12/31 22:00:20 pgsql Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.73 2005/03/17 23:44:52 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,6 +26,8 @@
 #include "catalog/pg_type.h"
 #include "nodes/makefuncs.h"
 #include "optimizer/prep.h"
+#include "optimizer/subselect.h"
+#include "parser/analyze.h"
 #include "parser/parsetree.h"
 #include "parser/parse_coerce.h"
 
@@ -41,11 +43,12 @@ static List *expand_targetlist(List *tlist, int command_type,
  *       Returns the new targetlist.
  */
 List *
-preprocess_targetlist(List *tlist,
-                                         int command_type,
-                                         Index result_relation,
-                                         List *range_table)
+preprocess_targetlist(Query *parse, List *tlist)
 {
+       int             result_relation = parse->resultRelation;
+       List   *range_table = parse->rtable;
+       CmdType command_type = parse->commandType;
+
        /*
         * Sanity check: if there is a result relation, it'd better be a real
         * relation not a subquery.  Else parser or rewriter messed up.
@@ -99,6 +102,60 @@ preprocess_targetlist(List *tlist,
                tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) var));
        }
 
+       /*
+        * Add TID targets for rels selected FOR UPDATE.  The executor
+        * uses the TID to know which rows to lock, much as for UPDATE or
+        * DELETE.
+        */
+       if (parse->rowMarks)
+       {
+               ListCell   *l;
+
+               /*
+                * We've got trouble if the FOR UPDATE appears inside
+                * grouping, since grouping renders a reference to individual
+                * tuple CTIDs invalid.  This is also checked at parse time,
+                * but that's insufficient because of rule substitution, query
+                * pullup, etc.
+                */
+               CheckSelectForUpdate(parse);
+
+               /*
+                * Currently the executor only supports FOR UPDATE at top
+                * level
+                */
+               if (PlannerQueryLevel > 1)
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                        errmsg("SELECT FOR UPDATE is not allowed in subqueries")));
+
+               foreach(l, parse->rowMarks)
+               {
+                       Index           rti = lfirst_int(l);
+                       char       *resname;
+                       Resdom     *resdom;
+                       Var                *var;
+                       TargetEntry *ctid;
+
+                       resname = (char *) palloc(32);
+                       snprintf(resname, 32, "ctid%u", rti);
+                       resdom = makeResdom(list_length(tlist) + 1,
+                                                               TIDOID,
+                                                               -1,
+                                                               resname,
+                                                               true);
+
+                       var = makeVar(rti,
+                                                 SelfItemPointerAttributeNumber,
+                                                 TIDOID,
+                                                 -1,
+                                                 0);
+
+                       ctid = makeTargetEntry(resdom, (Expr *) var);
+                       tlist = lappend(tlist, ctid);
+               }
+       }
+
        return tlist;
 }
 
index 5ce9b6cd7667e9b6ada53639e68589d75dc9ea2d..223c86eb1e5813229795e1ed0dc46ceec6fcad07 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/optimizer/prep.h,v 1.47 2004/12/31 22:03:36 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/prep.h,v 1.48 2005/03/17 23:45:09 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,8 +42,7 @@ extern Node *flatten_andors(Node *node);
 /*
  * prototypes for preptlist.c
  */
-extern List *preprocess_targetlist(List *tlist, int command_type,
-                                         Index result_relation, List *range_table);
+extern List *preprocess_targetlist(Query *parse, List *tlist);
 
 /*
  * prototypes for prepunion.c