refactor preprocess_targetlist - Mailing list pgsql-patches
From | Neil Conway |
---|---|
Subject | refactor preprocess_targetlist |
Date | |
Msg-id | 42392693.5050707@samurai.com Whole thread Raw |
Responses |
Re: refactor preprocess_targetlist
|
List | pgsql-patches |
This patch moves some code for preprocessing FOR UPDATE from 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(). Barring any objections, I'll apply this to HEAD tonight or tomorrow. -Neil Index: src/backend/optimizer/plan/planner.c =================================================================== RCS file: /var/lib/cvs/pgsql/src/backend/optimizer/plan/planner.c,v retrieving revision 1.179 diff -c -r1.179 planner.c *** src/backend/optimizer/plan/planner.c 10 Mar 2005 23:21:22 -0000 1.179 --- src/backend/optimizer/plan/planner.c 17 Mar 2005 06:33:03 -0000 *************** *** 36,42 **** #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" --- 36,41 ---- *************** *** 698,762 **** 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); ! } ! } /* * Generate appropriate target list for subplan; may be different --- 697,704 ---- MemSet(&agg_counts, 0, sizeof(AggClauseCounts)); ! /* Preprocess targetlist */ ! tlist = preprocess_targetlist(parse, tlist); /* * Generate appropriate target list for subplan; may be different Index: src/backend/optimizer/prep/preptlist.c =================================================================== RCS file: /var/lib/cvs/pgsql/src/backend/optimizer/prep/preptlist.c,v retrieving revision 1.72 diff -c -r1.72 preptlist.c *** src/backend/optimizer/prep/preptlist.c 31 Dec 2004 22:00:20 -0000 1.72 --- src/backend/optimizer/prep/preptlist.c 17 Mar 2005 06:34:37 -0000 *************** *** 26,31 **** --- 26,33 ---- #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,51 **** * Returns the new targetlist. */ List * ! preprocess_targetlist(List *tlist, ! int command_type, ! Index result_relation, ! List *range_table) { /* * Sanity check: if there is a result relation, it'd better be a real * relation not a subquery. Else parser or rewriter messed up. --- 43,54 ---- * Returns the new targetlist. */ List * ! 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,104 **** --- 102,161 ---- 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: src/include/optimizer/prep.h =================================================================== RCS file: /var/lib/cvs/pgsql/src/include/optimizer/prep.h,v retrieving revision 1.47 diff -c -r1.47 prep.h *** src/include/optimizer/prep.h 31 Dec 2004 22:03:36 -0000 1.47 --- src/include/optimizer/prep.h 17 Mar 2005 06:22:32 -0000 *************** *** 42,49 **** /* * prototypes for preptlist.c */ ! extern List *preprocess_targetlist(List *tlist, int command_type, ! Index result_relation, List *range_table); /* * prototypes for prepunion.c --- 42,48 ---- /* * prototypes for preptlist.c */ ! extern List *preprocess_targetlist(Query *parse, List *tlist); /* * prototypes for prepunion.c
pgsql-patches by date: