aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-08-30 12:56:50 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-08-30 12:56:50 -0400
commitd1a4db8d25ec53fd17e99168bc5efa0b16ef6fed (patch)
tree588664bf187cc3124312d55c7f836fe71533ca25 /src
parente1a6375d8f3a11f3447bea10883a4cbe1c5d3ec9 (diff)
downloadpostgresql-d1a4db8d25ec53fd17e99168bc5efa0b16ef6fed.tar.gz
postgresql-d1a4db8d25ec53fd17e99168bc5efa0b16ef6fed.zip
Improve EXPLAIN's ability to cope with LATERAL references in plans.
push_child_plan/pop_child_plan didn't bother to adjust the "ancestors" list of parent plan nodes when descending to a child plan node. I think this was okay when it was written, but it's not okay in the presence of LATERAL references, since a subplan node could easily be returning a LATERAL value back up to the same nestloop node that provides the value. Per changed regression test results, the omission led to failure to interpret Param nodes that have perfectly good interpretations.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/ruleutils.c18
-rw-r--r--src/test/regress/expected/join.out2
2 files changed, 11 insertions, 9 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index f6f7f85f443..ae6278432fd 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -2312,14 +2312,8 @@ push_child_plan(deparse_namespace *dpns, PlanState *ps,
/* Save state for restoration later */
*save_dpns = *dpns;
- /*
- * Currently we don't bother to adjust the ancestors list, because an
- * OUTER_VAR or INNER_VAR reference really shouldn't contain any Params
- * that would be set by the parent node itself. If we did want to adjust
- * the list, lcons'ing dpns->planstate onto dpns->ancestors would be the
- * appropriate thing --- and pop_child_plan would need to undo the change
- * to the list.
- */
+ /* Link current plan node into ancestors list */
+ dpns->ancestors = lcons(dpns->planstate, dpns->ancestors);
/* Set attention on selected child */
set_deparse_planstate(dpns, ps);
@@ -2331,8 +2325,16 @@ push_child_plan(deparse_namespace *dpns, PlanState *ps,
static void
pop_child_plan(deparse_namespace *dpns, deparse_namespace *save_dpns)
{
+ List *ancestors;
+
+ /* Get rid of ancestors list cell added by push_child_plan */
+ ancestors = list_delete_first(dpns->ancestors);
+
/* Restore fields changed by push_child_plan */
*dpns = *save_dpns;
+
+ /* Make sure dpns->ancestors is right (may be unnecessary) */
+ dpns->ancestors = ancestors;
}
/*
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 2e54ede8387..c2e83d7f8bb 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -3172,7 +3172,7 @@ explain (costs off)
Nested Loop
-> Seq Scan on int8_tbl a
-> Hash Left Join
- Hash Cond: (x.q2 = ($0))
+ Hash Cond: (x.q2 = (a.q1))
-> Seq Scan on int8_tbl x
-> Hash
-> Seq Scan on int4_tbl y