aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes/copyfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-04-04 01:21:48 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-04-04 01:21:48 +0000
commit1c72a8a37a446eebb09bcfb5eb6bad7ddd1655c8 (patch)
treea886d5b14699e0a3a271cc2b2ccd5a1e5dff8b2a /src/backend/nodes/copyfuncs.c
parent8cdabf074118ab0c86423891cc0b85c9c94939e7 (diff)
downloadpostgresql-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/nodes/copyfuncs.c')
-rw-r--r--src/backend/nodes/copyfuncs.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 836687240d5..41918cda142 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -8,15 +8,15 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.110 2000/03/22 22:08:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.111 2000/04/04 01:21:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "optimizer/clauses.h"
#include "optimizer/planmain.h"
-#include "optimizer/subselect.h"
/*
@@ -88,9 +88,10 @@ CopyPlanFields(Plan *from, Plan *newnode)
newnode->locParam = listCopy(from->locParam);
newnode->chgParam = listCopy(from->chgParam);
Node_Copy(from, newnode, initPlan);
+ /* subPlan list must point to subplans in the new subtree, not the old */
if (from->subPlan != NIL)
- newnode->subPlan = nconc(SS_pull_subplan((Node *) newnode->targetlist),
- SS_pull_subplan((Node *) newnode->qual));
+ newnode->subPlan = nconc(pull_subplans((Node *) newnode->targetlist),
+ pull_subplans((Node *) newnode->qual));
else
newnode->subPlan = NIL;
newnode->nParamExec = from->nParamExec;
@@ -142,7 +143,7 @@ _copyResult(Result *from)
*/
if (from->plan.subPlan != NIL)
newnode->plan.subPlan = nconc(newnode->plan.subPlan,
- SS_pull_subplan(newnode->resconstantqual));
+ pull_subplans(newnode->resconstantqual));
return newnode;
}
@@ -252,6 +253,17 @@ _copyIndexScan(IndexScan *from)
Node_Copy(from, newnode, indxqualorig);
newnode->indxorderdir = from->indxorderdir;
+ /*
+ * We must add subplans in index quals to the new plan's subPlan list
+ */
+ if (from->scan.plan.subPlan != NIL)
+ {
+ newnode->scan.plan.subPlan = nconc(newnode->scan.plan.subPlan,
+ pull_subplans((Node *) newnode->indxqual));
+ newnode->scan.plan.subPlan = nconc(newnode->scan.plan.subPlan,
+ pull_subplans((Node *) newnode->indxqualorig));
+ }
+
return newnode;
}
@@ -358,6 +370,13 @@ _copyMergeJoin(MergeJoin *from)
*/
Node_Copy(from, newnode, mergeclauses);
+ /*
+ * We must add subplans in mergeclauses to the new plan's subPlan list
+ */
+ if (from->join.subPlan != NIL)
+ newnode->join.subPlan = nconc(newnode->join.subPlan,
+ pull_subplans((Node *) newnode->mergeclauses));
+
return newnode;
}
@@ -382,9 +401,15 @@ _copyHashJoin(HashJoin *from)
* ----------------
*/
Node_Copy(from, newnode, hashclauses);
-
newnode->hashjoinop = from->hashjoinop;
+ /*
+ * We must add subplans in hashclauses to the new plan's subPlan list
+ */
+ if (from->join.subPlan != NIL)
+ newnode->join.subPlan = nconc(newnode->join.subPlan,
+ pull_subplans((Node *) newnode->hashclauses));
+
return newnode;
}