Re: [DEPARSE] EXPLAIN prints another ModifyTable's RETURNING aliases in a SubPlan

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>
Cc: Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>, assam258(at)gmail(dot)com, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: [DEPARSE] EXPLAIN prints another ModifyTable's RETURNING aliases in a SubPlan
Date: 2026-10-21 17:09:38
Message-ID: 2215512.1792602578@sss.pgh.pa.us
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

After further reflection, I don't buy the argument that we shouldn't
expose the rule's innards. You have to understand the rule in order
to realize why your "INSERT ON v" has turned into an "INSERT ON t"
in the first place. Another point is that "new" is already a rather
ambiguous name. Suppose the rule were

CREATE RULE v_ins AS ON INSERT TO v DO INSTEAD
INSERT INTO t as t_alias VALUES (new.a*2) RETURNING new.a;

If you try this with "INSERT INTO v AS new VALUES (1) RETURNING *",
what's inserted and returned is 2. Thus, "new" in the VALUES clause
refers to a value that was attempted to be inserted into v, but
"new" in the RETURNING clause refers to something that was inserted
into t, which is not the same. If we allow the rule's alias to be
used, then when we write

CREATE RULE v_ins AS ON INSERT TO v DO INSTEAD
INSERT INTO t VALUES (new.a*2) RETURNING WITH (NEW AS n) n.a;

we get

Insert on public.t
Output: n.a
-> Result
Output: 2

which seems to me to be *less* confusing than either "new" or "t"
would be. So I'm kind of inclined to think that Ayush found what
ought to be changed, but it's got the wrong precedence: the rule's
aliases should be preferred if there are any, along the lines of

/*
* If rule action lacks aliases for OLD and/or NEW in RETURNING list,
* use the triggering query's aliases.
*/
if (rule_action->returningOldAlias == NULL)
rule_action->returningOldAlias = parsetree->returningOldAlias;
if (rule_action->returningNewAlias == NULL)
rule_action->returningNewAlias = parsetree->returningNewAlias;

Neither this nor Ayush's patch yield any changes in the regression
tests, so we're definitely talking about an edge case. I also tried
simply removing this stanza entirely, but that again causes those
new Asserts to fail in regression.

regards, tom lane

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Bharath Rupireddy 2026-10-21 17:37:52 Re: Parallel vacuum: workers together with leader could overrun cost budget
Previous Message Tom Lane 2026-10-21 16:38:32 Re: [DEPARSE] EXPLAIN prints another ModifyTable's RETURNING aliases in a SubPlan