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