Fix virtual generated column type checking for ALTER TABLE
authorPeter Eisentraut <peter@eisentraut.org>
Tue, 24 Jun 2025 09:30:49 +0000 (11:30 +0200)
committerPeter Eisentraut <peter@eisentraut.org>
Tue, 24 Jun 2025 09:31:26 +0000 (11:31 +0200)
Virtual generated columns have some special checks in
CheckAttributeType(), mainly to check that domains are not used.  But
this check was only applied during CREATE TABLE, not during ALTER
TABLE.  This fixes that.

Reported-by: jian he <jian.universality@gmail.com>
Discussion: https://www.postgresql.org/message-id/CACJufxE0KHR__-h=zHXbhSNZXMMs4LYo4-dbj8H3YoStYBok1Q@mail.gmail.com

src/backend/commands/tablecmds.c
src/test/regress/expected/generated_virtual.out
src/test/regress/sql/generated_virtual.sql

index ea96947d81305db07356ee407766f956f6de6e78..074ddb6b9cd17fe8c8a27a54d0f4e1f91077aca3 100644 (file)
@@ -7374,7 +7374,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
    /* make sure datatype is legal for a column */
    CheckAttributeType(NameStr(attribute->attname), attribute->atttypid, attribute->attcollation,
                       list_make1_oid(rel->rd_rel->reltype),
-                      0);
+                      (attribute->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL ? CHKATYPE_IS_VIRTUAL : 0));
 
    InsertPgAttributeTuples(attrdesc, tupdesc, myrelid, NULL, NULL);
 
@@ -14426,7 +14426,7 @@ ATPrepAlterColumnType(List **wqueue,
    /* make sure datatype is legal for a column */
    CheckAttributeType(colName, targettype, targetcollid,
                       list_make1_oid(rel->rd_rel->reltype),
-                      0);
+                      (attTup->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL ? CHKATYPE_IS_VIRTUAL : 0));
 
    if (attTup->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
    {
index 6300e7c1d96e1bb0cb0629d61bb9bf826e497d4b..ab35a77477445684771ee3c3ef4b3208ffc04021 100644 (file)
@@ -800,6 +800,12 @@ CREATE TABLE gtest24r (a int PRIMARY KEY, b gtestdomain1range GENERATED ALWAYS A
 ERROR:  virtual generated column "b" cannot have a domain type
 --INSERT INTO gtest24r (a) VALUES (4);  -- ok
 --INSERT INTO gtest24r (a) VALUES (6);  -- error
+CREATE TABLE gtest24at (a int PRIMARY KEY);
+ALTER TABLE gtest24at ADD COLUMN b gtestdomain1 GENERATED ALWAYS AS (a * 2) VIRTUAL;  -- error
+ERROR:  virtual generated column "b" cannot have a domain type
+CREATE TABLE gtest24ata (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);
+ALTER TABLE gtest24ata ALTER COLUMN b TYPE gtestdomain1;  -- error
+ERROR:  virtual generated column "b" cannot have a domain type
 CREATE DOMAIN gtestdomainnn AS int CHECK (VALUE IS NOT NULL);
 CREATE TABLE gtest24nn (a int, b gtestdomainnn GENERATED ALWAYS AS (a * 2) VIRTUAL);
 ERROR:  virtual generated column "b" cannot have a domain type
index b4eedeee2fb27bc095a528c53c7ebb5de9d9c2b1..9011c9d26745f2a98385b4694dc2798465298ea5 100644 (file)
@@ -453,6 +453,11 @@ CREATE TABLE gtest24r (a int PRIMARY KEY, b gtestdomain1range GENERATED ALWAYS A
 --INSERT INTO gtest24r (a) VALUES (4);  -- ok
 --INSERT INTO gtest24r (a) VALUES (6);  -- error
 
+CREATE TABLE gtest24at (a int PRIMARY KEY);
+ALTER TABLE gtest24at ADD COLUMN b gtestdomain1 GENERATED ALWAYS AS (a * 2) VIRTUAL;  -- error
+CREATE TABLE gtest24ata (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);
+ALTER TABLE gtest24ata ALTER COLUMN b TYPE gtestdomain1;  -- error
+
 CREATE DOMAIN gtestdomainnn AS int CHECK (VALUE IS NOT NULL);
 CREATE TABLE gtest24nn (a int, b gtestdomainnn GENERATED ALWAYS AS (a * 2) VIRTUAL);
 --INSERT INTO gtest24nn (a) VALUES (4);  -- ok