summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r--src/backend/utils/adt/ruleutils.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index e7f7abc1588..97716991b86 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -7279,17 +7279,31 @@ get_name_for_var_field(Var *var, int fieldno,
/*
* We're deparsing a Plan tree so we don't have complete
* RTE entries (in particular, rte->subquery is NULL). But
- * the only place we'd see a Var directly referencing a
- * SUBQUERY RTE is in a SubqueryScan plan node, and we can
- * look into the child plan's tlist instead.
+ * the only place we'd normally see a Var directly
+ * referencing a SUBQUERY RTE is in a SubqueryScan plan
+ * node, and we can look into the child plan's tlist
+ * instead. An exception occurs if the subquery was
+ * proven empty and optimized away: then we'd find such a
+ * Var in a childless Result node, and there's nothing in
+ * the plan tree that would let us figure out what it had
+ * originally referenced. In that case, fall back on
+ * printing "fN", analogously to the default column names
+ * for RowExprs.
*/
TargetEntry *tle;
deparse_namespace save_dpns;
const char *result;
if (!dpns->inner_plan)
- elog(ERROR, "failed to find plan for subquery %s",
- rte->eref->aliasname);
+ {
+ char *dummy_name = palloc(32);
+
+ Assert(IsA(dpns->plan, Result));
+ snprintf(dummy_name, 32, "f%d", fieldno);
+ return dummy_name;
+ }
+ Assert(IsA(dpns->plan, SubqueryScan));
+
tle = get_tle_by_resno(dpns->inner_tlist, attnum);
if (!tle)
elog(ERROR, "bogus varattno for subquery var: %d",
@@ -7398,17 +7412,26 @@ get_name_for_var_field(Var *var, int fieldno,
{
/*
* We're deparsing a Plan tree so we don't have a CTE
- * list. But the only place we'd see a Var directly
- * referencing a CTE RTE is in a CteScan plan node, and we
- * can look into the subplan's tlist instead.
+ * list. But the only place we'd normally see a Var
+ * directly referencing a CTE RTE is in a CteScan plan
+ * node, and we can look into the subplan's tlist instead.
+ * As above, this can fail if the CTE has been proven
+ * empty, in which case fall back to "fN".
*/
TargetEntry *tle;
deparse_namespace save_dpns;
const char *result;
if (!dpns->inner_plan)
- elog(ERROR, "failed to find plan for CTE %s",
- rte->eref->aliasname);
+ {
+ char *dummy_name = palloc(32);
+
+ Assert(IsA(dpns->plan, Result));
+ snprintf(dummy_name, 32, "f%d", fieldno);
+ return dummy_name;
+ }
+ Assert(IsA(dpns->plan, CteScan));
+
tle = get_tle_by_resno(dpns->inner_tlist, attnum);
if (!tle)
elog(ERROR, "bogus varattno for subquery var: %d",