1-- sanity check of system catalog 2SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's'); 3 attrelid | attname | attgenerated 4----------+---------+-------------- 5(0 rows) 6 7CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED); 8CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); 9SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_name LIKE 'gtest_' ORDER BY 1, 2; 10 table_name | column_name | column_default | is_nullable | is_generated | generation_expression 11------------+-------------+----------------+-------------+--------------+----------------------- 12 gtest0 | a | | NO | NEVER | 13 gtest0 | b | | YES | ALWAYS | 55 14 gtest1 | a | | NO | NEVER | 15 gtest1 | b | | YES | ALWAYS | (a * 2) 16(4 rows) 17 18SELECT table_name, column_name, dependent_column FROM information_schema.column_column_usage ORDER BY 1, 2, 3; 19 table_name | column_name | dependent_column 20------------+-------------+------------------ 21 gtest1 | a | b 22(1 row) 23 24\d gtest1 25 Table "public.gtest1" 26 Column | Type | Collation | Nullable | Default 27--------+---------+-----------+----------+------------------------------------ 28 a | integer | | not null | 29 b | integer | | | generated always as (a * 2) stored 30Indexes: 31 "gtest1_pkey" PRIMARY KEY, btree (a) 32 33-- duplicate generated 34CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ALWAYS AS (a * 3) STORED); 35ERROR: multiple generation clauses specified for column "b" of table "gtest_err_1" 36LINE 1: ...ARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ... 37 ^ 38-- references to other generated columns, including self-references 39CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED); 40ERROR: cannot use generated column "b" in column generation expression 41LINE 1: ...2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STO... 42 ^ 43DETAIL: A generated column cannot reference another generated column. 44CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED); 45ERROR: cannot use generated column "b" in column generation expression 46LINE 1: ...AYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STO... 47 ^ 48DETAIL: A generated column cannot reference another generated column. 49-- a whole-row var is a self-reference on steroids, so disallow that too 50CREATE TABLE gtest_err_2c (a int PRIMARY KEY, 51 b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c)) STORED); 52ERROR: cannot use whole-row variable in column generation expression 53LINE 2: b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c)) STOR... 54 ^ 55DETAIL: This would cause the generated column to depend on its own value. 56-- invalid reference 57CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED); 58ERROR: column "c" does not exist 59LINE 1: ..._3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STO... 60 ^ 61-- generation expression must be immutable 62CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) STORED); 63ERROR: generation expression is not immutable 64-- cannot have default/identity and generated 65CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED); 66ERROR: both default and generation expression specified for column "b" of table "gtest_err_5a" 67LINE 1: ... gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ... 68 ^ 69CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED); 70ERROR: both identity and generation expression specified for column "b" of table "gtest_err_5b" 71LINE 1: ...t PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ... 72 ^ 73-- reference to system column not allowed in generated column 74-- (except tableoid, which we test below) 75CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED); 76ERROR: cannot use system column "xmin" in column generation expression 77LINE 1: ...a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37... 78 ^ 79-- various prohibited constructs 80CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED); 81ERROR: aggregate functions are not allowed in column generation expressions 82LINE 1: ...7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) ST... 83 ^ 84CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER BY a)) STORED); 85ERROR: window functions are not allowed in column generation expressions 86LINE 1: ...7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number... 87 ^ 88CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED); 89ERROR: cannot use subquery in column generation expression 90LINE 1: ...7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)... 91 ^ 92CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED); 93ERROR: set-returning functions are not allowed in column generation expressions 94LINE 1: ...7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_s... 95 ^ 96-- GENERATED BY DEFAULT not allowed 97CREATE TABLE gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT AS (a * 2) STORED); 98ERROR: for a generated column, GENERATED ALWAYS must be specified 99LINE 1: ...E gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT... 100 ^ 101INSERT INTO gtest1 VALUES (1); 102INSERT INTO gtest1 VALUES (2, DEFAULT); -- ok 103INSERT INTO gtest1 VALUES (3, 33); -- error 104ERROR: cannot insert a non-DEFAULT value into column "b" 105DETAIL: Column "b" is a generated column. 106INSERT INTO gtest1 VALUES (3, 33), (4, 44); -- error 107ERROR: cannot insert a non-DEFAULT value into column "b" 108DETAIL: Column "b" is a generated column. 109INSERT INTO gtest1 VALUES (3, DEFAULT), (4, 44); -- error 110ERROR: cannot insert a non-DEFAULT value into column "b" 111DETAIL: Column "b" is a generated column. 112INSERT INTO gtest1 VALUES (3, 33), (4, DEFAULT); -- error 113ERROR: cannot insert a non-DEFAULT value into column "b" 114DETAIL: Column "b" is a generated column. 115INSERT INTO gtest1 VALUES (3, DEFAULT), (4, DEFAULT); -- ok 116SELECT * FROM gtest1 ORDER BY a; 117 a | b 118---+--- 119 1 | 2 120 2 | 4 121 3 | 6 122 4 | 8 123(4 rows) 124 125DELETE FROM gtest1 WHERE a >= 3; 126UPDATE gtest1 SET b = DEFAULT WHERE a = 1; 127UPDATE gtest1 SET b = 11 WHERE a = 1; -- error 128ERROR: column "b" can only be updated to DEFAULT 129DETAIL: Column "b" is a generated column. 130SELECT * FROM gtest1 ORDER BY a; 131 a | b 132---+--- 133 1 | 2 134 2 | 4 135(2 rows) 136 137SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a; 138 a | b | b2 139---+---+---- 140 1 | 2 | 4 141 2 | 4 | 8 142(2 rows) 143 144SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a; 145 a | b 146---+--- 147 2 | 4 148(1 row) 149 150-- test that overflow error happens on write 151INSERT INTO gtest1 VALUES (2000000000); 152ERROR: integer out of range 153SELECT * FROM gtest1; 154 a | b 155---+--- 156 2 | 4 157 1 | 2 158(2 rows) 159 160DELETE FROM gtest1 WHERE a = 2000000000; 161-- test with joins 162CREATE TABLE gtestx (x int, y int); 163INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3); 164SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a; 165 x | y | a | b 166----+---+---+--- 167 11 | 1 | 1 | 2 168 22 | 2 | 2 | 4 169(2 rows) 170 171DROP TABLE gtestx; 172-- test UPDATE/DELETE quals 173SELECT * FROM gtest1 ORDER BY a; 174 a | b 175---+--- 176 1 | 2 177 2 | 4 178(2 rows) 179 180UPDATE gtest1 SET a = 3 WHERE b = 4; 181SELECT * FROM gtest1 ORDER BY a; 182 a | b 183---+--- 184 1 | 2 185 3 | 6 186(2 rows) 187 188DELETE FROM gtest1 WHERE b = 2; 189SELECT * FROM gtest1 ORDER BY a; 190 a | b 191---+--- 192 3 | 6 193(1 row) 194 195-- views 196CREATE VIEW gtest1v AS SELECT * FROM gtest1; 197SELECT * FROM gtest1v; 198 a | b 199---+--- 200 3 | 6 201(1 row) 202 203INSERT INTO gtest1v VALUES (4, 8); -- error 204ERROR: cannot insert a non-DEFAULT value into column "b" 205DETAIL: Column "b" is a generated column. 206INSERT INTO gtest1v VALUES (5, DEFAULT); -- ok 207INSERT INTO gtest1v VALUES (6, 66), (7, 77); -- error 208ERROR: cannot insert a non-DEFAULT value into column "b" 209DETAIL: Column "b" is a generated column. 210INSERT INTO gtest1v VALUES (6, DEFAULT), (7, 77); -- error 211ERROR: cannot insert a non-DEFAULT value into column "b" 212DETAIL: Column "b" is a generated column. 213INSERT INTO gtest1v VALUES (6, 66), (7, DEFAULT); -- error 214ERROR: cannot insert a non-DEFAULT value into column "b" 215DETAIL: Column "b" is a generated column. 216INSERT INTO gtest1v VALUES (6, DEFAULT), (7, DEFAULT); -- ok 217ALTER VIEW gtest1v ALTER COLUMN b SET DEFAULT 100; 218INSERT INTO gtest1v VALUES (8, DEFAULT); -- error 219ERROR: cannot insert a non-DEFAULT value into column "b" 220DETAIL: Column "b" is a generated column. 221INSERT INTO gtest1v VALUES (8, DEFAULT), (9, DEFAULT); -- error 222ERROR: cannot insert a non-DEFAULT value into column "b" 223DETAIL: Column "b" is a generated column. 224SELECT * FROM gtest1v; 225 a | b 226---+---- 227 3 | 6 228 5 | 10 229 6 | 12 230 7 | 14 231(4 rows) 232 233DELETE FROM gtest1v WHERE a >= 5; 234DROP VIEW gtest1v; 235-- CTEs 236WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo; 237 a | b 238---+--- 239 3 | 6 240(1 row) 241 242-- inheritance 243CREATE TABLE gtest1_1 () INHERITS (gtest1); 244SELECT * FROM gtest1_1; 245 a | b 246---+--- 247(0 rows) 248 249\d gtest1_1 250 Table "public.gtest1_1" 251 Column | Type | Collation | Nullable | Default 252--------+---------+-----------+----------+------------------------------------ 253 a | integer | | not null | 254 b | integer | | | generated always as (a * 2) stored 255Inherits: gtest1 256 257INSERT INTO gtest1_1 VALUES (4); 258SELECT * FROM gtest1_1; 259 a | b 260---+--- 261 4 | 8 262(1 row) 263 264SELECT * FROM gtest1; 265 a | b 266---+--- 267 3 | 6 268 4 | 8 269(2 rows) 270 271CREATE TABLE gtest_normal (a int, b int); 272CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED) INHERITS (gtest_normal); 273NOTICE: merging column "a" with inherited definition 274NOTICE: merging column "b" with inherited definition 275\d gtest_normal_child 276 Table "public.gtest_normal_child" 277 Column | Type | Collation | Nullable | Default 278--------+---------+-----------+----------+------------------------------------ 279 a | integer | | | 280 b | integer | | | generated always as (a * 2) stored 281Inherits: gtest_normal 282 283INSERT INTO gtest_normal (a) VALUES (1); 284INSERT INTO gtest_normal_child (a) VALUES (2); 285SELECT * FROM gtest_normal; 286 a | b 287---+--- 288 1 | 289 2 | 4 290(2 rows) 291 292CREATE TABLE gtest_normal_child2 (a int, b int GENERATED ALWAYS AS (a * 3) STORED); 293ALTER TABLE gtest_normal_child2 INHERIT gtest_normal; 294INSERT INTO gtest_normal_child2 (a) VALUES (3); 295SELECT * FROM gtest_normal; 296 a | b 297---+--- 298 1 | 299 2 | 4 300 3 | 9 301(3 rows) 302 303-- test inheritance mismatches between parent and child 304CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS (a * 22) STORED) INHERITS (gtest1); -- error 305NOTICE: merging column "b" with inherited definition 306ERROR: child column "b" specifies generation expression 307HINT: Omit the generation expression in the definition of the child table column to inherit the generation expression from the parent table. 308CREATE TABLE gtestx (x int, b int DEFAULT 10) INHERITS (gtest1); -- error 309NOTICE: merging column "b" with inherited definition 310ERROR: column "b" inherits from generated column but specifies default 311CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS IDENTITY) INHERITS (gtest1); -- error 312NOTICE: merging column "b" with inherited definition 313ERROR: column "b" inherits from generated column but specifies identity 314CREATE TABLE gtestxx_1 (a int NOT NULL, b int); 315ALTER TABLE gtestxx_1 INHERIT gtest1; -- error 316ERROR: column "b" in child table must be a generated column 317CREATE TABLE gtestxx_2 (a int NOT NULL, b int GENERATED ALWAYS AS (a * 22) STORED); 318ALTER TABLE gtestxx_2 INHERIT gtest1; -- error 319ERROR: column "b" in child table has a conflicting generation expression 320CREATE TABLE gtestxx_3 (a int NOT NULL, b int GENERATED ALWAYS AS (a * 2) STORED); 321ALTER TABLE gtestxx_3 INHERIT gtest1; -- ok 322CREATE TABLE gtestxx_4 (b int GENERATED ALWAYS AS (a * 2) STORED, a int NOT NULL); 323ALTER TABLE gtestxx_4 INHERIT gtest1; -- ok 324-- test multiple inheritance mismatches 325CREATE TABLE gtesty (x int, b int); 326CREATE TABLE gtest1_2 () INHERITS (gtest1, gtesty); -- error 327NOTICE: merging multiple inherited definitions of column "b" 328ERROR: inherited column "b" has a generation conflict 329DROP TABLE gtesty; 330CREATE TABLE gtesty (x int, b int GENERATED ALWAYS AS (x * 22) STORED); 331CREATE TABLE gtest1_2 () INHERITS (gtest1, gtesty); -- error 332NOTICE: merging multiple inherited definitions of column "b" 333ERROR: column "b" inherits conflicting generation expressions 334DROP TABLE gtesty; 335CREATE TABLE gtesty (x int, b int DEFAULT 55); 336CREATE TABLE gtest1_2 () INHERITS (gtest0, gtesty); -- error 337NOTICE: merging multiple inherited definitions of column "b" 338ERROR: inherited column "b" has a generation conflict 339DROP TABLE gtesty; 340-- test stored update 341CREATE TABLE gtest3 (a int, b int GENERATED ALWAYS AS (a * 3) STORED); 342INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL); 343SELECT * FROM gtest3 ORDER BY a; 344 a | b 345---+--- 346 1 | 3 347 2 | 6 348 3 | 9 349 | 350(4 rows) 351 352UPDATE gtest3 SET a = 22 WHERE a = 2; 353SELECT * FROM gtest3 ORDER BY a; 354 a | b 355----+---- 356 1 | 3 357 3 | 9 358 22 | 66 359 | 360(4 rows) 361 362CREATE TABLE gtest3a (a text, b text GENERATED ALWAYS AS (a || '+' || a) STORED); 363INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL); 364SELECT * FROM gtest3a ORDER BY a; 365 a | b 366---+----- 367 a | a+a 368 b | b+b 369 c | c+c 370 | 371(4 rows) 372 373UPDATE gtest3a SET a = 'bb' WHERE a = 'b'; 374SELECT * FROM gtest3a ORDER BY a; 375 a | b 376----+------- 377 a | a+a 378 bb | bb+bb 379 c | c+c 380 | 381(4 rows) 382 383-- COPY 384TRUNCATE gtest1; 385INSERT INTO gtest1 (a) VALUES (1), (2); 386COPY gtest1 TO stdout; 3871 3882 389COPY gtest1 (a, b) TO stdout; 390ERROR: column "b" is a generated column 391DETAIL: Generated columns cannot be used in COPY. 392COPY gtest1 FROM stdin; 393COPY gtest1 (a, b) FROM stdin; 394ERROR: column "b" is a generated column 395DETAIL: Generated columns cannot be used in COPY. 396SELECT * FROM gtest1 ORDER BY a; 397 a | b 398---+--- 399 1 | 2 400 2 | 4 401 3 | 6 402 4 | 8 403(4 rows) 404 405TRUNCATE gtest3; 406INSERT INTO gtest3 (a) VALUES (1), (2); 407COPY gtest3 TO stdout; 4081 4092 410COPY gtest3 (a, b) TO stdout; 411ERROR: column "b" is a generated column 412DETAIL: Generated columns cannot be used in COPY. 413COPY gtest3 FROM stdin; 414COPY gtest3 (a, b) FROM stdin; 415ERROR: column "b" is a generated column 416DETAIL: Generated columns cannot be used in COPY. 417SELECT * FROM gtest3 ORDER BY a; 418 a | b 419---+---- 420 1 | 3 421 2 | 6 422 3 | 9 423 4 | 12 424(4 rows) 425 426-- null values 427CREATE TABLE gtest2 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (NULL) STORED); 428INSERT INTO gtest2 VALUES (1); 429SELECT * FROM gtest2; 430 a | b 431---+--- 432 1 | 433(1 row) 434 435-- simple column reference for varlena types 436CREATE TABLE gtest_varlena (a varchar, b varchar GENERATED ALWAYS AS (a) STORED); 437INSERT INTO gtest_varlena (a) VALUES('01234567890123456789'); 438INSERT INTO gtest_varlena (a) VALUES(NULL); 439SELECT * FROM gtest_varlena ORDER BY a; 440 a | b 441----------------------+---------------------- 442 01234567890123456789 | 01234567890123456789 443 | 444(2 rows) 445 446DROP TABLE gtest_varlena; 447-- composite types 448CREATE TYPE double_int as (a int, b int); 449CREATE TABLE gtest4 ( 450 a int, 451 b double_int GENERATED ALWAYS AS ((a * 2, a * 3)) STORED 452); 453INSERT INTO gtest4 VALUES (1), (6); 454SELECT * FROM gtest4; 455 a | b 456---+--------- 457 1 | (2,3) 458 6 | (12,18) 459(2 rows) 460 461DROP TABLE gtest4; 462DROP TYPE double_int; 463-- using tableoid is allowed 464CREATE TABLE gtest_tableoid ( 465 a int PRIMARY KEY, 466 b bool GENERATED ALWAYS AS (tableoid = 'gtest_tableoid'::regclass) STORED 467); 468INSERT INTO gtest_tableoid VALUES (1), (2); 469ALTER TABLE gtest_tableoid ADD COLUMN 470 c regclass GENERATED ALWAYS AS (tableoid) STORED; 471SELECT * FROM gtest_tableoid; 472 a | b | c 473---+---+---------------- 474 1 | t | gtest_tableoid 475 2 | t | gtest_tableoid 476(2 rows) 477 478-- drop column behavior 479CREATE TABLE gtest10 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED); 480ALTER TABLE gtest10 DROP COLUMN b; 481\d gtest10 482 Table "public.gtest10" 483 Column | Type | Collation | Nullable | Default 484--------+---------+-----------+----------+--------- 485 a | integer | | not null | 486Indexes: 487 "gtest10_pkey" PRIMARY KEY, btree (a) 488 489CREATE TABLE gtest10a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); 490ALTER TABLE gtest10a DROP COLUMN b; 491INSERT INTO gtest10a (a) VALUES (1); 492-- privileges 493CREATE USER regress_user11; 494CREATE TABLE gtest11s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED); 495INSERT INTO gtest11s VALUES (1, 10), (2, 20); 496GRANT SELECT (a, c) ON gtest11s TO regress_user11; 497CREATE FUNCTION gf1(a int) RETURNS int AS $$ SELECT a * 3 $$ IMMUTABLE LANGUAGE SQL; 498REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC; 499CREATE TABLE gtest12s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (gf1(b)) STORED); 500INSERT INTO gtest12s VALUES (1, 10), (2, 20); 501GRANT SELECT (a, c) ON gtest12s TO regress_user11; 502SET ROLE regress_user11; 503SELECT a, b FROM gtest11s; -- not allowed 504ERROR: permission denied for table gtest11s 505SELECT a, c FROM gtest11s; -- allowed 506 a | c 507---+---- 508 1 | 20 509 2 | 40 510(2 rows) 511 512SELECT gf1(10); -- not allowed 513ERROR: permission denied for function gf1 514SELECT a, c FROM gtest12s; -- allowed 515 a | c 516---+---- 517 1 | 30 518 2 | 60 519(2 rows) 520 521RESET ROLE; 522DROP TABLE gtest11s, gtest12s; 523DROP FUNCTION gf1(int); 524DROP USER regress_user11; 525-- check constraints 526CREATE TABLE gtest20 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED CHECK (b < 50)); 527INSERT INTO gtest20 (a) VALUES (10); -- ok 528INSERT INTO gtest20 (a) VALUES (30); -- violates constraint 529ERROR: new row for relation "gtest20" violates check constraint "gtest20_b_check" 530DETAIL: Failing row contains (30, 60). 531CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); 532INSERT INTO gtest20a (a) VALUES (10); 533INSERT INTO gtest20a (a) VALUES (30); 534ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row 535ERROR: check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row 536CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); 537INSERT INTO gtest20b (a) VALUES (10); 538INSERT INTO gtest20b (a) VALUES (30); 539ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID; 540ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; -- fails on existing row 541ERROR: check constraint "chk" of relation "gtest20b" is violated by some row 542-- not-null constraints 543CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL); 544INSERT INTO gtest21a (a) VALUES (1); -- ok 545INSERT INTO gtest21a (a) VALUES (0); -- violates constraint 546ERROR: null value in column "b" of relation "gtest21a" violates not-null constraint 547DETAIL: Failing row contains (0, null). 548CREATE TABLE gtest21b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED); 549ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL; 550INSERT INTO gtest21b (a) VALUES (1); -- ok 551INSERT INTO gtest21b (a) VALUES (0); -- violates constraint 552ERROR: null value in column "b" of relation "gtest21b" violates not-null constraint 553DETAIL: Failing row contains (0, null). 554ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL; 555INSERT INTO gtest21b (a) VALUES (0); -- ok now 556-- index constraints 557CREATE TABLE gtest22a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a / 2) STORED UNIQUE); 558INSERT INTO gtest22a VALUES (2); 559INSERT INTO gtest22a VALUES (3); 560ERROR: duplicate key value violates unique constraint "gtest22a_b_key" 561DETAIL: Key (b)=(1) already exists. 562INSERT INTO gtest22a VALUES (4); 563CREATE TABLE gtest22b (a int, b int GENERATED ALWAYS AS (a / 2) STORED, PRIMARY KEY (a, b)); 564INSERT INTO gtest22b VALUES (2); 565INSERT INTO gtest22b VALUES (2); 566ERROR: duplicate key value violates unique constraint "gtest22b_pkey" 567DETAIL: Key (a, b)=(2, 1) already exists. 568-- indexes 569CREATE TABLE gtest22c (a int, b int GENERATED ALWAYS AS (a * 2) STORED); 570CREATE INDEX gtest22c_b_idx ON gtest22c (b); 571CREATE INDEX gtest22c_expr_idx ON gtest22c ((b * 3)); 572CREATE INDEX gtest22c_pred_idx ON gtest22c (a) WHERE b > 0; 573\d gtest22c 574 Table "public.gtest22c" 575 Column | Type | Collation | Nullable | Default 576--------+---------+-----------+----------+------------------------------------ 577 a | integer | | | 578 b | integer | | | generated always as (a * 2) stored 579Indexes: 580 "gtest22c_b_idx" btree (b) 581 "gtest22c_expr_idx" btree ((b * 3)) 582 "gtest22c_pred_idx" btree (a) WHERE b > 0 583 584INSERT INTO gtest22c VALUES (1), (2), (3); 585SET enable_seqscan TO off; 586SET enable_bitmapscan TO off; 587EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b = 4; 588 QUERY PLAN 589--------------------------------------------- 590 Index Scan using gtest22c_b_idx on gtest22c 591 Index Cond: (b = 4) 592(2 rows) 593 594SELECT * FROM gtest22c WHERE b = 4; 595 a | b 596---+--- 597 2 | 4 598(1 row) 599 600EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b * 3 = 6; 601 QUERY PLAN 602------------------------------------------------ 603 Index Scan using gtest22c_expr_idx on gtest22c 604 Index Cond: ((b * 3) = 6) 605(2 rows) 606 607SELECT * FROM gtest22c WHERE b * 3 = 6; 608 a | b 609---+--- 610 1 | 2 611(1 row) 612 613EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE a = 1 AND b > 0; 614 QUERY PLAN 615------------------------------------------------ 616 Index Scan using gtest22c_pred_idx on gtest22c 617 Index Cond: (a = 1) 618(2 rows) 619 620SELECT * FROM gtest22c WHERE a = 1 AND b > 0; 621 a | b 622---+--- 623 1 | 2 624(1 row) 625 626RESET enable_seqscan; 627RESET enable_bitmapscan; 628-- foreign keys 629CREATE TABLE gtest23a (x int PRIMARY KEY, y int); 630INSERT INTO gtest23a VALUES (1, 11), (2, 22), (3, 33); 631CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON UPDATE CASCADE); -- error 632ERROR: invalid ON UPDATE action for foreign key constraint containing generated column 633CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON DELETE SET NULL); -- error 634ERROR: invalid ON DELETE action for foreign key constraint containing generated column 635CREATE TABLE gtest23b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x)); 636\d gtest23b 637 Table "public.gtest23b" 638 Column | Type | Collation | Nullable | Default 639--------+---------+-----------+----------+------------------------------------ 640 a | integer | | not null | 641 b | integer | | | generated always as (a * 2) stored 642Indexes: 643 "gtest23b_pkey" PRIMARY KEY, btree (a) 644Foreign-key constraints: 645 "gtest23b_b_fkey" FOREIGN KEY (b) REFERENCES gtest23a(x) 646 647INSERT INTO gtest23b VALUES (1); -- ok 648INSERT INTO gtest23b VALUES (5); -- error 649ERROR: insert or update on table "gtest23b" violates foreign key constraint "gtest23b_b_fkey" 650DETAIL: Key (b)=(10) is not present in table "gtest23a". 651DROP TABLE gtest23b; 652DROP TABLE gtest23a; 653CREATE TABLE gtest23p (x int, y int GENERATED ALWAYS AS (x * 2) STORED, PRIMARY KEY (y)); 654INSERT INTO gtest23p VALUES (1), (2), (3); 655CREATE TABLE gtest23q (a int PRIMARY KEY, b int REFERENCES gtest23p (y)); 656INSERT INTO gtest23q VALUES (1, 2); -- ok 657INSERT INTO gtest23q VALUES (2, 5); -- error 658ERROR: insert or update on table "gtest23q" violates foreign key constraint "gtest23q_b_fkey" 659DETAIL: Key (b)=(5) is not present in table "gtest23p". 660-- domains 661CREATE DOMAIN gtestdomain1 AS int CHECK (VALUE < 10); 662CREATE TABLE gtest24 (a int PRIMARY KEY, b gtestdomain1 GENERATED ALWAYS AS (a * 2) STORED); 663INSERT INTO gtest24 (a) VALUES (4); -- ok 664INSERT INTO gtest24 (a) VALUES (6); -- error 665ERROR: value for domain gtestdomain1 violates check constraint "gtestdomain1_check" 666-- typed tables (currently not supported) 667CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint); 668CREATE TABLE gtest28 OF gtest_type (f1 WITH OPTIONS GENERATED ALWAYS AS (f2 *2) STORED); 669ERROR: generated columns are not supported on typed tables 670DROP TYPE gtest_type CASCADE; 671-- table partitions (currently not supported) 672CREATE TABLE gtest_parent (f1 date NOT NULL, f2 text, f3 bigint) PARTITION BY RANGE (f1); 673CREATE TABLE gtest_child PARTITION OF gtest_parent ( 674 f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 2) STORED 675) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error 676ERROR: generated columns are not supported on partitions 677DROP TABLE gtest_parent; 678-- partitioned table 679CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f1); 680CREATE TABLE gtest_child PARTITION OF gtest_parent FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); 681INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 1); 682SELECT * FROM gtest_parent; 683 f1 | f2 | f3 684------------+----+---- 685 07-15-2016 | 1 | 2 686(1 row) 687 688SELECT * FROM gtest_child; 689 f1 | f2 | f3 690------------+----+---- 691 07-15-2016 | 1 | 2 692(1 row) 693 694DROP TABLE gtest_parent; 695-- generated columns in partition key (not allowed) 696CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3); 697ERROR: cannot use generated column in partition key 698LINE 1: ...ENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3); 699 ^ 700DETAIL: Column "f3" is a generated column. 701CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE ((f3 * 3)); 702ERROR: cannot use generated column in partition key 703LINE 1: ...ED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE ((f3 * 3)); 704 ^ 705DETAIL: Column "f3" is a generated column. 706-- ALTER TABLE ... ADD COLUMN 707CREATE TABLE gtest25 (a int PRIMARY KEY); 708INSERT INTO gtest25 VALUES (3), (4); 709ALTER TABLE gtest25 ADD COLUMN b int GENERATED ALWAYS AS (a * 3) STORED; 710SELECT * FROM gtest25 ORDER BY a; 711 a | b 712---+---- 713 3 | 9 714 4 | 12 715(2 rows) 716 717ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (b * 4) STORED; -- error 718ERROR: cannot use generated column "b" in column generation expression 719DETAIL: A generated column cannot reference another generated column. 720ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (z * 4) STORED; -- error 721ERROR: column "z" does not exist 722ALTER TABLE gtest25 ADD COLUMN c int DEFAULT 42, 723 ADD COLUMN x int GENERATED ALWAYS AS (c * 4) STORED; 724ALTER TABLE gtest25 ADD COLUMN d int DEFAULT 101; 725ALTER TABLE gtest25 ALTER COLUMN d SET DATA TYPE float8, 726 ADD COLUMN y float8 GENERATED ALWAYS AS (d * 4) STORED; 727SELECT * FROM gtest25 ORDER BY a; 728 a | b | c | x | d | y 729---+----+----+-----+-----+----- 730 3 | 9 | 42 | 168 | 101 | 404 731 4 | 12 | 42 | 168 | 101 | 404 732(2 rows) 733 734\d gtest25 735 Table "public.gtest25" 736 Column | Type | Collation | Nullable | Default 737--------+------------------+-----------+----------+------------------------------------------------------ 738 a | integer | | not null | 739 b | integer | | | generated always as (a * 3) stored 740 c | integer | | | 42 741 x | integer | | | generated always as (c * 4) stored 742 d | double precision | | | 101 743 y | double precision | | | generated always as (d * 4::double precision) stored 744Indexes: 745 "gtest25_pkey" PRIMARY KEY, btree (a) 746 747-- ALTER TABLE ... ALTER COLUMN 748CREATE TABLE gtest27 ( 749 a int, 750 b int, 751 x int GENERATED ALWAYS AS ((a + b) * 2) STORED 752); 753INSERT INTO gtest27 (a, b) VALUES (3, 7), (4, 11); 754ALTER TABLE gtest27 ALTER COLUMN a TYPE text; -- error 755ERROR: cannot alter type of a column used by a generated column 756DETAIL: Column "a" is used by generated column "x". 757ALTER TABLE gtest27 ALTER COLUMN x TYPE numeric; 758\d gtest27 759 Table "public.gtest27" 760 Column | Type | Collation | Nullable | Default 761--------+---------+-----------+----------+-------------------------------------------- 762 a | integer | | | 763 b | integer | | | 764 x | numeric | | | generated always as (((a + b) * 2)) stored 765 766SELECT * FROM gtest27; 767 a | b | x 768---+----+---- 769 3 | 7 | 20 770 4 | 11 | 30 771(2 rows) 772 773ALTER TABLE gtest27 ALTER COLUMN x TYPE boolean USING x <> 0; -- error 774ERROR: generation expression for column "x" cannot be cast automatically to type boolean 775ALTER TABLE gtest27 ALTER COLUMN x DROP DEFAULT; -- error 776ERROR: column "x" of relation "gtest27" is a generated column 777HINT: Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead. 778-- It's possible to alter the column types this way: 779ALTER TABLE gtest27 780 DROP COLUMN x, 781 ALTER COLUMN a TYPE bigint, 782 ALTER COLUMN b TYPE bigint, 783 ADD COLUMN x bigint GENERATED ALWAYS AS ((a + b) * 2) STORED; 784\d gtest27 785 Table "public.gtest27" 786 Column | Type | Collation | Nullable | Default 787--------+--------+-----------+----------+------------------------------------------ 788 a | bigint | | | 789 b | bigint | | | 790 x | bigint | | | generated always as ((a + b) * 2) stored 791 792-- Ideally you could just do this, but not today (and should x change type?): 793ALTER TABLE gtest27 794 ALTER COLUMN a TYPE float8, 795 ALTER COLUMN b TYPE float8; -- error 796ERROR: cannot alter type of a column used by a generated column 797DETAIL: Column "a" is used by generated column "x". 798\d gtest27 799 Table "public.gtest27" 800 Column | Type | Collation | Nullable | Default 801--------+--------+-----------+----------+------------------------------------------ 802 a | bigint | | | 803 b | bigint | | | 804 x | bigint | | | generated always as ((a + b) * 2) stored 805 806SELECT * FROM gtest27; 807 a | b | x 808---+----+---- 809 3 | 7 | 20 810 4 | 11 | 30 811(2 rows) 812 813-- ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION 814CREATE TABLE gtest29 ( 815 a int, 816 b int GENERATED ALWAYS AS (a * 2) STORED 817); 818INSERT INTO gtest29 (a) VALUES (3), (4); 819ALTER TABLE gtest29 ALTER COLUMN a DROP EXPRESSION; -- error 820ERROR: column "a" of relation "gtest29" is not a stored generated column 821ALTER TABLE gtest29 ALTER COLUMN a DROP EXPRESSION IF EXISTS; -- notice 822NOTICE: column "a" of relation "gtest29" is not a stored generated column, skipping 823ALTER TABLE gtest29 ALTER COLUMN b DROP EXPRESSION; 824INSERT INTO gtest29 (a) VALUES (5); 825INSERT INTO gtest29 (a, b) VALUES (6, 66); 826SELECT * FROM gtest29; 827 a | b 828---+---- 829 3 | 6 830 4 | 8 831 5 | 832 6 | 66 833(4 rows) 834 835\d gtest29 836 Table "public.gtest29" 837 Column | Type | Collation | Nullable | Default 838--------+---------+-----------+----------+--------- 839 a | integer | | | 840 b | integer | | | 841 842-- check that dependencies between columns have also been removed 843ALTER TABLE gtest29 DROP COLUMN a; -- should not drop b 844\d gtest29 845 Table "public.gtest29" 846 Column | Type | Collation | Nullable | Default 847--------+---------+-----------+----------+--------- 848 b | integer | | | 849 850-- with inheritance 851CREATE TABLE gtest30 ( 852 a int, 853 b int GENERATED ALWAYS AS (a * 2) STORED 854); 855CREATE TABLE gtest30_1 () INHERITS (gtest30); 856ALTER TABLE gtest30 ALTER COLUMN b DROP EXPRESSION; 857\d gtest30 858 Table "public.gtest30" 859 Column | Type | Collation | Nullable | Default 860--------+---------+-----------+----------+--------- 861 a | integer | | | 862 b | integer | | | 863Number of child tables: 1 (Use \d+ to list them.) 864 865\d gtest30_1 866 Table "public.gtest30_1" 867 Column | Type | Collation | Nullable | Default 868--------+---------+-----------+----------+--------- 869 a | integer | | | 870 b | integer | | | 871Inherits: gtest30 872 873DROP TABLE gtest30 CASCADE; 874NOTICE: drop cascades to table gtest30_1 875CREATE TABLE gtest30 ( 876 a int, 877 b int GENERATED ALWAYS AS (a * 2) STORED 878); 879CREATE TABLE gtest30_1 () INHERITS (gtest30); 880ALTER TABLE ONLY gtest30 ALTER COLUMN b DROP EXPRESSION; -- error 881ERROR: ALTER TABLE / DROP EXPRESSION must be applied to child tables too 882\d gtest30 883 Table "public.gtest30" 884 Column | Type | Collation | Nullable | Default 885--------+---------+-----------+----------+------------------------------------ 886 a | integer | | | 887 b | integer | | | generated always as (a * 2) stored 888Number of child tables: 1 (Use \d+ to list them.) 889 890\d gtest30_1 891 Table "public.gtest30_1" 892 Column | Type | Collation | Nullable | Default 893--------+---------+-----------+----------+------------------------------------ 894 a | integer | | | 895 b | integer | | | generated always as (a * 2) stored 896Inherits: gtest30 897 898ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; -- error 899ERROR: cannot drop generation expression from inherited column 900-- triggers 901CREATE TABLE gtest26 ( 902 a int PRIMARY KEY, 903 b int GENERATED ALWAYS AS (a * 2) STORED 904); 905CREATE FUNCTION gtest_trigger_func() RETURNS trigger 906 LANGUAGE plpgsql 907AS $$ 908BEGIN 909 IF tg_op IN ('DELETE', 'UPDATE') THEN 910 RAISE INFO '%: %: old = %', TG_NAME, TG_WHEN, OLD; 911 END IF; 912 IF tg_op IN ('INSERT', 'UPDATE') THEN 913 RAISE INFO '%: %: new = %', TG_NAME, TG_WHEN, NEW; 914 END IF; 915 IF tg_op = 'DELETE' THEN 916 RETURN OLD; 917 ELSE 918 RETURN NEW; 919 END IF; 920END 921$$; 922CREATE TRIGGER gtest1 BEFORE DELETE OR UPDATE ON gtest26 923 FOR EACH ROW 924 WHEN (OLD.b < 0) -- ok 925 EXECUTE PROCEDURE gtest_trigger_func(); 926CREATE TRIGGER gtest2a BEFORE INSERT OR UPDATE ON gtest26 927 FOR EACH ROW 928 WHEN (NEW.b < 0) -- error 929 EXECUTE PROCEDURE gtest_trigger_func(); 930ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated columns 931LINE 3: WHEN (NEW.b < 0) 932 ^ 933DETAIL: Column "b" is a generated column. 934CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26 935 FOR EACH ROW 936 WHEN (NEW.* IS NOT NULL) -- error 937 EXECUTE PROCEDURE gtest_trigger_func(); 938ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated columns 939LINE 3: WHEN (NEW.* IS NOT NULL) 940 ^ 941DETAIL: A whole-row reference is used and the table contains generated columns. 942CREATE TRIGGER gtest2 BEFORE INSERT ON gtest26 943 FOR EACH ROW 944 WHEN (NEW.a < 0) 945 EXECUTE PROCEDURE gtest_trigger_func(); 946CREATE TRIGGER gtest3 AFTER DELETE OR UPDATE ON gtest26 947 FOR EACH ROW 948 WHEN (OLD.b < 0) -- ok 949 EXECUTE PROCEDURE gtest_trigger_func(); 950CREATE TRIGGER gtest4 AFTER INSERT OR UPDATE ON gtest26 951 FOR EACH ROW 952 WHEN (NEW.b < 0) -- ok 953 EXECUTE PROCEDURE gtest_trigger_func(); 954INSERT INTO gtest26 (a) VALUES (-2), (0), (3); 955INFO: gtest2: BEFORE: new = (-2,) 956INFO: gtest4: AFTER: new = (-2,-4) 957SELECT * FROM gtest26 ORDER BY a; 958 a | b 959----+---- 960 -2 | -4 961 0 | 0 962 3 | 6 963(3 rows) 964 965UPDATE gtest26 SET a = a * -2; 966INFO: gtest1: BEFORE: old = (-2,-4) 967INFO: gtest1: BEFORE: new = (4,) 968INFO: gtest3: AFTER: old = (-2,-4) 969INFO: gtest3: AFTER: new = (4,8) 970INFO: gtest4: AFTER: old = (3,6) 971INFO: gtest4: AFTER: new = (-6,-12) 972SELECT * FROM gtest26 ORDER BY a; 973 a | b 974----+----- 975 -6 | -12 976 0 | 0 977 4 | 8 978(3 rows) 979 980DELETE FROM gtest26 WHERE a = -6; 981INFO: gtest1: BEFORE: old = (-6,-12) 982INFO: gtest3: AFTER: old = (-6,-12) 983SELECT * FROM gtest26 ORDER BY a; 984 a | b 985---+--- 986 0 | 0 987 4 | 8 988(2 rows) 989 990DROP TRIGGER gtest1 ON gtest26; 991DROP TRIGGER gtest2 ON gtest26; 992DROP TRIGGER gtest3 ON gtest26; 993-- Check that an UPDATE of "a" fires the trigger for UPDATE OF b, per 994-- SQL standard. 995CREATE FUNCTION gtest_trigger_func3() RETURNS trigger 996 LANGUAGE plpgsql 997AS $$ 998BEGIN 999 RAISE NOTICE 'OK'; 1000 RETURN NEW; 1001END 1002$$; 1003CREATE TRIGGER gtest11 BEFORE UPDATE OF b ON gtest26 1004 FOR EACH ROW 1005 EXECUTE PROCEDURE gtest_trigger_func3(); 1006UPDATE gtest26 SET a = 1 WHERE a = 0; 1007NOTICE: OK 1008DROP TRIGGER gtest11 ON gtest26; 1009TRUNCATE gtest26; 1010-- check that modifications of stored generated columns in triggers do 1011-- not get propagated 1012CREATE FUNCTION gtest_trigger_func4() RETURNS trigger 1013 LANGUAGE plpgsql 1014AS $$ 1015BEGIN 1016 NEW.a = 10; 1017 NEW.b = 300; 1018 RETURN NEW; 1019END; 1020$$; 1021CREATE TRIGGER gtest12_01 BEFORE UPDATE ON gtest26 1022 FOR EACH ROW 1023 EXECUTE PROCEDURE gtest_trigger_func(); 1024CREATE TRIGGER gtest12_02 BEFORE UPDATE ON gtest26 1025 FOR EACH ROW 1026 EXECUTE PROCEDURE gtest_trigger_func4(); 1027CREATE TRIGGER gtest12_03 BEFORE UPDATE ON gtest26 1028 FOR EACH ROW 1029 EXECUTE PROCEDURE gtest_trigger_func(); 1030INSERT INTO gtest26 (a) VALUES (1); 1031UPDATE gtest26 SET a = 11 WHERE a = 1; 1032INFO: gtest12_01: BEFORE: old = (1,2) 1033INFO: gtest12_01: BEFORE: new = (11,) 1034INFO: gtest12_03: BEFORE: old = (1,2) 1035INFO: gtest12_03: BEFORE: new = (10,) 1036SELECT * FROM gtest26 ORDER BY a; 1037 a | b 1038----+---- 1039 10 | 20 1040(1 row) 1041 1042-- LIKE INCLUDING GENERATED and dropped column handling 1043CREATE TABLE gtest28a ( 1044 a int, 1045 b int, 1046 c int, 1047 x int GENERATED ALWAYS AS (b * 2) STORED 1048); 1049ALTER TABLE gtest28a DROP COLUMN a; 1050CREATE TABLE gtest28b (LIKE gtest28a INCLUDING GENERATED); 1051\d gtest28* 1052 Table "public.gtest28a" 1053 Column | Type | Collation | Nullable | Default 1054--------+---------+-----------+----------+------------------------------------ 1055 b | integer | | | 1056 c | integer | | | 1057 x | integer | | | generated always as (b * 2) stored 1058 1059 Table "public.gtest28b" 1060 Column | Type | Collation | Nullable | Default 1061--------+---------+-----------+----------+------------------------------------ 1062 b | integer | | | 1063 c | integer | | | 1064 x | integer | | | generated always as (b * 2) stored 1065 1066