aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/clauses.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/clauses.c')
-rw-r--r--src/backend/optimizer/util/clauses.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index dfef0778afa..11bb3946aa8 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -3115,10 +3115,19 @@ eval_const_expressions_mutator(Node *node,
* But it can arise while simplifying functions.) Also, we
* can optimize field selection from a RowExpr construct.
*
- * We must however check that the declared type of the field
- * is still the same as when the FieldSelect was created ---
- * this can change if someone did ALTER COLUMN TYPE on the
- * rowtype.
+ * However, replacing a whole-row Var in this way has a
+ * pitfall: if we've already built the reltargetlist for the
+ * source relation, then the whole-row Var is scheduled to be
+ * produced by the relation scan, but the simple Var probably
+ * isn't, which will lead to a failure in setrefs.c. This is
+ * not a problem when handling simple single-level queries, in
+ * which expression simplification always happens first. It
+ * is a risk for lateral references from subqueries, though.
+ * To avoid such failures, don't optimize uplevel references.
+ *
+ * We must also check that the declared type of the field is
+ * still the same as when the FieldSelect was created --- this
+ * can change if someone did ALTER COLUMN TYPE on the rowtype.
*/
FieldSelect *fselect = (FieldSelect *) node;
FieldSelect *newfselect;
@@ -3127,7 +3136,8 @@ eval_const_expressions_mutator(Node *node,
arg = eval_const_expressions_mutator((Node *) fselect->arg,
context);
if (arg && IsA(arg, Var) &&
- ((Var *) arg)->varattno == InvalidAttrNumber)
+ ((Var *) arg)->varattno == InvalidAttrNumber &&
+ ((Var *) arg)->varlevelsup == 0)
{
if (rowtype_field_matches(((Var *) arg)->vartype,
fselect->fieldnum,