1 -- sanity check of system catalog
2 SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's');
3 attrelid | attname | attgenerated
4 ----------+---------+--------------
7 CREATE SCHEMA generated_stored_tests;
8 GRANT USAGE ON SCHEMA generated_stored_tests TO PUBLIC;
9 SET search_path = generated_stored_tests;
10 CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED);
11 CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
12 SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_schema = 'generated_stored_tests' ORDER BY 1, 2;
13 table_name | column_name | column_default | is_nullable | is_generated | generation_expression
14 ------------+-------------+----------------+-------------+--------------+-----------------------
15 gtest0 | a | | NO | NEVER |
16 gtest0 | b | | YES | ALWAYS | 55
17 gtest1 | a | | NO | NEVER |
18 gtest1 | b | | YES | ALWAYS | (a * 2)
21 SELECT table_name, column_name, dependent_column FROM information_schema.column_column_usage WHERE table_schema = 'generated_stored_tests' ORDER BY 1, 2, 3;
22 table_name | column_name | dependent_column
23 ------------+-------------+------------------
28 Table "generated_stored_tests.gtest1"
29 Column | Type | Collation | Nullable | Default
30 --------+---------+-----------+----------+------------------------------------
31 a | integer | | not null |
32 b | integer | | | generated always as (a * 2) stored
34 "gtest1_pkey" PRIMARY KEY, btree (a)
36 -- duplicate generated
37 CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ALWAYS AS (a * 3) STORED);
38 ERROR: multiple generation clauses specified for column "b" of table "gtest_err_1"
39 LINE 1: ...ARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ...
41 -- references to other generated columns, including self-references
42 CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED);
43 ERROR: cannot use generated column "b" in column generation expression
44 LINE 1: ...2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STO...
46 DETAIL: A generated column cannot reference another generated column.
47 CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED);
48 ERROR: cannot use generated column "b" in column generation expression
49 LINE 1: ...AYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STO...
51 DETAIL: A generated column cannot reference another generated column.
52 -- a whole-row var is a self-reference on steroids, so disallow that too
53 CREATE TABLE gtest_err_2c (a int PRIMARY KEY,
54 b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c)) STORED);
55 ERROR: cannot use whole-row variable in column generation expression
56 LINE 2: b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c)) STOR...
58 DETAIL: This would cause the generated column to depend on its own value.
60 CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED);
61 ERROR: column "c" does not exist
62 LINE 1: ..._3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STO...
64 -- generation expression must be immutable
65 CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) STORED);
66 ERROR: generation expression is not immutable
67 -- ... but be sure that the immutability test is accurate
68 CREATE TABLE gtest2 (a int, b text GENERATED ALWAYS AS (a || ' sec') STORED);
70 -- cannot have default/identity and generated
71 CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED);
72 ERROR: both default and generation expression specified for column "b" of table "gtest_err_5a"
73 LINE 1: ... gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ...
75 CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED);
76 ERROR: both identity and generation expression specified for column "b" of table "gtest_err_5b"
77 LINE 1: ...t PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ...
79 -- reference to system column not allowed in generated column
80 -- (except tableoid, which we test below)
81 CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED);
82 ERROR: cannot use system column "xmin" in column generation expression
83 LINE 1: ...a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37...
85 -- various prohibited constructs
86 CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED);
87 ERROR: aggregate functions are not allowed in column generation expressions
88 LINE 1: ...7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) ST...
90 CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER BY a)) STORED);
91 ERROR: window functions are not allowed in column generation expressions
92 LINE 1: ...7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number...
94 CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED);
95 ERROR: cannot use subquery in column generation expression
96 LINE 1: ...7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)...
98 CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED);
99 ERROR: set-returning functions are not allowed in column generation expressions
100 LINE 1: ...7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_s...
102 -- GENERATED BY DEFAULT not allowed
103 CREATE TABLE gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT AS (a * 2) STORED);
104 ERROR: for a generated column, GENERATED ALWAYS must be specified
105 LINE 1: ...E gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT...
107 INSERT INTO gtest1 VALUES (1);
108 INSERT INTO gtest1 VALUES (2, DEFAULT); -- ok
109 INSERT INTO gtest1 VALUES (3, 33); -- error
110 ERROR: cannot insert a non-DEFAULT value into column "b"
111 DETAIL: Column "b" is a generated column.
112 INSERT INTO gtest1 VALUES (3, 33), (4, 44); -- error
113 ERROR: cannot insert a non-DEFAULT value into column "b"
114 DETAIL: Column "b" is a generated column.
115 INSERT INTO gtest1 VALUES (3, DEFAULT), (4, 44); -- error
116 ERROR: cannot insert a non-DEFAULT value into column "b"
117 DETAIL: Column "b" is a generated column.
118 INSERT INTO gtest1 VALUES (3, 33), (4, DEFAULT); -- error
119 ERROR: cannot insert a non-DEFAULT value into column "b"
120 DETAIL: Column "b" is a generated column.
121 INSERT INTO gtest1 VALUES (3, DEFAULT), (4, DEFAULT); -- ok
122 SELECT * FROM gtest1 ORDER BY a;
131 DELETE FROM gtest1 WHERE a >= 3;
132 UPDATE gtest1 SET b = DEFAULT WHERE a = 1;
133 UPDATE gtest1 SET b = 11 WHERE a = 1; -- error
134 ERROR: column "b" can only be updated to DEFAULT
135 DETAIL: Column "b" is a generated column.
136 SELECT * FROM gtest1 ORDER BY a;
143 SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a;
150 SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a;
156 -- test that overflow error happens on write
157 INSERT INTO gtest1 VALUES (2000000000);
158 ERROR: integer out of range
159 SELECT * FROM gtest1;
166 DELETE FROM gtest1 WHERE a = 2000000000;
168 CREATE TABLE gtestx (x int, y int);
169 INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3);
170 SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a;
178 -- test UPDATE/DELETE quals
179 SELECT * FROM gtest1 ORDER BY a;
186 UPDATE gtest1 SET a = 3 WHERE b = 4;
187 SELECT * FROM gtest1 ORDER BY a;
194 DELETE FROM gtest1 WHERE b = 2;
195 SELECT * FROM gtest1 ORDER BY a;
202 CREATE TABLE gtestm (
206 f3 int GENERATED ALWAYS AS (f1 * 2) STORED,
207 f4 int GENERATED ALWAYS AS (f2 * 2) STORED
209 INSERT INTO gtestm VALUES (1, 5, 100);
210 MERGE INTO gtestm t USING (VALUES (1, 10), (2, 20)) v(id, f1) ON t.id = v.id
211 WHEN MATCHED THEN UPDATE SET f1 = v.f1
212 WHEN NOT MATCHED THEN INSERT VALUES (v.id, v.f1, 200);
213 SELECT * FROM gtestm ORDER BY id;
214 id | f1 | f2 | f3 | f4
215 ----+----+-----+----+-----
216 1 | 10 | 100 | 20 | 200
217 2 | 20 | 200 | 40 | 400
222 CREATE VIEW gtest1v AS SELECT * FROM gtest1;
223 SELECT * FROM gtest1v;
229 INSERT INTO gtest1v VALUES (4, 8); -- error
230 ERROR: cannot insert a non-DEFAULT value into column "b"
231 DETAIL: Column "b" is a generated column.
232 INSERT INTO gtest1v VALUES (5, DEFAULT); -- ok
233 INSERT INTO gtest1v VALUES (6, 66), (7, 77); -- error
234 ERROR: cannot insert a non-DEFAULT value into column "b"
235 DETAIL: Column "b" is a generated column.
236 INSERT INTO gtest1v VALUES (6, DEFAULT), (7, 77); -- error
237 ERROR: cannot insert a non-DEFAULT value into column "b"
238 DETAIL: Column "b" is a generated column.
239 INSERT INTO gtest1v VALUES (6, 66), (7, DEFAULT); -- error
240 ERROR: cannot insert a non-DEFAULT value into column "b"
241 DETAIL: Column "b" is a generated column.
242 INSERT INTO gtest1v VALUES (6, DEFAULT), (7, DEFAULT); -- ok
243 ALTER VIEW gtest1v ALTER COLUMN b SET DEFAULT 100;
244 INSERT INTO gtest1v VALUES (8, DEFAULT); -- error
245 ERROR: cannot insert a non-DEFAULT value into column "b"
246 DETAIL: Column "b" is a generated column.
247 INSERT INTO gtest1v VALUES (8, DEFAULT), (9, DEFAULT); -- error
248 ERROR: cannot insert a non-DEFAULT value into column "b"
249 DETAIL: Column "b" is a generated column.
250 SELECT * FROM gtest1v;
259 DELETE FROM gtest1v WHERE a >= 5;
262 WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo;
269 CREATE TABLE gtest1_1 () INHERITS (gtest1);
270 SELECT * FROM gtest1_1;
276 Table "generated_stored_tests.gtest1_1"
277 Column | Type | Collation | Nullable | Default
278 --------+---------+-----------+----------+------------------------------------
279 a | integer | | not null |
280 b | integer | | | generated always as (a * 2) stored
283 INSERT INTO gtest1_1 VALUES (4);
284 SELECT * FROM gtest1_1;
290 SELECT * FROM gtest1;
297 -- can't have generated column that is a child of normal column
298 CREATE TABLE gtest_normal (a int, b int);
299 CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED) INHERITS (gtest_normal); -- error
300 NOTICE: merging column "a" with inherited definition
301 NOTICE: merging column "b" with inherited definition
302 ERROR: child column "b" specifies generation expression
303 HINT: A child table column cannot be generated unless its parent column is.
304 CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED);
305 ALTER TABLE gtest_normal_child INHERIT gtest_normal; -- error
306 ERROR: column "b" in child table must not be a generated column
307 DROP TABLE gtest_normal, gtest_normal_child;
308 -- test inheritance mismatches between parent and child
309 CREATE TABLE gtestx (x int, b int DEFAULT 10) INHERITS (gtest1); -- error
310 NOTICE: merging column "b" with inherited definition
311 ERROR: column "b" inherits from generated column but specifies default
312 CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS IDENTITY) INHERITS (gtest1); -- error
313 NOTICE: merging column "b" with inherited definition
314 ERROR: column "b" inherits from generated column but specifies identity
315 CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS (a * 22) STORED) INHERITS (gtest1); -- ok, overrides parent
316 NOTICE: merging column "b" with inherited definition
318 Table "generated_stored_tests.gtestx"
319 Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
320 --------+---------+-----------+----------+-------------------------------------+---------+--------------+-------------
321 a | integer | | not null | | plain | |
322 b | integer | | | generated always as (a * 22) stored | plain | |
323 x | integer | | | | plain | |
324 Not-null constraints:
325 "gtest1_a_not_null" NOT NULL "a" (inherited)
328 CREATE TABLE gtestxx_1 (a int NOT NULL, b int);
329 ALTER TABLE gtestxx_1 INHERIT gtest1; -- error
330 ERROR: column "b" in child table must be a generated column
331 CREATE TABLE gtestxx_3 (a int NOT NULL, b int GENERATED ALWAYS AS (a * 2) STORED);
332 ALTER TABLE gtestxx_3 INHERIT gtest1; -- ok
333 CREATE TABLE gtestxx_4 (b int GENERATED ALWAYS AS (a * 2) STORED, a int NOT NULL);
334 ALTER TABLE gtestxx_4 INHERIT gtest1; -- ok
335 -- test multiple inheritance mismatches
336 CREATE TABLE gtesty (x int, b int DEFAULT 55);
337 CREATE TABLE gtest1_y () INHERITS (gtest0, gtesty); -- error
338 NOTICE: merging multiple inherited definitions of column "b"
339 ERROR: inherited column "b" has a generation conflict
341 CREATE TABLE gtesty (x int, b int);
342 CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty); -- error
343 NOTICE: merging multiple inherited definitions of column "b"
344 ERROR: inherited column "b" has a generation conflict
346 CREATE TABLE gtesty (x int, b int GENERATED ALWAYS AS (x * 22) STORED);
347 CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty); -- error
348 NOTICE: merging multiple inherited definitions of column "b"
349 ERROR: column "b" inherits conflicting generation expressions
350 HINT: To resolve the conflict, specify a generation expression explicitly.
351 CREATE TABLE gtest1_y (b int GENERATED ALWAYS AS (x + 1) STORED) INHERITS (gtest1, gtesty); -- ok
352 NOTICE: merging multiple inherited definitions of column "b"
353 NOTICE: moving and merging column "b" with inherited definition
354 DETAIL: User-specified column moved to the position of the inherited column.
356 Table "generated_stored_tests.gtest1_y"
357 Column | Type | Collation | Nullable | Default
358 --------+---------+-----------+----------+------------------------------------
359 a | integer | | not null |
360 b | integer | | | generated always as (x + 1) stored
365 -- test correct handling of GENERATED column that's only in child
366 CREATE TABLE gtestp (f1 int);
367 CREATE TABLE gtestc (f2 int GENERATED ALWAYS AS (f1+1) STORED) INHERITS(gtestp);
368 INSERT INTO gtestc values(42);
375 UPDATE gtestp SET f1 = f1 * 10;
382 DROP TABLE gtestp CASCADE;
383 NOTICE: drop cascades to table gtestc
384 -- test stored update
385 CREATE TABLE gtest3 (a int, b int GENERATED ALWAYS AS (a * 3) STORED);
386 INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL);
387 SELECT * FROM gtest3 ORDER BY a;
396 UPDATE gtest3 SET a = 22 WHERE a = 2;
397 SELECT * FROM gtest3 ORDER BY a;
406 CREATE TABLE gtest3a (a text, b text GENERATED ALWAYS AS (a || '+' || a) STORED);
407 INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL);
408 SELECT * FROM gtest3a ORDER BY a;
417 UPDATE gtest3a SET a = 'bb' WHERE a = 'b';
418 SELECT * FROM gtest3a ORDER BY a;
429 INSERT INTO gtest1 (a) VALUES (1), (2);
430 COPY gtest1 TO stdout;
433 COPY gtest1 (a, b) TO stdout;
434 ERROR: column "b" is a generated column
435 DETAIL: Generated columns cannot be used in COPY.
436 COPY gtest1 FROM stdin;
437 COPY gtest1 (a, b) FROM stdin;
438 ERROR: column "b" is a generated column
439 DETAIL: Generated columns cannot be used in COPY.
440 SELECT * FROM gtest1 ORDER BY a;
450 INSERT INTO gtest3 (a) VALUES (1), (2);
451 COPY gtest3 TO stdout;
454 COPY gtest3 (a, b) TO stdout;
455 ERROR: column "b" is a generated column
456 DETAIL: Generated columns cannot be used in COPY.
457 COPY gtest3 FROM stdin;
458 COPY gtest3 (a, b) FROM stdin;
459 ERROR: column "b" is a generated column
460 DETAIL: Generated columns cannot be used in COPY.
461 SELECT * FROM gtest3 ORDER BY a;
471 CREATE TABLE gtest2 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (NULL) STORED);
472 INSERT INTO gtest2 VALUES (1);
473 SELECT * FROM gtest2;
479 -- simple column reference for varlena types
480 CREATE TABLE gtest_varlena (a varchar, b varchar GENERATED ALWAYS AS (a) STORED);
481 INSERT INTO gtest_varlena (a) VALUES('01234567890123456789');
482 INSERT INTO gtest_varlena (a) VALUES(NULL);
483 SELECT * FROM gtest_varlena ORDER BY a;
485 ----------------------+----------------------
486 01234567890123456789 | 01234567890123456789
490 DROP TABLE gtest_varlena;
492 CREATE TYPE double_int as (a int, b int);
493 CREATE TABLE gtest4 (
495 b double_int GENERATED ALWAYS AS ((a * 2, a * 3)) STORED
497 INSERT INTO gtest4 VALUES (1), (6);
498 SELECT * FROM gtest4;
506 DROP TYPE double_int;
507 -- using tableoid is allowed
508 CREATE TABLE gtest_tableoid (
510 b bool GENERATED ALWAYS AS (tableoid = 'gtest_tableoid'::regclass) STORED
512 INSERT INTO gtest_tableoid VALUES (1), (2);
513 ALTER TABLE gtest_tableoid ADD COLUMN
514 c regclass GENERATED ALWAYS AS (tableoid) STORED;
515 SELECT * FROM gtest_tableoid;
517 ---+---+----------------
518 1 | t | gtest_tableoid
519 2 | t | gtest_tableoid
522 -- drop column behavior
523 CREATE TABLE gtest10 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED);
524 ALTER TABLE gtest10 DROP COLUMN b; -- fails
525 ERROR: cannot drop column b of table gtest10 because other objects depend on it
526 DETAIL: column c of table gtest10 depends on column b of table gtest10
527 HINT: Use DROP ... CASCADE to drop the dependent objects too.
528 ALTER TABLE gtest10 DROP COLUMN b CASCADE; -- drops c too
529 NOTICE: drop cascades to column c of table gtest10
531 Table "generated_stored_tests.gtest10"
532 Column | Type | Collation | Nullable | Default
533 --------+---------+-----------+----------+---------
534 a | integer | | not null |
536 "gtest10_pkey" PRIMARY KEY, btree (a)
538 CREATE TABLE gtest10a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
539 ALTER TABLE gtest10a DROP COLUMN b;
540 INSERT INTO gtest10a (a) VALUES (1);
542 CREATE USER regress_user11;
543 CREATE TABLE gtest11s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED);
544 INSERT INTO gtest11s VALUES (1, 10), (2, 20);
545 GRANT SELECT (a, c) ON gtest11s TO regress_user11;
546 CREATE FUNCTION gf1(a int) RETURNS int AS $$ SELECT a * 3 $$ IMMUTABLE LANGUAGE SQL;
547 REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC;
548 CREATE TABLE gtest12s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (gf1(b)) STORED);
549 INSERT INTO gtest12s VALUES (1, 10), (2, 20);
550 GRANT SELECT (a, c) ON gtest12s TO regress_user11;
551 SET ROLE regress_user11;
552 SELECT a, b FROM gtest11s; -- not allowed
553 ERROR: permission denied for table gtest11s
554 SELECT a, c FROM gtest11s; -- allowed
561 SELECT gf1(10); -- not allowed
562 ERROR: permission denied for function gf1
563 SELECT a, c FROM gtest12s; -- allowed
571 DROP FUNCTION gf1(int); -- fail
572 ERROR: cannot drop function gf1(integer) because other objects depend on it
573 DETAIL: column c of table gtest12s depends on function gf1(integer)
574 HINT: Use DROP ... CASCADE to drop the dependent objects too.
575 DROP TABLE gtest11s, gtest12s;
576 DROP FUNCTION gf1(int);
577 DROP USER regress_user11;
579 CREATE TABLE gtest20 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED CHECK (b < 50));
580 INSERT INTO gtest20 (a) VALUES (10); -- ok
581 INSERT INTO gtest20 (a) VALUES (30); -- violates constraint
582 ERROR: new row for relation "gtest20" violates check constraint "gtest20_b_check"
583 DETAIL: Failing row contains (30, 60).
584 ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); -- violates constraint
585 ERROR: check constraint "gtest20_b_check" of relation "gtest20" is violated by some row
586 ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); -- ok
587 CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
588 INSERT INTO gtest20a (a) VALUES (10);
589 INSERT INTO gtest20a (a) VALUES (30);
590 ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
591 ERROR: check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
592 CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
593 INSERT INTO gtest20b (a) VALUES (10);
594 INSERT INTO gtest20b (a) VALUES (30);
595 ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID;
596 ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; -- fails on existing row
597 ERROR: check constraint "chk" of relation "gtest20b" is violated by some row
598 -- not-null constraints
599 CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL);
600 INSERT INTO gtest21a (a) VALUES (1); -- ok
601 INSERT INTO gtest21a (a) VALUES (0); -- violates constraint
602 ERROR: null value in column "b" of relation "gtest21a" violates not-null constraint
603 DETAIL: Failing row contains (0, null).
604 CREATE TABLE gtest21b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED);
605 ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL;
606 INSERT INTO gtest21b (a) VALUES (1); -- ok
607 INSERT INTO gtest21b (a) VALUES (0); -- violates constraint
608 ERROR: null value in column "b" of relation "gtest21b" violates not-null constraint
609 DETAIL: Failing row contains (0, null).
610 ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL;
611 INSERT INTO gtest21b (a) VALUES (0); -- ok now
613 CREATE TABLE gtest22a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a / 2) STORED UNIQUE);
614 INSERT INTO gtest22a VALUES (2);
615 INSERT INTO gtest22a VALUES (3);
616 ERROR: duplicate key value violates unique constraint "gtest22a_b_key"
617 DETAIL: Key (b)=(1) already exists.
618 INSERT INTO gtest22a VALUES (4);
619 CREATE TABLE gtest22b (a int, b int GENERATED ALWAYS AS (a / 2) STORED, PRIMARY KEY (a, b));
620 INSERT INTO gtest22b VALUES (2);
621 INSERT INTO gtest22b VALUES (2);
622 ERROR: duplicate key value violates unique constraint "gtest22b_pkey"
623 DETAIL: Key (a, b)=(2, 1) already exists.
625 CREATE TABLE gtest22c (a int, b int GENERATED ALWAYS AS (a * 2) STORED);
626 CREATE INDEX gtest22c_b_idx ON gtest22c (b);
627 CREATE INDEX gtest22c_expr_idx ON gtest22c ((b * 3));
628 CREATE INDEX gtest22c_pred_idx ON gtest22c (a) WHERE b > 0;
630 Table "generated_stored_tests.gtest22c"
631 Column | Type | Collation | Nullable | Default
632 --------+---------+-----------+----------+------------------------------------
634 b | integer | | | generated always as (a * 2) stored
636 "gtest22c_b_idx" btree (b)
637 "gtest22c_expr_idx" btree ((b * 3))
638 "gtest22c_pred_idx" btree (a) WHERE b > 0
640 INSERT INTO gtest22c VALUES (1), (2), (3);
641 SET enable_seqscan TO off;
642 SET enable_bitmapscan TO off;
643 EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b = 4;
645 ---------------------------------------------
646 Index Scan using gtest22c_b_idx on gtest22c
650 SELECT * FROM gtest22c WHERE b = 4;
656 EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b * 3 = 6;
658 ------------------------------------------------
659 Index Scan using gtest22c_expr_idx on gtest22c
660 Index Cond: ((b * 3) = 6)
663 SELECT * FROM gtest22c WHERE b * 3 = 6;
669 EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE a = 1 AND b > 0;
671 ------------------------------------------------
672 Index Scan using gtest22c_pred_idx on gtest22c
676 SELECT * FROM gtest22c WHERE a = 1 AND b > 0;
682 ALTER TABLE gtest22c ALTER COLUMN b SET EXPRESSION AS (a * 4);
684 EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b = 8;
686 ---------------------------------------------
687 Index Scan using gtest22c_b_idx on gtest22c
691 SELECT * FROM gtest22c WHERE b = 8;
697 EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b * 3 = 12;
699 ------------------------------------------------
700 Index Scan using gtest22c_expr_idx on gtest22c
701 Index Cond: ((b * 3) = 12)
704 SELECT * FROM gtest22c WHERE b * 3 = 12;
710 EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE a = 1 AND b > 0;
712 ------------------------------------------------
713 Index Scan using gtest22c_pred_idx on gtest22c
717 SELECT * FROM gtest22c WHERE a = 1 AND b > 0;
723 RESET enable_seqscan;
724 RESET enable_bitmapscan;
726 CREATE TABLE gtest23a (x int PRIMARY KEY, y int);
727 INSERT INTO gtest23a VALUES (1, 11), (2, 22), (3, 33);
728 CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON UPDATE CASCADE); -- error
729 ERROR: invalid ON UPDATE action for foreign key constraint containing generated column
730 CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON DELETE SET NULL); -- error
731 ERROR: invalid ON DELETE action for foreign key constraint containing generated column
732 CREATE TABLE gtest23b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x));
734 Table "generated_stored_tests.gtest23b"
735 Column | Type | Collation | Nullable | Default
736 --------+---------+-----------+----------+------------------------------------
737 a | integer | | not null |
738 b | integer | | | generated always as (a * 2) stored
740 "gtest23b_pkey" PRIMARY KEY, btree (a)
741 Foreign-key constraints:
742 "gtest23b_b_fkey" FOREIGN KEY (b) REFERENCES gtest23a(x)
744 INSERT INTO gtest23b VALUES (1); -- ok
745 INSERT INTO gtest23b VALUES (5); -- error
746 ERROR: insert or update on table "gtest23b" violates foreign key constraint "gtest23b_b_fkey"
747 DETAIL: Key (b)=(10) is not present in table "gtest23a".
748 ALTER TABLE gtest23b ALTER COLUMN b SET EXPRESSION AS (a * 5); -- error
749 ERROR: insert or update on table "gtest23b" violates foreign key constraint "gtest23b_b_fkey"
750 DETAIL: Key (b)=(5) is not present in table "gtest23a".
751 ALTER TABLE gtest23b ALTER COLUMN b SET EXPRESSION AS (a * 1); -- ok
754 CREATE TABLE gtest23p (x int, y int GENERATED ALWAYS AS (x * 2) STORED, PRIMARY KEY (y));
755 INSERT INTO gtest23p VALUES (1), (2), (3);
756 CREATE TABLE gtest23q (a int PRIMARY KEY, b int REFERENCES gtest23p (y));
757 INSERT INTO gtest23q VALUES (1, 2); -- ok
758 INSERT INTO gtest23q VALUES (2, 5); -- error
759 ERROR: insert or update on table "gtest23q" violates foreign key constraint "gtest23q_b_fkey"
760 DETAIL: Key (b)=(5) is not present in table "gtest23p".
762 CREATE DOMAIN gtestdomain1 AS int CHECK (VALUE < 10);
763 CREATE TABLE gtest24 (a int PRIMARY KEY, b gtestdomain1 GENERATED ALWAYS AS (a * 2) STORED);
764 INSERT INTO gtest24 (a) VALUES (4); -- ok
765 INSERT INTO gtest24 (a) VALUES (6); -- error
766 ERROR: value for domain gtestdomain1 violates check constraint "gtestdomain1_check"
767 -- typed tables (currently not supported)
768 CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint);
769 CREATE TABLE gtest28 OF gtest_type (f1 WITH OPTIONS GENERATED ALWAYS AS (f2 *2) STORED);
770 ERROR: generated columns are not supported on typed tables
771 DROP TYPE gtest_type CASCADE;
772 -- partitioning cases
773 CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint) PARTITION BY RANGE (f1);
774 CREATE TABLE gtest_child PARTITION OF gtest_parent (
775 f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 2) STORED
776 ) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error
777 ERROR: child column "f3" specifies generation expression
778 HINT: A child table column cannot be generated unless its parent column is.
779 CREATE TABLE gtest_child (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED);
780 ALTER TABLE gtest_parent ATTACH PARTITION gtest_child FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error
781 ERROR: column "f3" in child table must not be a generated column
782 DROP TABLE gtest_parent, gtest_child;
783 CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f1);
784 CREATE TABLE gtest_child PARTITION OF gtest_parent
785 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- inherits gen expr
786 CREATE TABLE gtest_child2 PARTITION OF gtest_parent (
787 f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 22) STORED -- overrides gen expr
788 ) FOR VALUES FROM ('2016-08-01') TO ('2016-09-01');
789 CREATE TABLE gtest_child3 PARTITION OF gtest_parent (
790 f3 DEFAULT 42 -- error
791 ) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01');
792 ERROR: column "f3" inherits from generated column but specifies default
793 CREATE TABLE gtest_child3 PARTITION OF gtest_parent (
794 f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY -- error
795 ) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01');
796 ERROR: identity columns are not supported on partitions
797 CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint);
798 ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error
799 ERROR: column "f3" in child table must be a generated column
800 DROP TABLE gtest_child3;
801 CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint DEFAULT 42);
802 ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error
803 ERROR: column "f3" in child table must be a generated column
804 DROP TABLE gtest_child3;
805 CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS IDENTITY);
806 ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error
807 ERROR: table "gtest_child3" being attached contains an identity column "f3"
808 DETAIL: The new partition may not contain an identity column.
809 DROP TABLE gtest_child3;
810 CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 33) STORED);
811 ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01');
813 Table "generated_stored_tests.gtest_child"
814 Column | Type | Collation | Nullable | Default
815 --------+--------+-----------+----------+-------------------------------------
816 f1 | date | | not null |
818 f3 | bigint | | | generated always as (f2 * 2) stored
819 Partition of: gtest_parent FOR VALUES FROM ('07-01-2016') TO ('08-01-2016')
822 Table "generated_stored_tests.gtest_child2"
823 Column | Type | Collation | Nullable | Default
824 --------+--------+-----------+----------+--------------------------------------
825 f1 | date | | not null |
827 f3 | bigint | | | generated always as (f2 * 22) stored
828 Partition of: gtest_parent FOR VALUES FROM ('08-01-2016') TO ('09-01-2016')
831 Table "generated_stored_tests.gtest_child3"
832 Column | Type | Collation | Nullable | Default
833 --------+--------+-----------+----------+--------------------------------------
834 f1 | date | | not null |
836 f3 | bigint | | | generated always as (f2 * 33) stored
837 Partition of: gtest_parent FOR VALUES FROM ('09-01-2016') TO ('10-01-2016')
839 INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 1);
840 INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 2);
841 INSERT INTO gtest_parent (f1, f2) VALUES ('2016-08-15', 3);
842 SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3;
843 tableoid | f1 | f2 | f3
844 --------------+------------+----+----
845 gtest_child | 07-15-2016 | 1 | 2
846 gtest_child | 07-15-2016 | 2 | 4
847 gtest_child2 | 08-15-2016 | 3 | 66
850 UPDATE gtest_parent SET f1 = f1 + 60 WHERE f2 = 1;
851 SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3;
852 tableoid | f1 | f2 | f3
853 --------------+------------+----+----
854 gtest_child | 07-15-2016 | 2 | 4
855 gtest_child2 | 08-15-2016 | 3 | 66
856 gtest_child3 | 09-13-2016 | 1 | 33
859 -- alter only parent's and one child's generation expression
860 ALTER TABLE ONLY gtest_parent ALTER COLUMN f3 SET EXPRESSION AS (f2 * 4);
861 ALTER TABLE gtest_child ALTER COLUMN f3 SET EXPRESSION AS (f2 * 10);
863 Partitioned table "generated_stored_tests.gtest_parent"
864 Column | Type | Collation | Nullable | Default
865 --------+--------+-----------+----------+-------------------------------------
866 f1 | date | | not null |
868 f3 | bigint | | | generated always as (f2 * 4) stored
869 Partition key: RANGE (f1)
870 Number of partitions: 3 (Use \d+ to list them.)
873 Table "generated_stored_tests.gtest_child"
874 Column | Type | Collation | Nullable | Default
875 --------+--------+-----------+----------+--------------------------------------
876 f1 | date | | not null |
878 f3 | bigint | | | generated always as (f2 * 10) stored
879 Partition of: gtest_parent FOR VALUES FROM ('07-01-2016') TO ('08-01-2016')
882 Table "generated_stored_tests.gtest_child2"
883 Column | Type | Collation | Nullable | Default
884 --------+--------+-----------+----------+--------------------------------------
885 f1 | date | | not null |
887 f3 | bigint | | | generated always as (f2 * 22) stored
888 Partition of: gtest_parent FOR VALUES FROM ('08-01-2016') TO ('09-01-2016')
891 Table "generated_stored_tests.gtest_child3"
892 Column | Type | Collation | Nullable | Default
893 --------+--------+-----------+----------+--------------------------------------
894 f1 | date | | not null |
896 f3 | bigint | | | generated always as (f2 * 33) stored
897 Partition of: gtest_parent FOR VALUES FROM ('09-01-2016') TO ('10-01-2016')
899 SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3;
900 tableoid | f1 | f2 | f3
901 --------------+------------+----+----
902 gtest_child | 07-15-2016 | 2 | 20
903 gtest_child2 | 08-15-2016 | 3 | 66
904 gtest_child3 | 09-13-2016 | 1 | 33
907 -- alter generation expression of parent and all its children altogether
908 ALTER TABLE gtest_parent ALTER COLUMN f3 SET EXPRESSION AS (f2 * 2);
910 Partitioned table "generated_stored_tests.gtest_parent"
911 Column | Type | Collation | Nullable | Default
912 --------+--------+-----------+----------+-------------------------------------
913 f1 | date | | not null |
915 f3 | bigint | | | generated always as (f2 * 2) stored
916 Partition key: RANGE (f1)
917 Number of partitions: 3 (Use \d+ to list them.)
920 Table "generated_stored_tests.gtest_child"
921 Column | Type | Collation | Nullable | Default
922 --------+--------+-----------+----------+-------------------------------------
923 f1 | date | | not null |
925 f3 | bigint | | | generated always as (f2 * 2) stored
926 Partition of: gtest_parent FOR VALUES FROM ('07-01-2016') TO ('08-01-2016')
929 Table "generated_stored_tests.gtest_child2"
930 Column | Type | Collation | Nullable | Default
931 --------+--------+-----------+----------+-------------------------------------
932 f1 | date | | not null |
934 f3 | bigint | | | generated always as (f2 * 2) stored
935 Partition of: gtest_parent FOR VALUES FROM ('08-01-2016') TO ('09-01-2016')
938 Table "generated_stored_tests.gtest_child3"
939 Column | Type | Collation | Nullable | Default
940 --------+--------+-----------+----------+-------------------------------------
941 f1 | date | | not null |
943 f3 | bigint | | | generated always as (f2 * 2) stored
944 Partition of: gtest_parent FOR VALUES FROM ('09-01-2016') TO ('10-01-2016')
946 SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3;
947 tableoid | f1 | f2 | f3
948 --------------+------------+----+----
949 gtest_child | 07-15-2016 | 2 | 4
950 gtest_child2 | 08-15-2016 | 3 | 6
951 gtest_child3 | 09-13-2016 | 1 | 2
954 -- we leave these tables around for purposes of testing dump/reload/upgrade
955 -- generated columns in partition key (not allowed)
956 CREATE TABLE gtest_part_key (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3);
957 ERROR: cannot use generated column in partition key
958 LINE 1: ...ENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3);
960 DETAIL: Column "f3" is a generated column.
961 CREATE TABLE gtest_part_key (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE ((f3 * 3));
962 ERROR: cannot use generated column in partition key
963 LINE 1: ...ED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE ((f3 * 3));
965 DETAIL: Column "f3" is a generated column.
966 -- ALTER TABLE ... ADD COLUMN
967 CREATE TABLE gtest25 (a int PRIMARY KEY);
968 INSERT INTO gtest25 VALUES (3), (4);
969 ALTER TABLE gtest25 ADD COLUMN b int GENERATED ALWAYS AS (a * 2) STORED, ALTER COLUMN b SET EXPRESSION AS (a * 3);
970 SELECT * FROM gtest25 ORDER BY a;
977 ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (b * 4) STORED; -- error
978 ERROR: cannot use generated column "b" in column generation expression
979 DETAIL: A generated column cannot reference another generated column.
980 ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (z * 4) STORED; -- error
981 ERROR: column "z" does not exist
982 ALTER TABLE gtest25 ADD COLUMN c int DEFAULT 42,
983 ADD COLUMN x int GENERATED ALWAYS AS (c * 4) STORED;
984 ALTER TABLE gtest25 ADD COLUMN d int DEFAULT 101;
985 ALTER TABLE gtest25 ALTER COLUMN d SET DATA TYPE float8,
986 ADD COLUMN y float8 GENERATED ALWAYS AS (d * 4) STORED;
987 SELECT * FROM gtest25 ORDER BY a;
988 a | b | c | x | d | y
989 ---+----+----+-----+-----+-----
990 3 | 9 | 42 | 168 | 101 | 404
991 4 | 12 | 42 | 168 | 101 | 404
995 Table "generated_stored_tests.gtest25"
996 Column | Type | Collation | Nullable | Default
997 --------+------------------+-----------+----------+------------------------------------------------------
998 a | integer | | not null |
999 b | integer | | | generated always as (a * 3) stored
1000 c | integer | | | 42
1001 x | integer | | | generated always as (c * 4) stored
1002 d | double precision | | | 101
1003 y | double precision | | | generated always as (d * 4::double precision) stored
1005 "gtest25_pkey" PRIMARY KEY, btree (a)
1007 -- ALTER TABLE ... ALTER COLUMN
1008 CREATE TABLE gtest27 (
1011 x int GENERATED ALWAYS AS ((a + b) * 2) STORED
1013 INSERT INTO gtest27 (a, b) VALUES (3, 7), (4, 11);
1014 ALTER TABLE gtest27 ALTER COLUMN a TYPE text; -- error
1015 ERROR: cannot alter type of a column used by a generated column
1016 DETAIL: Column "a" is used by generated column "x".
1017 ALTER TABLE gtest27 ALTER COLUMN x TYPE numeric;
1019 Table "generated_stored_tests.gtest27"
1020 Column | Type | Collation | Nullable | Default
1021 --------+---------+-----------+----------+--------------------------------------------
1024 x | numeric | | | generated always as (((a + b) * 2)) stored
1026 SELECT * FROM gtest27;
1033 ALTER TABLE gtest27 ALTER COLUMN x TYPE boolean USING x <> 0; -- error
1034 ERROR: cannot specify USING when altering type of generated column
1035 DETAIL: Column "x" is a generated column.
1036 ALTER TABLE gtest27 ALTER COLUMN x DROP DEFAULT; -- error
1037 ERROR: column "x" of relation "gtest27" is a generated column
1038 HINT: Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead.
1039 -- It's possible to alter the column types this way:
1042 ALTER COLUMN a TYPE bigint,
1043 ALTER COLUMN b TYPE bigint,
1044 ADD COLUMN x bigint GENERATED ALWAYS AS ((a + b) * 2) STORED;
1046 Table "generated_stored_tests.gtest27"
1047 Column | Type | Collation | Nullable | Default
1048 --------+--------+-----------+----------+------------------------------------------
1051 x | bigint | | | generated always as ((a + b) * 2) stored
1053 -- Ideally you could just do this, but not today (and should x change type?):
1055 ALTER COLUMN a TYPE float8,
1056 ALTER COLUMN b TYPE float8; -- error
1057 ERROR: cannot alter type of a column used by a generated column
1058 DETAIL: Column "a" is used by generated column "x".
1060 Table "generated_stored_tests.gtest27"
1061 Column | Type | Collation | Nullable | Default
1062 --------+--------+-----------+----------+------------------------------------------
1065 x | bigint | | | generated always as ((a + b) * 2) stored
1067 SELECT * FROM gtest27;
1074 -- ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION
1075 CREATE TABLE gtest29 (
1077 b int GENERATED ALWAYS AS (a * 2) STORED
1079 INSERT INTO gtest29 (a) VALUES (3), (4);
1080 SELECT * FROM gtest29;
1088 Table "generated_stored_tests.gtest29"
1089 Column | Type | Collation | Nullable | Default
1090 --------+---------+-----------+----------+------------------------------------
1092 b | integer | | | generated always as (a * 2) stored
1094 ALTER TABLE gtest29 ALTER COLUMN a SET EXPRESSION AS (a * 3); -- error
1095 ERROR: column "a" of relation "gtest29" is not a generated column
1096 ALTER TABLE gtest29 ALTER COLUMN a DROP EXPRESSION; -- error
1097 ERROR: column "a" of relation "gtest29" is not a stored generated column
1098 ALTER TABLE gtest29 ALTER COLUMN a DROP EXPRESSION IF EXISTS; -- notice
1099 NOTICE: column "a" of relation "gtest29" is not a stored generated column, skipping
1100 -- Change the expression
1101 ALTER TABLE gtest29 ALTER COLUMN b SET EXPRESSION AS (a * 3);
1102 SELECT * FROM gtest29;
1110 Table "generated_stored_tests.gtest29"
1111 Column | Type | Collation | Nullable | Default
1112 --------+---------+-----------+----------+------------------------------------
1114 b | integer | | | generated always as (a * 3) stored
1116 ALTER TABLE gtest29 ALTER COLUMN b DROP EXPRESSION;
1117 INSERT INTO gtest29 (a) VALUES (5);
1118 INSERT INTO gtest29 (a, b) VALUES (6, 66);
1119 SELECT * FROM gtest29;
1129 Table "generated_stored_tests.gtest29"
1130 Column | Type | Collation | Nullable | Default
1131 --------+---------+-----------+----------+---------
1135 -- check that dependencies between columns have also been removed
1136 ALTER TABLE gtest29 DROP COLUMN a; -- should not drop b
1138 Table "generated_stored_tests.gtest29"
1139 Column | Type | Collation | Nullable | Default
1140 --------+---------+-----------+----------+---------
1144 CREATE TABLE gtest30 (
1146 b int GENERATED ALWAYS AS (a * 2) STORED
1148 CREATE TABLE gtest30_1 () INHERITS (gtest30);
1149 ALTER TABLE gtest30 ALTER COLUMN b DROP EXPRESSION;
1151 Table "generated_stored_tests.gtest30"
1152 Column | Type | Collation | Nullable | Default
1153 --------+---------+-----------+----------+---------
1156 Number of child tables: 1 (Use \d+ to list them.)
1159 Table "generated_stored_tests.gtest30_1"
1160 Column | Type | Collation | Nullable | Default
1161 --------+---------+-----------+----------+---------
1166 DROP TABLE gtest30 CASCADE;
1167 NOTICE: drop cascades to table gtest30_1
1168 CREATE TABLE gtest30 (
1170 b int GENERATED ALWAYS AS (a * 2) STORED
1172 CREATE TABLE gtest30_1 () INHERITS (gtest30);
1173 ALTER TABLE ONLY gtest30 ALTER COLUMN b DROP EXPRESSION; -- error
1174 ERROR: ALTER TABLE / DROP EXPRESSION must be applied to child tables too
1176 Table "generated_stored_tests.gtest30"
1177 Column | Type | Collation | Nullable | Default
1178 --------+---------+-----------+----------+------------------------------------
1180 b | integer | | | generated always as (a * 2) stored
1181 Number of child tables: 1 (Use \d+ to list them.)
1184 Table "generated_stored_tests.gtest30_1"
1185 Column | Type | Collation | Nullable | Default
1186 --------+---------+-----------+----------+------------------------------------
1188 b | integer | | | generated always as (a * 2) stored
1191 ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; -- error
1192 ERROR: cannot drop generation expression from inherited column
1194 CREATE TABLE gtest26 (
1196 b int GENERATED ALWAYS AS (a * 2) STORED
1198 CREATE FUNCTION gtest_trigger_func() RETURNS trigger
1202 IF tg_op IN ('DELETE', 'UPDATE') THEN
1203 RAISE INFO '%: %: old = %', TG_NAME, TG_WHEN, OLD;
1205 IF tg_op IN ('INSERT', 'UPDATE') THEN
1206 RAISE INFO '%: %: new = %', TG_NAME, TG_WHEN, NEW;
1208 IF tg_op = 'DELETE' THEN
1215 CREATE TRIGGER gtest1 BEFORE DELETE OR UPDATE ON gtest26
1217 WHEN (OLD.b < 0) -- ok
1218 EXECUTE PROCEDURE gtest_trigger_func();
1219 CREATE TRIGGER gtest2a BEFORE INSERT OR UPDATE ON gtest26
1221 WHEN (NEW.b < 0) -- error
1222 EXECUTE PROCEDURE gtest_trigger_func();
1223 ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated columns
1224 LINE 3: WHEN (NEW.b < 0) -- error
1226 DETAIL: Column "b" is a generated column.
1227 CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26
1229 WHEN (NEW.* IS NOT NULL) -- error
1230 EXECUTE PROCEDURE gtest_trigger_func();
1231 ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated columns
1232 LINE 3: WHEN (NEW.* IS NOT NULL) -- error
1234 DETAIL: A whole-row reference is used and the table contains generated columns.
1235 CREATE TRIGGER gtest2 BEFORE INSERT ON gtest26
1238 EXECUTE PROCEDURE gtest_trigger_func();
1239 CREATE TRIGGER gtest3 AFTER DELETE OR UPDATE ON gtest26
1241 WHEN (OLD.b < 0) -- ok
1242 EXECUTE PROCEDURE gtest_trigger_func();
1243 CREATE TRIGGER gtest4 AFTER INSERT OR UPDATE ON gtest26
1245 WHEN (NEW.b < 0) -- ok
1246 EXECUTE PROCEDURE gtest_trigger_func();
1247 INSERT INTO gtest26 (a) VALUES (-2), (0), (3);
1248 INFO: gtest2: BEFORE: new = (-2,)
1249 INFO: gtest4: AFTER: new = (-2,-4)
1250 SELECT * FROM gtest26 ORDER BY a;
1258 UPDATE gtest26 SET a = a * -2;
1259 INFO: gtest1: BEFORE: old = (-2,-4)
1260 INFO: gtest1: BEFORE: new = (4,)
1261 INFO: gtest3: AFTER: old = (-2,-4)
1262 INFO: gtest3: AFTER: new = (4,8)
1263 INFO: gtest4: AFTER: old = (3,6)
1264 INFO: gtest4: AFTER: new = (-6,-12)
1265 SELECT * FROM gtest26 ORDER BY a;
1273 DELETE FROM gtest26 WHERE a = -6;
1274 INFO: gtest1: BEFORE: old = (-6,-12)
1275 INFO: gtest3: AFTER: old = (-6,-12)
1276 SELECT * FROM gtest26 ORDER BY a;
1283 DROP TRIGGER gtest1 ON gtest26;
1284 DROP TRIGGER gtest2 ON gtest26;
1285 DROP TRIGGER gtest3 ON gtest26;
1286 -- Check that an UPDATE of "a" fires the trigger for UPDATE OF b, per
1288 CREATE FUNCTION gtest_trigger_func3() RETURNS trigger
1296 CREATE TRIGGER gtest11 BEFORE UPDATE OF b ON gtest26
1298 EXECUTE PROCEDURE gtest_trigger_func3();
1299 UPDATE gtest26 SET a = 1 WHERE a = 0;
1301 DROP TRIGGER gtest11 ON gtest26;
1303 -- check that modifications of stored generated columns in triggers do
1304 -- not get propagated
1305 CREATE FUNCTION gtest_trigger_func4() RETURNS trigger
1314 CREATE TRIGGER gtest12_01 BEFORE UPDATE ON gtest26
1316 EXECUTE PROCEDURE gtest_trigger_func();
1317 CREATE TRIGGER gtest12_02 BEFORE UPDATE ON gtest26
1319 EXECUTE PROCEDURE gtest_trigger_func4();
1320 CREATE TRIGGER gtest12_03 BEFORE UPDATE ON gtest26
1322 EXECUTE PROCEDURE gtest_trigger_func();
1323 INSERT INTO gtest26 (a) VALUES (1);
1324 UPDATE gtest26 SET a = 11 WHERE a = 1;
1325 INFO: gtest12_01: BEFORE: old = (1,2)
1326 INFO: gtest12_01: BEFORE: new = (11,)
1327 INFO: gtest12_03: BEFORE: old = (1,2)
1328 INFO: gtest12_03: BEFORE: new = (10,)
1329 SELECT * FROM gtest26 ORDER BY a;
1335 -- LIKE INCLUDING GENERATED and dropped column handling
1336 CREATE TABLE gtest28a (
1340 x int GENERATED ALWAYS AS (b * 2) STORED
1342 ALTER TABLE gtest28a DROP COLUMN a;
1343 CREATE TABLE gtest28b (LIKE gtest28a INCLUDING GENERATED);
1345 Table "generated_stored_tests.gtest28a"
1346 Column | Type | Collation | Nullable | Default
1347 --------+---------+-----------+----------+------------------------------------
1350 x | integer | | | generated always as (b * 2) stored
1352 Table "generated_stored_tests.gtest28b"
1353 Column | Type | Collation | Nullable | Default
1354 --------+---------+-----------+----------+------------------------------------
1357 x | integer | | | generated always as (b * 2) stored