Re: MERGE ... RETURNING
Jeff Davis <pgsql@j-davis.com>
From: Jeff Davis <pgsql@j-davis.com>
To: Dean Rasheed <dean.a.rasheed@gmail.com>, jian he <jian.universality@gmail.com>
Cc: Vik Fearing <vik@postgresfriends.org>, Gurjeet Singh <gurjeet@singh.im>,
Isaac Morland <isaac.morland@gmail.com>, PostgreSQL Hackers
<pgsql-hackers@lists.postgresql.org>
Date: 2024-02-29T19:49:29Z
Lists: pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Add RETURNING support to MERGE.
- c649fa24a42b 17.0 landed
-
doc: Improve a couple of places in the MERGE docs.
- 97d4262683ac 17.0 landed
- d4c573d8e81e 16.3 landed
- a875743ff402 15.7 landed
-
doc: improve description of privileges for MERGE and update glossary.
- 4bc8f29088f8 17.0 landed
- 3b6728910ace 16.2 landed
- ff772853d02e 15.6 landed
-
Fix RLS policy usage in MERGE.
- c2e08b04c9e7 17.0 cited
-
Fix leak of LLVM "fatal-on-oom" section counter.
- 4f4d73466d71 17.0 cited
-
Implement outer-level aggregates to conform to the SQL spec, with
- e649796f128b 7.4.1 cited
Can we get some input on whether the current MERGE ... RETURNING patch is the right approach from a language standpoint? We've gone through a lot of iterations -- thank you Dean, for implementing so many variations. To summarize, most of the problem has been in retrieving the action (INSERT/UPDATE/DELETE) taken or the WHEN-clause number applied to a particular matched row. The reason this is important is because the row returned is the old row for a DELETE action, and the new row for an INSERT or UPDATE action. Without a way to distinguish the particular action, the RETURNING clause returns a mixture of old and new rows, which would be hard to use sensibly. Granted, DELETE in a MERGE may be a less common case. But given that we also have INSERT ... ON CONFLICT, MERGE commands are more likely to be the complicated cases where distinguishing the action or clause number is important. But linguistically it's not clear where the action or clause number should come from. The clauses don't have assigned numbers, and even if they did, linguistically it's not clear how to refer to the clause number in a language like SQL. Would it be a special identifier, a function, a special function, or be a column in a special table reference? Or, do we just have one RETURNING-clause per WHEN-clause, and let the user use a literal of their choice in the RETURNING clause? The current implementation uses a special function MERGING (a grammatical construct without an OID that parses into a new MergingFunc expr), which takes keywords ACTION or CLAUSE_NUMBER in the argument positions. That's not totally unprecedented in SQL -- the XML and JSON functions are kind of similar. But it's different in the sense that MERGING is also context-sensitive: grammatically, it fits pretty much anywhere a function fits, but then gets rejected at parse analysis time (or perhaps even execution time?) if it's not called from the right place. Is that a reasonable thing to do? Another related topic came up, which is that the RETURNING clause (for UPDATE as well as MERGE) should probably accept some kind of alias like NEW/OLD or BEFORE/AFTER to address the version of the row that you want. That doesn't eliminate the need for the MERGING function, but it's good to think about how that might fit in with whatever we do here. Regards, Jeff Davis