=== Applying patches on top of PostgreSQL commit ID 66ad764c8d517f59577d41ac3dad786729c9e10e === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Tue Apr 14 20:17:26 UTC 2026 On branch cf/6010 nothing to commit, working tree clean === using 'git am' to apply patch ./v3-0001-ALTER-COLUMN-SET-EXPRESSION-VIRTUAL-STORED.patch === Applying: ALTER COLUMN SET EXPRESSION [ VIRTUAL | STORED ] Using index info to reconstruct a base tree... M doc/src/sgml/ref/alter_table.sgml M src/backend/access/heap/heapam_handler.c M src/backend/commands/tablecmds.c M src/backend/parser/gram.y M src/include/nodes/parsenodes.h M src/test/modules/test_ddl_deparse/test_ddl_deparse.c M src/test/regress/expected/fast_default.out M src/test/regress/expected/generated_stored.out M src/test/regress/expected/generated_virtual.out M src/test/regress/expected/publication.out M src/test/regress/sql/fast_default.sql M src/test/regress/sql/generated_stored.sql M src/test/regress/sql/generated_virtual.sql M src/test/regress/sql/publication.sql M src/tools/pgindent/typedefs.list Falling back to patching base and 3-way merge... Auto-merging src/tools/pgindent/typedefs.list Auto-merging src/test/regress/sql/publication.sql Auto-merging src/test/regress/sql/generated_virtual.sql CONFLICT (content): Merge conflict in src/test/regress/sql/generated_virtual.sql Auto-merging src/test/regress/sql/generated_stored.sql Auto-merging src/test/regress/sql/fast_default.sql Auto-merging src/test/regress/expected/publication.out Auto-merging src/test/regress/expected/generated_virtual.out CONFLICT (content): Merge conflict in src/test/regress/expected/generated_virtual.out Auto-merging src/test/regress/expected/generated_stored.out Auto-merging src/test/regress/expected/fast_default.out Auto-merging src/test/modules/test_ddl_deparse/test_ddl_deparse.c Auto-merging src/include/nodes/parsenodes.h Auto-merging src/backend/parser/gram.y Auto-merging src/backend/commands/tablecmds.c CONFLICT (content): Merge conflict in src/backend/commands/tablecmds.c Auto-merging src/backend/access/heap/heapam_handler.c Auto-merging doc/src/sgml/ref/alter_table.sgml CONFLICT (content): Merge conflict in doc/src/sgml/ref/alter_table.sgml error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 ALTER COLUMN SET EXPRESSION [ VIRTUAL | STORED ] 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 ./v3-0001-ALTER-COLUMN-SET-EXPRESSION-VIRTUAL-STORED.patch === patching file doc/src/sgml/ref/alter_table.sgml Hunk #2 FAILED at 272. 1 out of 2 hunks FAILED -- saving rejects to file doc/src/sgml/ref/alter_table.sgml.rej patching file src/backend/access/heap/heapam_handler.c Hunk #1 succeeded at 2346 (offset -29 lines). Hunk #2 succeeded at 2431 with fuzz 1 (offset 33 lines). patching file src/backend/commands/tablecmds.c Hunk #1 succeeded at 538 (offset 15 lines). Hunk #2 succeeded at 5066 (offset 33 lines). Hunk #3 succeeded at 8703 (offset 60 lines). Hunk #4 FAILED at 8672. Hunk #5 succeeded at 8748 (offset 48 lines). Hunk #6 succeeded at 8866 (offset 47 lines). Hunk #7 succeeded at 8947 (offset 47 lines). 1 out of 7 hunks FAILED -- saving rejects to file src/backend/commands/tablecmds.c.rej patching file src/backend/parser/gram.y Hunk #1 succeeded at 2625 (offset 49 lines). patching file src/include/nodes/parsenodes.h Hunk #1 succeeded at 2986 (offset 80 lines). patching file src/test/modules/test_ddl_deparse/expected/alter_table.out patching file src/test/modules/test_ddl_deparse/sql/alter_table.sql patching file src/test/modules/test_ddl_deparse/test_ddl_deparse.c Hunk #1 succeeded at 130 (offset 1 line). patching file src/test/regress/expected/fast_default.out patching file src/test/regress/expected/generated_stored.out Hunk #2 succeeded at 568 (offset 3 lines). Hunk #3 succeeded at 590 (offset 3 lines). Hunk #4 succeeded at 686 (offset 3 lines). Hunk #5 succeeded at 910 (offset 56 lines). Hunk #6 succeeded at 942 (offset 60 lines). Hunk #7 succeeded at 1068 (offset 60 lines). Hunk #8 succeeded at 1163 (offset 60 lines). Hunk #9 succeeded at 1259 (offset 60 lines). Hunk #10 succeeded at 1410 (offset 69 lines). Hunk #11 succeeded at 1502 (offset 71 lines). Hunk #12 succeeded at 1532 (offset 71 lines). patching file src/test/regress/expected/generated_virtual.out Hunk #2 FAILED at 651. Hunk #3 succeeded at 964 (offset 15 lines). Hunk #4 succeeded at 1068 (offset 24 lines). Hunk #5 succeeded at 1164 (offset 24 lines). Hunk #6 succeeded at 1309 (offset 24 lines). Hunk #7 succeeded at 1405 (offset 26 lines). Hunk #8 succeeded at 1434 (offset 26 lines). 1 out of 8 hunks FAILED -- saving rejects to file src/test/regress/expected/generated_virtual.out.rej patching file src/test/regress/expected/publication.out Hunk #1 succeeded at 1097 (offset 221 lines). patching file src/test/regress/sql/fast_default.sql patching file src/test/regress/sql/generated_stored.sql Hunk #5 succeeded at 456 (offset 34 lines). Hunk #6 succeeded at 488 (offset 39 lines). Hunk #7 succeeded at 549 (offset 39 lines). Hunk #8 succeeded at 566 (offset 39 lines). Hunk #9 succeeded at 594 (offset 39 lines). Hunk #10 succeeded at 660 (offset 47 lines). Hunk #11 succeeded at 693 (offset 47 lines). Hunk #12 succeeded at 709 (offset 47 lines). Hunk #13 succeeded at 724 (offset 47 lines). patching file src/test/regress/sql/generated_virtual.sql Hunk #2 FAILED at 326. Hunk #3 succeeded at 539 (offset 2 lines). Hunk #4 succeeded at 563 (offset 9 lines). Hunk #5 succeeded at 591 (offset 9 lines). Hunk #6 succeeded at 653 (offset 9 lines). Hunk #7 succeeded at 687 (offset 9 lines). Hunk #8 succeeded at 703 (offset 9 lines). 1 out of 8 hunks FAILED -- saving rejects to file src/test/regress/sql/generated_virtual.sql.rej patching file src/test/regress/sql/publication.sql Hunk #1 succeeded at 645 (offset 98 lines). patching file src/tools/pgindent/typedefs.list Hunk #1 succeeded at 1087 (offset 38 lines). Unstaged changes after reset: M doc/src/sgml/ref/alter_table.sgml M src/backend/access/heap/heapam_handler.c M src/backend/commands/tablecmds.c M src/backend/parser/gram.y M src/include/nodes/parsenodes.h M src/test/modules/test_ddl_deparse/expected/alter_table.out M src/test/modules/test_ddl_deparse/sql/alter_table.sql M src/test/modules/test_ddl_deparse/test_ddl_deparse.c M src/test/regress/expected/fast_default.out M src/test/regress/expected/generated_stored.out M src/test/regress/expected/generated_virtual.out M src/test/regress/expected/publication.out M src/test/regress/sql/fast_default.sql M src/test/regress/sql/generated_stored.sql M src/test/regress/sql/generated_virtual.sql M src/test/regress/sql/publication.sql M src/tools/pgindent/typedefs.list Removing doc/src/sgml/ref/alter_table.sgml.rej Removing src/backend/commands/tablecmds.c.rej Removing src/test/regress/expected/generated_virtual.out.rej Removing src/test/regress/sql/generated_virtual.sql.rej === using 'git apply' to apply patch ./v3-0001-ALTER-COLUMN-SET-EXPRESSION-VIRTUAL-STORED.patch === Applied patch to 'doc/src/sgml/ref/alter_table.sgml' with conflicts. Applied patch to 'src/backend/access/heap/heapam_handler.c' cleanly. Applied patch to 'src/backend/commands/tablecmds.c' with conflicts. Applied patch to 'src/backend/parser/gram.y' cleanly. Applied patch to 'src/include/nodes/parsenodes.h' cleanly. Applied patch to 'src/test/modules/test_ddl_deparse/expected/alter_table.out' cleanly. Applied patch to 'src/test/modules/test_ddl_deparse/sql/alter_table.sql' cleanly. Applied patch to 'src/test/modules/test_ddl_deparse/test_ddl_deparse.c' cleanly. Applied patch to 'src/test/regress/expected/fast_default.out' cleanly. Applied patch to 'src/test/regress/expected/generated_stored.out' cleanly. Applied patch to 'src/test/regress/expected/generated_virtual.out' with conflicts. Applied patch to 'src/test/regress/expected/publication.out' cleanly. Applied patch to 'src/test/regress/sql/fast_default.sql' cleanly. Applied patch to 'src/test/regress/sql/generated_stored.sql' cleanly. Applied patch to 'src/test/regress/sql/generated_virtual.sql' with conflicts. Applied patch to 'src/test/regress/sql/publication.sql' cleanly. Applied patch to 'src/tools/pgindent/typedefs.list' cleanly. U doc/src/sgml/ref/alter_table.sgml U src/backend/commands/tablecmds.c U src/test/regress/expected/generated_virtual.out U src/test/regress/sql/generated_virtual.sql diff --cc doc/src/sgml/ref/alter_table.sgml index 453395c5c73,cfb3a114fa0..00000000000 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@@ -273,15 -272,22 +273,31 @@@ WITH ( MODULUS - SET EXPRESSION AS + SET EXPRESSION AS ( expression ) [ STORED | VIRTUAL ] ++<<<<<<< ours + This form replaces the expression of a generated column. Existing data + in a stored generated column is rewritten and all the future changes + will apply the new generation expression. + Replacing the expression of a virtual generated column do not require a + table rewrite, but if the column is used in a constraint, the table will + be scanned to check that existing rows meet the constraint. ++======= + This form replaces the expression of a generated column and may optionally + change its storage persistence type. + + + If the column is stored generated column or STORED is + specified, existing data is rewritten and all the future changes will apply + the new generation expression. + If VIRTUAL is specified, existing data won’t be rewritten, + and pg_attribute.attgenerated + is set to v. + If STORED is specified, + pg_attribute.attgenerated + set to s. ++>>>>>>> theirs diff --cc src/backend/commands/tablecmds.c index eec09ba1ded,b40019188a5..00000000000 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@@ -8725,6 -8668,19 +8728,22 @@@ ATExecSetExpression(AlteredTableInfo *t errmsg("column \"%s\" of relation \"%s\" is not a generated column", colName, RelationGetRelationName(rel)))); ++<<<<<<< ours ++======= + /* + * TODO: This could be done, just need to recheck any constraints + * afterwards. + */ + if (!IsA(newExpr, GenerationExpr) && + attgenerated == ATTRIBUTE_GENERATED_VIRTUAL && + rel->rd_att->constr && rel->rd_att->constr->num_check > 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns in tables with check constraints"), + errdetail("Column \"%s\" of relation \"%s\" is a virtual generated column.", + colName, RelationGetRelationName(rel)))); + ++>>>>>>> theirs if (attgenerated == ATTRIBUTE_GENERATED_VIRTUAL && attTup->attnotnull) tab->verify_new_notnull = true; diff --cc src/test/regress/expected/generated_virtual.out index 234061fa1f7,68ffc938665..00000000000 --- a/src/test/regress/expected/generated_virtual.out +++ b/src/test/regress/expected/generated_virtual.out @@@ -642,25 -645,24 +648,46 @@@ INSERT INTO gtest20 (a) VALUES (10); - INSERT INTO gtest20 (a) VALUES (30); -- violates constraint ERROR: new row for relation "gtest20" violates check constraint "gtest20_b_check" DETAIL: Failing row contains (30, virtual). ++<<<<<<< ours +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint +ERROR: check constraint "gtest20_b_check" of relation "gtest20" is violated by some row +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok +-- table rewrite should not happen +SELECT pg_relation_filenode('gtest20') AS gtest20_filenode \gset +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 4), ADD COLUMN c INT DEFAULT 11; +SELECT pg_relation_filenode('gtest20') = :gtest20_filenode AS is_same_file; + is_same_file +-------------- + t +(1 row) + +\d gtest20 + Table "generated_virtual_tests.gtest20" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+----------------------------- + a | integer | | not null | + b | integer | | | generated always as (a * 4) + c | integer | | | 11 ++======= + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint (currently not supported) + ERROR: ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns in tables with check constraints + DETAIL: Column "b" of relation "gtest20" is a virtual generated column. + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok (currently not supported) + ERROR: ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns in tables with check constraints + DETAIL: Column "b" of relation "gtest20" is a virtual generated column. + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3) VIRTUAL; -- ok (currently not supported) + ERROR: ALTER TABLE / SET EXPRESSION VIRTUAL is not supported for virtual generated columns in tables with check constraints + DETAIL: Column "b" of relation "gtest20" is a virtual generated column. + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 5) STORED; --error, violates constraint + ERROR: check constraint "gtest20_b_check" of relation "gtest20" is violated by some row + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3) STORED; --ok + \d gtest20 + Table "generated_virtual_tests.gtest20" + Column | Type | Collation | Nullable | Default + --------+---------+-----------+----------+------------------------------------ + a | integer | | not null | + b | integer | | | generated always as (a * 3) stored ++>>>>>>> theirs Indexes: "gtest20_pkey" PRIMARY KEY, btree (a) Check constraints: diff --cc src/test/regress/sql/generated_virtual.sql index 4d9ad3c5dca,1782558fd7f..00000000000 --- a/src/test/regress/sql/generated_virtual.sql +++ b/src/test/regress/sql/generated_virtual.sql @@@ -317,12 -324,11 +324,20 @@@ CREATE TABLE gtest20 (a int PRIMARY KEY INSERT INTO gtest20 (a) VALUES (10); -- ok INSERT INTO gtest20 (a) VALUES (30); -- violates constraint ++<<<<<<< ours +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok +-- table rewrite should not happen +SELECT pg_relation_filenode('gtest20') AS gtest20_filenode \gset +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 4), ADD COLUMN c INT DEFAULT 11; +SELECT pg_relation_filenode('gtest20') = :gtest20_filenode AS is_same_file; ++======= + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint (currently not supported) + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok (currently not supported) + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3) VIRTUAL; -- ok (currently not supported) + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 5) STORED; --error, violates constraint + ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3) STORED; --ok ++>>>>>>> theirs \d gtest20 CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);