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