diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-04-04 01:21:48 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-04-04 01:21:48 +0000 |
commit | 1c72a8a37a446eebb09bcfb5eb6bad7ddd1655c8 (patch) | |
tree | a886d5b14699e0a3a271cc2b2ccd5a1e5dff8b2a /src/backend/optimizer/plan/subselect.c | |
parent | 8cdabf074118ab0c86423891cc0b85c9c94939e7 (diff) | |
download | postgresql-1c72a8a37a446eebb09bcfb5eb6bad7ddd1655c8.tar.gz postgresql-1c72a8a37a446eebb09bcfb5eb6bad7ddd1655c8.zip |
Fix extremely nasty little bug observed when a sub-SELECT appears in
WHERE in a place where it can be part of a nestloop inner indexqual.
As the code stood, it put the same physical sub-Plan node into both
indxqual and indxqualorig of the IndexScan plan node. That confused
later processing in the optimizer (which expected that tracing the
subPlan list would visit each subplan node exactly once), and would
probably have blown up in the executor if the planner hadn't choked first.
Fix by making the 'fixed' indexqual be a complete deep copy of the
original indexqual, rather than trying to share nodes below the topmost
operator node. This had further ramifications though, because we were
making the aforesaid list of sub-Plan nodes during SS_process_sublinks
which is run before construction of the 'fixed' indexqual, meaning that
the copy of the sub-Plan didn't show up in that list. Fix by rearranging
logic so that the sub-Plan list is built by the final set_plan_references
pass, not in SS_process_sublinks. This may sound like a mess, but it's
actually a good deal cleaner now than it was before, because we are no
longer dependent on the assumption that planning will never make a copy
of a sub-Plan node.
Diffstat (limited to 'src/backend/optimizer/plan/subselect.c')
-rw-r--r-- | src/backend/optimizer/plan/subselect.c | 41 |
1 files changed, 11 insertions, 30 deletions
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 3928f578360..b77d8b586f6 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.33 2000/03/21 05:12:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.34 2000/04/04 01:21:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -442,6 +442,12 @@ set_unioni(List *l1, List *l2) * finalize_primnode: build lists of subplans and params appearing * in the given expression tree. NOTE: items are added to lists passed in, * so caller must initialize lists to NIL before first call! + * + * Note: the subplan list that is constructed here and assigned to the + * plan's subPlan field will be replaced with an up-to-date list in + * set_plan_references(). We could almost dispense with building this + * subplan list at all; I believe the only place that uses it is the + * check in make_subplan to see whether a subselect has any subselects. */ typedef struct finalize_primnode_results { @@ -604,6 +610,10 @@ SS_finalize_plan(Plan *plan) case T_IndexScan: finalize_primnode((Node *) ((IndexScan *) plan)->indxqual, &results); + /* we need not look at indxqualorig, since it will have the + * same param references as indxqual, and we aren't really + * concerned yet about having a complete subplan list. + */ break; case T_MergeJoin: @@ -670,32 +680,3 @@ SS_finalize_plan(Plan *plan) return results.paramids; } - -/* - * Construct a list of all subplans found within the given node tree. - */ - -static bool SS_pull_subplan_walker(Node *node, List **listptr); - -List * -SS_pull_subplan(Node *expr) -{ - List *result = NIL; - - SS_pull_subplan_walker(expr, &result); - return result; -} - -static bool -SS_pull_subplan_walker(Node *node, List **listptr) -{ - if (node == NULL) - return false; - if (is_subplan(node)) - { - *listptr = lappend(*listptr, ((Expr *) node)->oper); - /* fall through to check args to subplan */ - } - return expression_tree_walker(node, SS_pull_subplan_walker, - (void *) listptr); -} |