From e932fb4d89a6f3cc5b1e4551549ed4cdba30c453 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Mon, 19 Oct 2026 21:00:00 +0900 Subject: [PATCH v2 1/2] Add tests for a relation alias named SET in DML targets An alias named "set" on the target of UPDATE, DELETE or MERGE is printed bare and read back as the SET keyword. Cover UPDATE and DELETE in rules and MERGE in a BEGIN ATOMIC function body, each recreated from its deparsed text. The expected output shows the behavior before the fix. The next commit fixes it and updates the output. Discussion: https://postgr.es/m/CAAAe_zDqXin5NeB5atRCbZqUdcMOeyXRqhan+tVp0F30OCURnw@mail.gmail.com --- src/test/regress/expected/rules.out | 49 +++++++++++++++++++++++++++++ src/test/regress/sql/rules.sql | 32 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 4addeba2508..dfd09f17953 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -4153,3 +4153,52 @@ DROP TABLE ruletest_t3; DROP TABLE ruletest_t2; DROP TABLE ruletest_t1; DROP USER regress_rule_user1; +-- +-- A target alias named "set" must not be read back as the SET keyword +-- +create table ruletest_setalias (a int, b int); +create rule ruletest_setalias_r1 as on insert to ruletest_setalias + do also update ruletest_setalias "set" set b = 1 where "set".a = 2; +create rule ruletest_setalias_r2 as on insert to ruletest_setalias + do also delete from ruletest_setalias "set" where "set".a = 1; +create table ruletest_setalias_m (a int, b int); +create function ruletest_setalias_f() returns void language sql +begin atomic + merge into ruletest_setalias_m "set" using (values (1)) s(a) + on "set".a = s.a when matched then update set b = 1; +end; +select pg_get_ruledef(oid) as def1 from pg_rewrite + where rulename = 'ruletest_setalias_r1' \gset +select pg_get_ruledef(oid) as def2 from pg_rewrite + where rulename = 'ruletest_setalias_r2' \gset +select pg_get_functiondef('ruletest_setalias_f'::regproc) as def3 \gset +drop rule ruletest_setalias_r1 on ruletest_setalias; +drop rule ruletest_setalias_r2 on ruletest_setalias; +drop function ruletest_setalias_f(); +:def1 +ERROR: syntax error at or near "b" +LINE 2: ...ruletest_setalias DO UPDATE ruletest_setalias set SET b = 1 + ^ +:def2 +ERROR: syntax error at or near "set" +LINE 2: ...blic.ruletest_setalias DO DELETE FROM ruletest_setalias set + ^ +:def3; +ERROR: syntax error at or near "set" +LINE 5: MERGE INTO ruletest_setalias_m set + ^ +select pg_get_ruledef(oid) from pg_rewrite + where rulename like 'ruletest_setalias_r%' order by rulename; + pg_get_ruledef +---------------- +(0 rows) + +select pg_get_functiondef(oid) from pg_proc + where proname = 'ruletest_setalias_f'; + pg_get_functiondef +-------------------- +(0 rows) + +drop function ruletest_setalias_f(); +ERROR: function ruletest_setalias_f() does not exist +drop table ruletest_setalias, ruletest_setalias_m; diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql index abe89d097c9..624b3958ba6 100644 --- a/src/test/regress/sql/rules.sql +++ b/src/test/regress/sql/rules.sql @@ -1460,3 +1460,35 @@ DROP TABLE ruletest_t2; DROP TABLE ruletest_t1; DROP USER regress_rule_user1; + +-- +-- A target alias named "set" must not be read back as the SET keyword +-- +create table ruletest_setalias (a int, b int); +create rule ruletest_setalias_r1 as on insert to ruletest_setalias + do also update ruletest_setalias "set" set b = 1 where "set".a = 2; +create rule ruletest_setalias_r2 as on insert to ruletest_setalias + do also delete from ruletest_setalias "set" where "set".a = 1; +create table ruletest_setalias_m (a int, b int); +create function ruletest_setalias_f() returns void language sql +begin atomic + merge into ruletest_setalias_m "set" using (values (1)) s(a) + on "set".a = s.a when matched then update set b = 1; +end; +select pg_get_ruledef(oid) as def1 from pg_rewrite + where rulename = 'ruletest_setalias_r1' \gset +select pg_get_ruledef(oid) as def2 from pg_rewrite + where rulename = 'ruletest_setalias_r2' \gset +select pg_get_functiondef('ruletest_setalias_f'::regproc) as def3 \gset +drop rule ruletest_setalias_r1 on ruletest_setalias; +drop rule ruletest_setalias_r2 on ruletest_setalias; +drop function ruletest_setalias_f(); +:def1 +:def2 +:def3; +select pg_get_ruledef(oid) from pg_rewrite + where rulename like 'ruletest_setalias_r%' order by rulename; +select pg_get_functiondef(oid) from pg_proc + where proname = 'ruletest_setalias_f'; +drop function ruletest_setalias_f(); +drop table ruletest_setalias, ruletest_setalias_m; -- 2.54.0 (Apple Git-157)