diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-12-06 23:55:19 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-12-06 23:55:19 +0000 |
commit | 73d2a3595a3d14e64cb4dbcc09e90308a486e79f (patch) | |
tree | a0fd394b68e558c62dbf69bec6706651f98663ec /src/backend/optimizer | |
parent | db0de2241dba1663aaa2fe11018b8d7885d116bf (diff) | |
download | postgresql-73d2a3595a3d14e64cb4dbcc09e90308a486e79f.tar.gz postgresql-73d2a3595a3d14e64cb4dbcc09e90308a486e79f.zip |
Clean up handling of FOR UPDATE inside views and subselects ... make it
work where we can (given that the executor only handles it at top level)
and generate an error where we can't. Note that while the parser has
been allowing views to say SELECT FOR UPDATE for a few weeks now, that
hasn't actually worked until just now.
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 7a1151f0c9a..7c73a878242 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.96 2000/11/12 00:36:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.97 2000/12/06 23:55:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,6 +25,7 @@ #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 "rewrite/rewriteManip.h" @@ -255,6 +256,7 @@ pull_up_subqueries(Query *parse, Node *jtnode) int rtoffset; Node *subjointree; List *subtlist; + List *l; /* * First, recursively pull up the subquery's subqueries, @@ -290,9 +292,21 @@ pull_up_subqueries(Query *parse, Node *jtnode) ResolveNew(parse->havingQual, varno, 0, subtlist, CMD_SELECT, 0); /* + * Pull up any FOR UPDATE markers, too. + */ + foreach(l, subquery->rowMarks) + { + int submark = lfirsti(l); + + parse->rowMarks = lappendi(parse->rowMarks, + submark + rtoffset); + } + /* * Miscellaneous housekeeping. */ parse->hasSubLinks |= subquery->hasSubLinks; + /* subquery won't be pulled up if it hasAggs, so no work there */ + /* * Return the adjusted subquery jointree to replace the * RangeTblRef entry in my jointree. @@ -341,11 +355,6 @@ is_simple_subquery(Query *subquery) subquery->isPortal) elog(ERROR, "is_simple_subquery: subquery is bogus"); /* - * Also check for currently-unsupported features. - */ - if (subquery->rowMarks) - elog(ERROR, "FOR UPDATE is not supported in subselects"); - /* * Can't currently pull up a query with setops. * Maybe after querytree redesign... */ @@ -708,6 +717,13 @@ grouping_planner(Query *parse, double tuple_fraction) tlist = postprocess_setop_tlist(result_plan->targetlist, tlist); /* + * Can't handle FOR UPDATE here (parser should have checked already, + * but let's make sure). + */ + if (parse->rowMarks) + elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT"); + + /* * We set current_pathkeys NIL indicating we do not know sort * order. This is correct when the top set operation is UNION ALL, * since the appended-together results are unsorted even if the @@ -744,6 +760,18 @@ grouping_planner(Query *parse, double tuple_fraction) { List *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) + elog(ERROR, "SELECT FOR UPDATE is not allowed in subselects"); + foreach(l, parse->rowMarks) { Index rti = lfirsti(l); |