mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
Fix ALTER TABLE ADD VIRTUAL GENERATED COLUMN when table rewrite
demo: CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL); ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT RANDOM() CHECK (b < 60); ERROR: no generation expression found for column number 2 of table "pg_temp_17306" In ATRewriteTable, the variable OIDNewHeap (if valid) corresponding pg_attrdef default expression entry was not populated. So OIDNewHeap cannot be used to call expand_generated_columns_in_expr or build_generation_expression. Therefore in ATRewriteTable, we can only use the existing relation to expand the generated expression. Author: jian he <jian.universality@gmail.com> Reviewed-by: Srinath Reddy <srinath2133@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/CACJufxEJ%3DFoajabWXjszo_yrQeKSxdZ87KJqBW373rSbajKGAA%40mail.gmail.com
This commit is contained in:
@ -6137,7 +6137,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
|
|||||||
{
|
{
|
||||||
case CONSTR_CHECK:
|
case CONSTR_CHECK:
|
||||||
needscan = true;
|
needscan = true;
|
||||||
con->qualstate = ExecPrepareExpr((Expr *) expand_generated_columns_in_expr(con->qual, newrel ? newrel : oldrel, 1), estate);
|
con->qualstate = ExecPrepareExpr((Expr *) expand_generated_columns_in_expr(con->qual, oldrel, 1), estate);
|
||||||
break;
|
break;
|
||||||
case CONSTR_FOREIGN:
|
case CONSTR_FOREIGN:
|
||||||
/* Nothing to do here */
|
/* Nothing to do here */
|
||||||
|
@ -656,6 +656,10 @@ INSERT INTO gtest20a (a) VALUES (10);
|
|||||||
INSERT INTO gtest20a (a) VALUES (30);
|
INSERT INTO gtest20a (a) VALUES (30);
|
||||||
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
|
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
|
||||||
ERROR: check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
|
ERROR: check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
|
||||||
|
-- table rewrite cases
|
||||||
|
ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 50); -- fails on existing row
|
||||||
|
ERROR: check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
|
||||||
|
ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 61); -- ok
|
||||||
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
|
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
|
||||||
INSERT INTO gtest20b (a) VALUES (10);
|
INSERT INTO gtest20b (a) VALUES (10);
|
||||||
INSERT INTO gtest20b (a) VALUES (30);
|
INSERT INTO gtest20b (a) VALUES (30);
|
||||||
|
@ -647,6 +647,10 @@ INSERT INTO gtest20a (a) VALUES (10);
|
|||||||
INSERT INTO gtest20a (a) VALUES (30);
|
INSERT INTO gtest20a (a) VALUES (30);
|
||||||
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
|
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
|
||||||
ERROR: check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
|
ERROR: check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
|
||||||
|
-- table rewrite cases
|
||||||
|
ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 50); -- fails on existing row
|
||||||
|
ERROR: check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
|
||||||
|
ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 61); -- ok
|
||||||
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);
|
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);
|
||||||
INSERT INTO gtest20b (a) VALUES (10);
|
INSERT INTO gtest20b (a) VALUES (10);
|
||||||
INSERT INTO gtest20b (a) VALUES (30);
|
INSERT INTO gtest20b (a) VALUES (30);
|
||||||
|
@ -319,6 +319,9 @@ CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STOR
|
|||||||
INSERT INTO gtest20a (a) VALUES (10);
|
INSERT INTO gtest20a (a) VALUES (10);
|
||||||
INSERT INTO gtest20a (a) VALUES (30);
|
INSERT INTO gtest20a (a) VALUES (30);
|
||||||
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
|
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
|
||||||
|
-- table rewrite cases
|
||||||
|
ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 50); -- fails on existing row
|
||||||
|
ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 61); -- ok
|
||||||
|
|
||||||
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
|
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
|
||||||
INSERT INTO gtest20b (a) VALUES (10);
|
INSERT INTO gtest20b (a) VALUES (10);
|
||||||
|
@ -319,6 +319,9 @@ CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRT
|
|||||||
INSERT INTO gtest20a (a) VALUES (10);
|
INSERT INTO gtest20a (a) VALUES (10);
|
||||||
INSERT INTO gtest20a (a) VALUES (30);
|
INSERT INTO gtest20a (a) VALUES (30);
|
||||||
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
|
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
|
||||||
|
-- table rewrite cases
|
||||||
|
ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 50); -- fails on existing row
|
||||||
|
ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 61); -- ok
|
||||||
|
|
||||||
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);
|
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) VIRTUAL);
|
||||||
INSERT INTO gtest20b (a) VALUES (10);
|
INSERT INTO gtest20b (a) VALUES (10);
|
||||||
|
Reference in New Issue
Block a user