From: | jian he <jian(dot)universality(at)gmail(dot)com> |
---|---|
To: | Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com> |
Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | Re: Adding OLD/NEW support to RETURNING |
Date: | 2023-12-16 13:03:00 |
Message-ID: | CACJufxERA3cxF1FVKXTyDv95KTESQCT38HUUEOYNHh=Y5aGC2g@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Mon, Dec 4, 2023 at 8:15 PM Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)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.
From | Date | Subject | |
---|---|---|---|
Next Message | Alena Rybakina | 2023-12-16 15:41:27 | Re: [PoC] Reducing planning time when tables have many partitions |
Previous Message | Andres Freund | 2023-12-16 12:29:00 | Re: Clang optimiser vs preproc.c |