=== Applying patches on top of PostgreSQL commit ID 1863452a4bfecfefc51336ecfc78837a164fbb10 === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Mon Jul 13 08:28:29 UTC 2026 On branch cf/6704 nothing to commit, working tree clean === using 'git am' to apply patch ./v8-0001-Forbid-FOR-PORTION-OF-on-views-with-INSTEAD-OF-tr.patch === Applying: Forbid FOR PORTION OF on views with INSTEAD OF triggers Using index info to reconstruct a base tree... M src/backend/parser/analyze.c M src/test/regress/expected/updatable_views.out M src/test/regress/sql/updatable_views.sql Falling back to patching base and 3-way merge... Auto-merging src/test/regress/sql/updatable_views.sql CONFLICT (content): Merge conflict in src/test/regress/sql/updatable_views.sql Auto-merging src/test/regress/expected/updatable_views.out CONFLICT (content): Merge conflict in src/test/regress/expected/updatable_views.out Auto-merging src/backend/parser/analyze.c error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 Forbid FOR PORTION OF on views with INSTEAD OF triggers When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". === using patch(1) to apply patch ./v8-0001-Forbid-FOR-PORTION-OF-on-views-with-INSTEAD-OF-tr.patch === patching file src/backend/parser/analyze.c patching file src/test/regress/expected/updatable_views.out Hunk #1 FAILED at 4165. 1 out of 1 hunk FAILED -- saving rejects to file src/test/regress/expected/updatable_views.out.rej patching file src/test/regress/sql/updatable_views.sql Hunk #1 FAILED at 2148. 1 out of 1 hunk FAILED -- saving rejects to file src/test/regress/sql/updatable_views.sql.rej Unstaged changes after reset: M src/backend/parser/analyze.c Removing src/test/regress/expected/updatable_views.out.rej Removing src/test/regress/sql/updatable_views.sql.rej === using 'git apply' to apply patch ./v8-0001-Forbid-FOR-PORTION-OF-on-views-with-INSTEAD-OF-tr.patch === Applied patch to 'src/backend/parser/analyze.c' cleanly. Applied patch to 'src/test/regress/expected/updatable_views.out' with conflicts. Applied patch to 'src/test/regress/sql/updatable_views.sql' with conflicts. U src/test/regress/expected/updatable_views.out U src/test/regress/sql/updatable_views.sql diff --cc src/test/regress/expected/updatable_views.out index 9c6bb2219f9,acab165ae4c..00000000000 --- a/src/test/regress/expected/updatable_views.out +++ b/src/test/regress/expected/updatable_views.out @@@ -4179,60 -4179,27 +4179,82 @@@ update uv_fpo_instead_vie for portion of valid_at from '2015-01-01' to '2020-01-01' set b = 99 where id = '[1,1]'; -- error ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF ++<<<<<<< ours ++======= + LINE 2: for portion of valid_at from '2015-01-01' to '2020-01-01' + ^ ++>>>>>>> theirs delete from uv_fpo_instead_view for portion of valid_at from '2017-01-01' to '2022-01-01' where id = '[1,1]'; -- error ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF ++<<<<<<< ours ++======= + LINE 2: for portion of valid_at from '2017-01-01' to '2022-01-01' + ^ ++>>>>>>> theirs -- The check does not depend on which rows match, so it errors even when -- no rows do. update uv_fpo_instead_view for portion of valid_at from '2015-01-01' to '2020-01-01' set b = 99 where id = '[9,9]'; -- error, even with no matching rows ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF ++<<<<<<< ours ++======= + LINE 2: for portion of valid_at from '2015-01-01' to '2020-01-01' + ^ ++>>>>>>> theirs delete from uv_fpo_instead_view for portion of valid_at from '2017-01-01' to '2022-01-01' where id = '[9,9]'; -- error, even with no matching rows ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF ++<<<<<<< ours +drop view uv_fpo_instead_view; +drop function uv_fpo_instead_trig(); +-- Forbid INSTEAD OF triggers with FOR PORTION OF even if the FOR PORTION OF +-- statement is parsed before the trigger exists. +-- This can happen in at least a couple ways: a rewrite rule or a BEGIN ATOMIC function. +create function uv_fpo_instead_trig() returns trigger language plpgsql as +$$ begin return new; end $$; +-- via a rewrite rule +create table uv_fpo_rule_tab (id int4range, valid_at tsrange, b float); +insert into uv_fpo_rule_tab values ('[1,1]', '[2000-01-01, 2030-01-01)', 0); +create view uv_fpo_rule_view as select id, valid_at, b from uv_fpo_rule_tab; +create rule uv_fpo_rule as on insert to uv_fpo_rule_tab do also + update uv_fpo_rule_view + for portion of valid_at from '2010-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; +create trigger uv_fpo_rule_instead + instead of update on uv_fpo_rule_view + for each row execute function uv_fpo_instead_trig(); +-- Would crash if we checked at parse-time: +insert into uv_fpo_rule_tab values ('[2,2]', '[2000-01-01,2030-01-01)', 0); +ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF +drop table uv_fpo_rule_tab cascade; +NOTICE: drop cascades to view uv_fpo_rule_view +-- via a BEGIN ATOMIC function body +create table uv_fpo_atomic_tab (id int4range, valid_at tsrange, b float); +insert into uv_fpo_atomic_tab values ('[1,1]', '[2000-01-01, 2030-01-01)', 0); +create view uv_fpo_atomic_view as select id, valid_at, b from uv_fpo_atomic_tab; +create function uv_fpo_atomic_fn() returns void language sql begin atomic + update uv_fpo_atomic_view + for portion of valid_at from '2010-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; +end; +create trigger uv_fpo_atomic_instead + instead of update on uv_fpo_atomic_view + for each row execute function uv_fpo_instead_trig(); +-- Would crash if we checked at parse-time: +select uv_fpo_atomic_fn(); +ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF +CONTEXT: SQL function "uv_fpo_atomic_fn" statement 1 +drop function uv_fpo_atomic_fn(); +drop table uv_fpo_atomic_tab cascade; +NOTICE: drop cascades to view uv_fpo_atomic_view +drop function uv_fpo_instead_trig(); ++======= + LINE 2: for portion of valid_at from '2017-01-01' to '2022-01-01' + ^ + drop view uv_fpo_instead_view; + drop function uv_fpo_instead_trig(); ++>>>>>>> theirs diff --cc src/test/regress/sql/updatable_views.sql index 2ef9aa32f36,f4a7e0327b0..00000000000 --- a/src/test/regress/sql/updatable_views.sql +++ b/src/test/regress/sql/updatable_views.sql @@@ -2182,42 -2182,3 +2182,45 @@@ delete from uv_fpo_instead_vie drop view uv_fpo_instead_view; drop function uv_fpo_instead_trig(); ++<<<<<<< ours + +-- Forbid INSTEAD OF triggers with FOR PORTION OF even if the FOR PORTION OF +-- statement is parsed before the trigger exists. +-- This can happen in at least a couple ways: a rewrite rule or a BEGIN ATOMIC function. +create function uv_fpo_instead_trig() returns trigger language plpgsql as +$$ begin return new; end $$; + +-- via a rewrite rule +create table uv_fpo_rule_tab (id int4range, valid_at tsrange, b float); +insert into uv_fpo_rule_tab values ('[1,1]', '[2000-01-01, 2030-01-01)', 0); +create view uv_fpo_rule_view as select id, valid_at, b from uv_fpo_rule_tab; +create rule uv_fpo_rule as on insert to uv_fpo_rule_tab do also + update uv_fpo_rule_view + for portion of valid_at from '2010-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; +create trigger uv_fpo_rule_instead + instead of update on uv_fpo_rule_view + for each row execute function uv_fpo_instead_trig(); +-- Would crash if we checked at parse-time: +insert into uv_fpo_rule_tab values ('[2,2]', '[2000-01-01,2030-01-01)', 0); +drop table uv_fpo_rule_tab cascade; + +-- via a BEGIN ATOMIC function body +create table uv_fpo_atomic_tab (id int4range, valid_at tsrange, b float); +insert into uv_fpo_atomic_tab values ('[1,1]', '[2000-01-01, 2030-01-01)', 0); +create view uv_fpo_atomic_view as select id, valid_at, b from uv_fpo_atomic_tab; +create function uv_fpo_atomic_fn() returns void language sql begin atomic + update uv_fpo_atomic_view + for portion of valid_at from '2010-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; +end; +create trigger uv_fpo_atomic_instead + instead of update on uv_fpo_atomic_view + for each row execute function uv_fpo_instead_trig(); +-- Would crash if we checked at parse-time: +select uv_fpo_atomic_fn(); +drop function uv_fpo_atomic_fn(); +drop table uv_fpo_atomic_tab cascade; +drop function uv_fpo_instead_trig(); ++======= ++>>>>>>> theirs