MERGE lacks ruleutils.c decompiling support!?

Started by Tom Lanealmost 3 years ago10 messageshackers
Jump to latest
#1Tom Lane
tgl@sss.pgh.pa.us

I made this function:

CREATE OR REPLACE FUNCTION test_fun()
RETURNS void
LANGUAGE SQL
BEGIN ATOMIC
MERGE INTO target
USING source s on s.id = target.id
WHEN MATCHED THEN
UPDATE SET data = s.data
WHEN NOT MATCHED THEN
INSERT VALUES (s.id, s.data);
end;

It appears to work fine, but:

regression=# \sf+ test_fun()
ERROR: unrecognized query command type: 5

and it also breaks pg_dump. Somebody screwed up pretty badly
here. Is there any hope of fixing it for Monday's releases?

(I'd guess that decompiling the WHEN clause would take a nontrivial
amount of new code, so maybe fixing it on such short notice is
impractical. But ugh.)

regards, tom lane

#2Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#1)
Re: MERGE lacks ruleutils.c decompiling support!?

On 2023-May-05, Tom Lane wrote:

I made this function:

CREATE OR REPLACE FUNCTION test_fun()
RETURNS void
LANGUAGE SQL
BEGIN ATOMIC
MERGE INTO target
USING source s on s.id = target.id
WHEN MATCHED THEN
UPDATE SET data = s.data
WHEN NOT MATCHED THEN
INSERT VALUES (s.id, s.data);
end;

It appears to work fine, but:

regression=# \sf+ test_fun()
ERROR: unrecognized query command type: 5

and it also breaks pg_dump. Somebody screwed up pretty badly
here. Is there any hope of fixing it for Monday's releases?

(I'd guess that decompiling the WHEN clause would take a nontrivial
amount of new code, so maybe fixing it on such short notice is
impractical. But ugh.)

Hmm, there is *some* code in ruleutils for MERGE, but clearly something
is missing. Let me have a look ...

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/

#3Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#1)
Re: MERGE lacks ruleutils.c decompiling support!?

On 2023-May-05, Tom Lane wrote:

(I'd guess that decompiling the WHEN clause would take a nontrivial
amount of new code, so maybe fixing it on such short notice is
impractical. But ugh.)

Here's a first attempt. I mostly just copied code from the insert and
update support routines. There's a couple of things missing still, but
I'm not sure I'll get to it tonight. I only tested to the extent of
what's in the new regression test.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
<Schwern> It does it in a really, really complicated way
<crab> why does it need to be complicated?
<Schwern> Because it's MakeMaker.

Attachments:

0001-add-ruleutils.c-support-for-MERGE.patchtext/x-diff; charset=us-asciiDownload+225-1
#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#3)
Re: MERGE lacks ruleutils.c decompiling support!?

Alvaro Herrera <alvherre@alvh.no-ip.org> writes:

Here's a first attempt. I mostly just copied code from the insert and
update support routines. There's a couple of things missing still, but
I'm not sure I'll get to it tonight. I only tested to the extent of
what's in the new regression test.

I did a bit of review and more work on this:

* Added the missing OVERRIDING support

* Played around with the pretty-printing indentation

* Improved test coverage, and moved the test to rules.sql where
I thought it fit more naturally.

I think we could probably commit this, though I've not tried it
in v15 yet.

regards, tom lane

Attachments:

0001-add-ruleutils.c-support-for-MERGE-v2.patchtext/x-diff; charset=us-ascii; name=0001-add-ruleutils.c-support-for-MERGE-v2.patchDownload+262-0
#5Michael Paquier
michael@paquier.xyz
In reply to: Tom Lane (#4)
Re: MERGE lacks ruleutils.c decompiling support!?

On Fri, May 05, 2023 at 05:06:34PM -0400, Tom Lane wrote:

I did a bit of review and more work on this:

* Added the missing OVERRIDING support

* Played around with the pretty-printing indentation

* Improved test coverage, and moved the test to rules.sql where
I thought it fit more naturally.

I think we could probably commit this, though I've not tried it
in v15 yet.

Seems rather OK..

+WHEN NOT MATCHED
+   AND s.a > 100
+   THEN INSERT (id, data) OVERRIDING SYSTEM VALUE
+   VALUES (s.a, DEFAULT)

About OVERRIDING, I can see that this is still missing coverage for
OVERRIDING USER VALUE.
--
Michael

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Michael Paquier (#5)
Re: MERGE lacks ruleutils.c decompiling support!?

Michael Paquier <michael@paquier.xyz> writes:

+WHEN NOT MATCHED
+   AND s.a > 100
+   THEN INSERT (id, data) OVERRIDING SYSTEM VALUE
+   VALUES (s.a, DEFAULT)

About OVERRIDING, I can see that this is still missing coverage for
OVERRIDING USER VALUE.

Yeah, I couldn't see that covering that too was worth any cycles.

regards, tom lane

#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#4)
Re: MERGE lacks ruleutils.c decompiling support!?

I wrote:

I think we could probably commit this, though I've not tried it
in v15 yet.

Ping? The hours grow short, if we're to get this into 15.3.

regards, tom lane

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#7)
Re: MERGE lacks ruleutils.c decompiling support!?

I wrote:

Ping? The hours grow short, if we're to get this into 15.3.

I went ahead and pushed v2, since we can't wait any longer if
we're to get reasonable buildfarm coverage before 15.3 wraps.

regards, tom lane

#9Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#8)
Re: MERGE lacks ruleutils.c decompiling support!?

On 2023-May-07, Tom Lane wrote:

I wrote:

Ping? The hours grow short, if we're to get this into 15.3.

I went ahead and pushed v2, since we can't wait any longer if
we're to get reasonable buildfarm coverage before 15.3 wraps.

Much appreciated. I wanted to get back to this yesterday but was unable
to.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/

#10Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#1)
Re: MERGE lacks ruleutils.c decompiling support!?

BTW, I spent some time adding a cross-check to see if the code was at
least approximately correct for all the queries in the MERGE regression
tests, and couldn't find any failures. I then extended the test to the
other optimizable commands, and couldn't find any problems there either.

My approach was perhaps a bit simple-minded: I just patched
pg_analyze_and_rewrite_fixedparams() to call pg_get_querydef() after
parse_analyze_fixedparams(), then ran the main regression tests. No
crashes. Also had it output as a WARNING together with the
query_string, so that I could eyeball for any discrepancies; I couldn't
find any queries that produce wrong contents, though this was just
manual examination of the resulting noise logs.

I suppose a better approach might be to run the query produced by
pg_get_querydef() again through parse analysis and see if it produces
the same; or better yet, discard the original parsed query and parse the
pg_get_querydef(). I didn't try to do this.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"No deja de ser humillante para una persona de ingenio saber
que no hay tonto que no le pueda enseñar algo." (Jean B. Say)