0001-bug-18576-fix-fail.patch
text/x-diff
Filename: 0001-bug-18576-fix-fail.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
Series: patch 0001
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/setrefs.c | 32 | 17 |
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 7aed84584c..7c417d4e14 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -1013,26 +1013,41 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
else
{
/*
- * The tlist of a childless Result could contain
- * unresolved ROWID_VAR Vars, in case it's representing a
- * target relation which is completely empty because of
- * constraint exclusion. Replace any such Vars by null
- * constants, as though they'd been resolved for a leaf
- * scan node that doesn't support them. We could have
- * fix_scan_expr do this, but since the case is only
- * 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.
+ * The tlist of a dummy Result (one with constant-false
+ * resconstantqual) could contain Vars, which are
+ * effectively dangling references and have the potential
+ * to cause problems in the executor or EXPLAIN. We could
+ * not get rid of these earlier without breaking Var
+ * replacement in upper plan levels, but now let's reduce
+ * the tlist to a bunch of NULL constants. Since the
+ * tlist should never be executed, this has no run-time
+ * effect. (One useful side-effect is that this makes it
+ * safe for fix_scan_expr to assert that it won't see
+ * ROWID_VARs; without this, unresolved ROWID Vars could
+ * be found in the tlist of such a result.)
*/
- foreach(l, splan->plan.targetlist)
+ bool dummy = false;
+
+ if (list_length((List *) splan->resconstantqual) == 1)
{
- TargetEntry *tle = (TargetEntry *) lfirst(l);
- Var *var = (Var *) tle->expr;
+ Const *cqual = (Const *) linitial((List *) splan->resconstantqual);
+
+ dummy = IsA(cqual, Const) &&
+ (cqual->constisnull ||
+ !DatumGetBool(cqual->constvalue));
+ }
- if (var && IsA(var, Var) && var->varno == ROWID_VAR)
- tle->expr = (Expr *) makeNullConst(var->vartype,
- var->vartypmod,
- var->varcollid);
+ if (dummy)
+ {
+ foreach(l, splan->plan.targetlist)
+ {
+ TargetEntry *tle = (TargetEntry *) lfirst(l);
+ Node *expr = (Node *) tle->expr;
+
+ tle->expr = (Expr *) makeNullConst(exprType(expr),
+ exprTypmod(expr),
+ exprCollation(expr));
+ }
}
splan->plan.targetlist =