summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/setrefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/setrefs.c')
-rw-r--r--src/backend/optimizer/plan/setrefs.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 6950eff2c5b..ccdc9bc264a 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -1034,16 +1034,35 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
* expected to occur here, it seems safer to special-case
* it here and keep the assertions that ROWID_VARs
* shouldn't be seen by fix_scan_expr.
+ *
+ * We also must handle the case where set operations have
+ * been short-circuited resulting in a dummy Result node.
+ * prepunion.c uses varno==0 for the set op targetlist.
+ * See generate_setop_tlist() and generate_setop_tlist().
+ * Here we rewrite these to use varno==1, which is the
+ * varno of the first set-op child. Without this, EXPLAIN
+ * will have trouble displaying targetlists of dummy set
+ * operations.
*/
foreach(l, splan->plan.targetlist)
{
TargetEntry *tle = (TargetEntry *) lfirst(l);
Var *var = (Var *) tle->expr;
- if (var && IsA(var, Var) && var->varno == ROWID_VAR)
- tle->expr = (Expr *) makeNullConst(var->vartype,
- var->vartypmod,
- var->varcollid);
+ if (var && IsA(var, Var))
+ {
+ if (var->varno == ROWID_VAR)
+ tle->expr = (Expr *) makeNullConst(var->vartype,
+ var->vartypmod,
+ var->varcollid);
+ else if (var->varno == 0)
+ tle->expr = (Expr *) makeVar(1,
+ var->varattno,
+ var->vartype,
+ var->vartypmod,
+ var->varcollid,
+ var->varlevelsup);
+ }
}
splan->plan.targetlist =