Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8d3d4fa

Browse files
author
Commitfest Bot
committed
[CF 5645] v1 - support ALTER COLUMN SET EXPRESSION over virtual generated column with check constraint
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5645 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/CACJufxF9vVYcx53yJpC6Oo7Y7_=20=pmv_t-6SBKAJ63bQXhnQ@mail.gmail.com Author(s): Jian He
2 parents 03c53a7 + 50f45ee commit 8d3d4fa

File tree

3 files changed

+50
-29
lines changed

3 files changed

+50
-29
lines changed

src/backend/commands/tablecmds.c

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8601,18 +8601,6 @@ ATExecSetExpression(AlteredTableInfo *tab, Relation rel, const char *colName,
86018601
errmsg("column \"%s\" of relation \"%s\" is not a generated column",
86028602
colName, RelationGetRelationName(rel))));
86038603

8604-
/*
8605-
* TODO: This could be done, just need to recheck any constraints
8606-
* afterwards.
8607-
*/
8608-
if (attgenerated == ATTRIBUTE_GENERATED_VIRTUAL &&
8609-
rel->rd_att->constr && rel->rd_att->constr->num_check > 0)
8610-
ereport(ERROR,
8611-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8612-
errmsg("ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns on tables with check constraints"),
8613-
errdetail("Column \"%s\" of relation \"%s\" is a virtual generated column.",
8614-
colName, RelationGetRelationName(rel))));
8615-
86168604
if (attgenerated == ATTRIBUTE_GENERATED_VIRTUAL && attTup->attnotnull)
86178605
tab->verify_new_notnull = true;
86188606

@@ -8642,17 +8630,16 @@ ATExecSetExpression(AlteredTableInfo *tab, Relation rel, const char *colName,
86428630
* this renders them pointless.
86438631
*/
86448632
RelationClearMissing(rel);
8633+
}
86458634

8646-
/* make sure we don't conflict with later attribute modifications */
8647-
CommandCounterIncrement();
8635+
/* make sure we don't conflict with later attribute modifications */
8636+
CommandCounterIncrement();
86488637

8649-
/*
8650-
* Find everything that depends on the column (constraints, indexes,
8651-
* etc), and record enough information to let us recreate the objects
8652-
* after rewrite.
8653-
*/
8654-
RememberAllDependentForRebuilding(tab, AT_SetExpression, rel, attnum, colName);
8655-
}
8638+
/*
8639+
* Find everything that depends on the column (constraints, indexes,
8640+
* etc), and record enough information to let us recreate the objects.
8641+
*/
8642+
RememberAllDependentForRebuilding(tab, AT_SetExpression, rel, attnum, colName);
86568643

86578644
/*
86588645
* Drop the dependency records of the GENERATED expression, in particular

src/test/regress/expected/generated_virtual.out

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -636,12 +636,22 @@ INSERT INTO gtest20 (a) VALUES (10); -- ok
636636
INSERT INTO gtest20 (a) VALUES (30); -- violates constraint
637637
ERROR: new row for relation "gtest20" violates check constraint "gtest20_b_check"
638638
DETAIL: Failing row contains (30, virtual).
639-
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint (currently not supported)
640-
ERROR: ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns on tables with check constraints
641-
DETAIL: Column "b" of relation "gtest20" is a virtual generated column.
642-
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok (currently not supported)
643-
ERROR: ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns on tables with check constraints
644-
DETAIL: Column "b" of relation "gtest20" is a virtual generated column.
639+
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint
640+
ERROR: check constraint "gtest20_b_check" of relation "gtest20" is violated by some row
641+
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok
642+
--test no table rewrite happen
643+
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 4), ADD COLUMN C int default 11;
644+
SELECT pa.attnum,pa.attname,attmissingval
645+
FROM pg_attribute pa
646+
JOIN pg_attrdef patt ON pa.attrelid = patt.adrelid AND pa.attnum = patt.adnum
647+
WHERE pa.attrelid = 'gtest20'::regclass
648+
ORDER BY pa.attnum;
649+
attnum | attname | attmissingval
650+
--------+---------+---------------
651+
2 | b |
652+
3 | c | {11}
653+
(2 rows)
654+
645655
CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);
646656
INSERT INTO gtest20a (a) VALUES (10);
647657
INSERT INTO gtest20a (a) VALUES (30);
@@ -973,6 +983,15 @@ SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3;
973983
gtest_child3 | 09-13-2016 | 1 | 4
974984
(3 rows)
975985

986+
--check constraint was validated based on each partitions's generation expression
987+
ALTER TABLE gtest_parent ADD CONSTRAINT cc1 CHECK (f3 < 19); --error
988+
ERROR: check constraint "cc1" of relation "gtest_child" is violated by some row
989+
ALTER TABLE gtest_parent ADD CONSTRAINT cc1 CHECK (f3 < 66); --error
990+
ERROR: check constraint "cc1" of relation "gtest_child2" is violated by some row
991+
ALTER TABLE gtest_parent ADD CONSTRAINT cc1 CHECK (f3 <> 33); --error
992+
ERROR: check constraint "cc1" of relation "gtest_child3" is violated by some row
993+
ALTER TABLE gtest_parent ADD CONSTRAINT cc CHECK (f3 < 67); --ok
994+
ALTER TABLE gtest_parent DROP CONSTRAINT cc;
976995
-- alter generation expression of parent and all its children altogether
977996
ALTER TABLE gtest_parent ALTER COLUMN f3 SET EXPRESSION AS (f2 * 2);
978997
\d gtest_parent

src/test/regress/sql/generated_virtual.sql

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,15 @@ CREATE TABLE gtest20 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTU
312312
INSERT INTO gtest20 (a) VALUES (10); -- ok
313313
INSERT INTO gtest20 (a) VALUES (30); -- violates constraint
314314

315-
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint (currently not supported)
316-
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok (currently not supported)
315+
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint
316+
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok
317+
--test no table rewrite happen
318+
ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 4), ADD COLUMN C int default 11;
319+
SELECT pa.attnum,pa.attname,attmissingval
320+
FROM pg_attribute pa
321+
JOIN pg_attrdef patt ON pa.attrelid = patt.adrelid AND pa.attnum = patt.adnum
322+
WHERE pa.attrelid = 'gtest20'::regclass
323+
ORDER BY pa.attnum;
317324

318325
CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);
319326
INSERT INTO gtest20a (a) VALUES (10);
@@ -523,6 +530,14 @@ ALTER TABLE gtest_child ALTER COLUMN f3 SET EXPRESSION AS (f2 * 10);
523530
\d gtest_child3
524531
SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3;
525532

533+
--check constraint was validated based on each partitions's generation expression
534+
ALTER TABLE gtest_parent ADD CONSTRAINT cc1 CHECK (f3 < 19); --error
535+
ALTER TABLE gtest_parent ADD CONSTRAINT cc1 CHECK (f3 < 66); --error
536+
ALTER TABLE gtest_parent ADD CONSTRAINT cc1 CHECK (f3 <> 33); --error
537+
538+
ALTER TABLE gtest_parent ADD CONSTRAINT cc CHECK (f3 < 67); --ok
539+
ALTER TABLE gtest_parent DROP CONSTRAINT cc;
540+
526541
-- alter generation expression of parent and all its children altogether
527542
ALTER TABLE gtest_parent ALTER COLUMN f3 SET EXPRESSION AS (f2 * 2);
528543
\d gtest_parent

0 commit comments

Comments
 (0)