Re: Adding OLD/NEW support to RETURNING - Mailing list pgsql-hackers
From | jian he |
---|---|
Subject | Re: Adding OLD/NEW support to RETURNING |
Date | |
Msg-id | CACJufxERA3cxF1FVKXTyDv95KTESQCT38HUUEOYNHh=Y5aGC2g@mail.gmail.com Whole thread Raw |
In response to | Adding OLD/NEW support to RETURNING (Dean Rasheed <dean.a.rasheed@gmail.com>) |
Responses |
Re: Adding OLD/NEW support to RETURNING
|
List | pgsql-hackers |
On Mon, Dec 4, 2023 at 8:15 PM Dean Rasheed <dean.a.rasheed@gmail.com> wrote: > > I have been playing around with the idea of adding support for OLD/NEW > to RETURNING, partly motivated by the discussion on the MERGE > RETURNING thread [1], but also because I think it would be a very > useful addition for other commands (UPDATE in particular). > > This was discussed a long time ago [2], but that previous discussion > didn't lead to a workable patch, and so I have taken a different > approach here. > > Thoughts? > /* get the tuple from the relation being scanned */ - scratch.opcode = EEOP_ASSIGN_SCAN_VAR; + switch (variable->varreturningtype) + { + case VAR_RETURNING_OLD: + scratch.opcode = EEOP_ASSIGN_OLD_VAR; + break; + case VAR_RETURNING_NEW: + scratch.opcode = EEOP_ASSIGN_NEW_VAR; + break; + default: + scratch.opcode = EEOP_ASSIGN_SCAN_VAR; + break; + } I have roughly an idea of what this code is doing. but do you need to refactor the above comment? /* for EEOP_INNER/OUTER/SCAN_FETCHSOME */ in src/backend/executor/execExpr.c, do you need to update the comment? create temp table foo (f1 int, f2 int); insert into foo values (1,2), (3,4); INSERT INTO foo select 11, 22 RETURNING WITH (old AS new, new AS old) new.*, old.*; --this works. which is fine. create or replace function stricttest1() returns void as $$ declare x record; begin insert into foo values(5,6) returning new.* into x; raise notice 'x.f1 = % x.f2 %', x.f1, x.f2; end$$ language plpgsql; select * from stricttest1(); --this works. create or replace function stricttest2() returns void as $$ declare x record; y record; begin INSERT INTO foo select 11, 22 RETURNING WITH (old AS o, new AS n) o into x, n into y; raise notice 'x.f1: % x.f2 % y.f1 % y.f2 %', x.f1,x.f2, y.f1, y.f2; end$$ language plpgsql; --this does not work. --because https://www.postgresql.org/message-id/flat/CAFj8pRB76FE2MVxJYPc1RvXmsf2upoTgoPCC9GsvSAssCM2APQ%40mail.gmail.com create or replace function stricttest3() returns void as $$ declare x record; y record; begin INSERT INTO foo select 11, 22 RETURNING WITH (old AS o, new AS n) o.*,n.* into x; raise notice 'x.f1 % x.f2 %, % %', x.f1, x.f2, x.f1,x.f2; end$$ language plpgsql; select * from stricttest3(); --this is not what we want. because old and new share the same column name --so here you cannot get the "new" content. create or replace function stricttest4() returns void as $$ declare x record; y record; begin INSERT INTO foo select 11, 22 RETURNING WITH (old AS o, new AS n) o.f1 as of1,o.f2 as of2,n.f1 as nf1, n.f2 as nf2 into x; raise notice 'x.0f1 % x.of2 % nf1 % nf2 %', x.of1, x.of2, x.nf1, x.nf2; end$$ language plpgsql; --kind of verbose, but works, which is fine. create or replace function stricttest5() returns void as $$ declare x record; y record; a foo%ROWTYPE; b foo%ROWTYPE; begin INSERT INTO foo select 11, 22 RETURNING WITH (old AS o, new AS n) o into a, n into b; end$$ language plpgsql; -- expect this to work.
pgsql-hackers by date: