1 -- sanity check of system catalog
2 SELECT attrelid, attname, attidentity FROM pg_attribute WHERE attidentity NOT IN ('', 'a', 'd');
3 attrelid | attname | attidentity
4 ----------+---------+-------------
7 CREATE TABLE itest1 (a int generated by default as identity, b text);
8 CREATE TABLE itest2 (a bigint generated always as identity, b text);
9 CREATE TABLE itest3 (a smallint generated by default as identity (start with 7 increment by 5), b text);
10 ALTER TABLE itest3 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; -- error
11 ERROR: column "a" of relation "itest3" is already an identity column
12 SELECT table_name, column_name, column_default, is_nullable, is_identity, identity_generation, identity_start, identity_increment, identity_maximum, identity_minimum, identity_cycle FROM information_schema.columns WHERE table_name LIKE 'itest_' ORDER BY 1, 2;
13 table_name | column_name | column_default | is_nullable | is_identity | identity_generation | identity_start | identity_increment | identity_maximum | identity_minimum | identity_cycle
14 ------------+-------------+----------------+-------------+-------------+---------------------+----------------+--------------------+---------------------+------------------+----------------
15 itest1 | a | | NO | YES | BY DEFAULT | 1 | 1 | 2147483647 | 1 | NO
16 itest1 | b | | YES | NO | | | | | | NO
17 itest2 | a | | NO | YES | ALWAYS | 1 | 1 | 9223372036854775807 | 1 | NO
18 itest2 | b | | YES | NO | | | | | | NO
19 itest3 | a | | NO | YES | BY DEFAULT | 7 | 5 | 32767 | 1 | NO
20 itest3 | b | | YES | NO | | | | | | NO
23 -- internal sequences should not be shown here
24 SELECT sequence_name FROM information_schema.sequences WHERE sequence_name LIKE 'itest%';
29 SELECT pg_get_serial_sequence('itest1', 'a');
30 pg_get_serial_sequence
31 ------------------------
36 Sequence "public.itest1_a_seq"
37 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
38 ---------+-------+---------+------------+-----------+---------+-------
39 integer | 1 | 1 | 2147483647 | 1 | no | 1
40 Sequence for identity column: public.itest1.a
42 CREATE TABLE itest4 (a int, b text);
43 ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; -- error, requires NOT NULL
44 ERROR: column "a" of relation "itest4" must be declared NOT NULL before identity can be added
45 ALTER TABLE itest4 ALTER COLUMN a SET NOT NULL;
46 ALTER TABLE itest4 ALTER COLUMN c ADD GENERATED ALWAYS AS IDENTITY; -- error, column c does not exist
47 ERROR: column "c" of relation "itest4" does not exist
48 ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; -- ok
49 ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL; -- error, disallowed
50 ERROR: column "a" of relation "itest4" is an identity column
51 ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; -- error, already set
52 ERROR: column "a" of relation "itest4" is already an identity column
53 ALTER TABLE itest4 ALTER COLUMN b ADD GENERATED ALWAYS AS IDENTITY; -- error, wrong data type
54 ERROR: identity column type must be smallint, integer, or bigint
56 ALTER TABLE itest4 ALTER COLUMN b SET DEFAULT '';
57 -- invalid column type
58 CREATE TABLE itest_err_1 (a text generated by default as identity);
59 ERROR: identity column type must be smallint, integer, or bigint
61 CREATE TABLE itest_err_2 (a int generated always as identity generated by default as identity);
62 ERROR: multiple identity specifications for column "a" of table "itest_err_2"
63 LINE 1: ...E itest_err_2 (a int generated always as identity generated ...
65 -- cannot have default and identity
66 CREATE TABLE itest_err_3 (a int default 5 generated by default as identity);
67 ERROR: both default and identity specified for column "a" of table "itest_err_3"
68 LINE 1: CREATE TABLE itest_err_3 (a int default 5 generated by defau...
70 -- cannot combine serial and identity
71 CREATE TABLE itest_err_4 (a serial generated by default as identity);
72 ERROR: both default and identity specified for column "a" of table "itest_err_4"
73 INSERT INTO itest1 DEFAULT VALUES;
74 INSERT INTO itest1 DEFAULT VALUES;
75 INSERT INTO itest2 DEFAULT VALUES;
76 INSERT INTO itest2 DEFAULT VALUES;
77 INSERT INTO itest3 DEFAULT VALUES;
78 INSERT INTO itest3 DEFAULT VALUES;
79 INSERT INTO itest4 DEFAULT VALUES;
80 INSERT INTO itest4 DEFAULT VALUES;
102 SELECT * FROM itest4;
110 CREATE TABLE itest5 (a int generated always as identity, b text);
111 INSERT INTO itest5 VALUES (1, 'a'); -- error
112 ERROR: cannot insert a non-DEFAULT value into column "a"
113 DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
114 HINT: Use OVERRIDING SYSTEM VALUE to override.
115 INSERT INTO itest5 VALUES (DEFAULT, 'a'); -- ok
116 INSERT INTO itest5 VALUES (2, 'b'), (3, 'c'); -- error
117 ERROR: cannot insert a non-DEFAULT value into column "a"
118 DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
119 HINT: Use OVERRIDING SYSTEM VALUE to override.
120 INSERT INTO itest5 VALUES (DEFAULT, 'b'), (3, 'c'); -- error
121 ERROR: cannot insert a non-DEFAULT value into column "a"
122 DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
123 HINT: Use OVERRIDING SYSTEM VALUE to override.
124 INSERT INTO itest5 VALUES (2, 'b'), (DEFAULT, 'c'); -- error
125 ERROR: cannot insert a non-DEFAULT value into column "a"
126 DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
127 HINT: Use OVERRIDING SYSTEM VALUE to override.
128 INSERT INTO itest5 VALUES (DEFAULT, 'b'), (DEFAULT, 'c'); -- ok
129 INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-1, 'aa');
130 INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-2, 'bb'), (-3, 'cc');
131 INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'dd'), (-4, 'ee');
132 INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-5, 'ff'), (DEFAULT, 'gg');
133 INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'hh'), (DEFAULT, 'ii');
134 INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-1, 'aaa');
135 INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-2, 'bbb'), (-3, 'ccc');
136 INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'ddd'), (-4, 'eee');
137 INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-5, 'fff'), (DEFAULT, 'ggg');
138 INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'hhh'), (DEFAULT, 'iii');
139 SELECT * FROM itest5;
166 INSERT INTO itest3 VALUES (DEFAULT, 'a');
167 INSERT INTO itest3 VALUES (DEFAULT, 'b'), (DEFAULT, 'c');
168 SELECT * FROM itest3;
179 -- GENERATED BY DEFAULT
180 -- This inserts the row as presented:
181 INSERT INTO itest1 VALUES (10, 'xyz');
182 -- With GENERATED BY DEFAULT, OVERRIDING SYSTEM VALUE is not allowed
183 -- by the standard, but we allow it as a no-op, since it is of use if
184 -- there are multiple identity columns in a table, which is also an
186 INSERT INTO itest1 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz');
187 -- This ignores the 30 and uses the sequence value instead:
188 INSERT INTO itest1 OVERRIDING USER VALUE VALUES (30, 'xyz');
189 SELECT * FROM itest1;
201 INSERT INTO itest2 VALUES (10, 'xyz');
202 ERROR: cannot insert a non-DEFAULT value into column "a"
203 DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
204 HINT: Use OVERRIDING SYSTEM VALUE to override.
205 -- This inserts the row as presented:
206 INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz');
207 -- This ignores the 30 and uses the sequence value instead:
208 INSERT INTO itest2 OVERRIDING USER VALUE VALUES (30, 'xyz');
209 SELECT * FROM itest2;
219 -- GENERATED BY DEFAULT is not restricted.
220 UPDATE itest1 SET a = 101 WHERE a = 1;
221 UPDATE itest1 SET a = DEFAULT WHERE a = 2;
222 SELECT * FROM itest1;
232 -- GENERATED ALWAYS allows only DEFAULT.
233 UPDATE itest2 SET a = 101 WHERE a = 1; -- error
234 ERROR: column "a" can only be updated to DEFAULT
235 DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
236 UPDATE itest2 SET a = DEFAULT WHERE a = 2; -- ok
237 SELECT * FROM itest2;
247 CREATE TABLE itest9 (a int GENERATED ALWAYS AS IDENTITY, b text, c bigint);
248 COPY itest9 FROM stdin;
249 COPY itest9 (b, c) FROM stdin;
250 SELECT * FROM itest9 ORDER BY c;
259 -- DROP IDENTITY tests
260 ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY;
261 ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY; -- error
262 ERROR: column "a" of relation "itest4" is not an identity column
263 ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY IF EXISTS; -- noop
264 NOTICE: column "a" of relation "itest4" is not an identity column, skipping
265 INSERT INTO itest4 DEFAULT VALUES; -- fails because NOT NULL is not dropped
266 ERROR: null value in column "a" of relation "itest4" violates not-null constraint
267 DETAIL: Failing row contains (null, ).
268 ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL;
269 INSERT INTO itest4 DEFAULT VALUES;
270 SELECT * FROM itest4;
278 -- check that sequence is removed
279 SELECT sequence_name FROM itest4_a_seq;
280 ERROR: relation "itest4_a_seq" does not exist
281 LINE 1: SELECT sequence_name FROM itest4_a_seq;
284 CREATE TABLE itest10 (a int generated by default as identity, b text);
285 CREATE TABLE itest11 (a int generated always as identity, b text);
286 CREATE VIEW itestv10 AS SELECT * FROM itest10;
287 CREATE VIEW itestv11 AS SELECT * FROM itest11;
288 INSERT INTO itestv10 DEFAULT VALUES;
289 INSERT INTO itestv10 DEFAULT VALUES;
290 INSERT INTO itestv11 DEFAULT VALUES;
291 INSERT INTO itestv11 DEFAULT VALUES;
292 SELECT * FROM itestv10;
299 SELECT * FROM itestv11;
306 INSERT INTO itestv10 VALUES (10, 'xyz');
307 INSERT INTO itestv10 OVERRIDING USER VALUE VALUES (11, 'xyz');
308 SELECT * FROM itestv10;
317 INSERT INTO itestv11 VALUES (10, 'xyz');
318 ERROR: cannot insert a non-DEFAULT value into column "a"
319 DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
320 HINT: Use OVERRIDING SYSTEM VALUE to override.
321 INSERT INTO itestv11 OVERRIDING SYSTEM VALUE VALUES (11, 'xyz');
322 SELECT * FROM itestv11;
330 DROP VIEW itestv10, itestv11;
332 CREATE TABLE itest13 (a int);
333 -- add column to empty table
334 ALTER TABLE itest13 ADD COLUMN b int GENERATED BY DEFAULT AS IDENTITY;
335 INSERT INTO itest13 VALUES (1), (2), (3);
336 -- add column to populated table
337 ALTER TABLE itest13 ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY;
338 SELECT * FROM itest13;
346 -- various ALTER COLUMN tests
347 -- fail, not allowed for identity columns
348 ALTER TABLE itest1 ALTER COLUMN a SET DEFAULT 1;
349 ERROR: column "a" of relation "itest1" is an identity column
350 -- fail, not allowed, already has a default
351 CREATE TABLE itest5 (a serial, b text);
352 ALTER TABLE itest5 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;
353 ERROR: column "a" of relation "itest5" already has a default value
354 ALTER TABLE itest3 ALTER COLUMN a TYPE int;
355 SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regclass;
362 Table "public.itest3"
363 Column | Type | Collation | Nullable | Default
364 --------+---------+-----------+----------+----------------------------------
365 a | integer | | not null | generated by default as identity
368 ALTER TABLE itest3 ALTER COLUMN a TYPE text; -- error
369 ERROR: identity column type must be smallint, integer, or bigint
370 -- check that unlogged propagates to sequence
371 CREATE UNLOGGED TABLE itest17 (a int NOT NULL, b text);
372 ALTER TABLE itest17 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;
373 ALTER TABLE itest17 ADD COLUMN c int GENERATED ALWAYS AS IDENTITY;
375 Unlogged table "public.itest17"
376 Column | Type | Collation | Nullable | Default
377 --------+---------+-----------+----------+------------------------------
378 a | integer | | not null | generated always as identity
380 c | integer | | not null | generated always as identity
383 Unlogged sequence "public.itest17_a_seq"
384 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
385 ---------+-------+---------+------------+-----------+---------+-------
386 integer | 1 | 1 | 2147483647 | 1 | no | 1
387 Sequence for identity column: public.itest17.a
390 Unlogged sequence "public.itest17_c_seq"
391 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
392 ---------+-------+---------+------------+-----------+---------+-------
393 integer | 1 | 1 | 2147483647 | 1 | no | 1
394 Sequence for identity column: public.itest17.c
396 CREATE TABLE itest18 (a int NOT NULL, b text);
397 ALTER TABLE itest18 SET UNLOGGED, ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;
399 Unlogged table "public.itest18"
400 Column | Type | Collation | Nullable | Default
401 --------+---------+-----------+----------+------------------------------
402 a | integer | | not null | generated always as identity
406 Unlogged sequence "public.itest18_a_seq"
407 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
408 ---------+-------+---------+------------+-----------+---------+-------
409 integer | 1 | 1 | 2147483647 | 1 | no | 1
410 Sequence for identity column: public.itest18.a
412 ALTER TABLE itest18 SET LOGGED;
414 Table "public.itest18"
415 Column | Type | Collation | Nullable | Default
416 --------+---------+-----------+----------+------------------------------
417 a | integer | | not null | generated always as identity
421 Sequence "public.itest18_a_seq"
422 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
423 ---------+-------+---------+------------+-----------+---------+-------
424 integer | 1 | 1 | 2147483647 | 1 | no | 1
425 Sequence for identity column: public.itest18.a
427 ALTER TABLE itest18 SET UNLOGGED;
429 Unlogged table "public.itest18"
430 Column | Type | Collation | Nullable | Default
431 --------+---------+-----------+----------+------------------------------
432 a | integer | | not null | generated always as identity
436 Unlogged sequence "public.itest18_a_seq"
437 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
438 ---------+-------+---------+------------+-----------+---------+-------
439 integer | 1 | 1 | 2147483647 | 1 | no | 1
440 Sequence for identity column: public.itest18.a
442 -- kinda silly to change property in the same command, but it should work
444 ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY,
445 ALTER COLUMN c SET GENERATED ALWAYS;
447 Table "public.itest3"
448 Column | Type | Collation | Nullable | Default
449 --------+---------+-----------+----------+----------------------------------
450 a | integer | | not null | generated by default as identity
452 c | integer | | not null | generated always as identity
454 -- ALTER COLUMN ... SET
455 CREATE TABLE itest6 (a int GENERATED ALWAYS AS IDENTITY, b text);
456 INSERT INTO itest6 DEFAULT VALUES;
457 ALTER TABLE itest6 ALTER COLUMN a SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 100 RESTART;
458 INSERT INTO itest6 DEFAULT VALUES;
459 INSERT INTO itest6 DEFAULT VALUES;
460 SELECT * FROM itest6;
468 SELECT table_name, column_name, is_identity, identity_generation FROM information_schema.columns WHERE table_name = 'itest6' ORDER BY 1, 2;
469 table_name | column_name | is_identity | identity_generation
470 ------------+-------------+-------------+---------------------
471 itest6 | a | YES | BY DEFAULT
475 ALTER TABLE itest6 ALTER COLUMN b SET INCREMENT BY 2; -- fail, not identity
476 ERROR: column "b" of relation "itest6" is not an identity column
477 -- prohibited direct modification of sequence
478 ALTER SEQUENCE itest6_a_seq OWNED BY NONE;
479 ERROR: cannot change ownership of identity sequence
480 DETAIL: Sequence "itest6_a_seq" is linked to table "itest6".
482 CREATE TABLE itest7 (a int GENERATED ALWAYS AS IDENTITY);
483 INSERT INTO itest7 DEFAULT VALUES;
484 SELECT * FROM itest7;
490 -- identity property is not inherited
491 CREATE TABLE itest7a (b text) INHERITS (itest7);
492 -- make column identity in child table
493 CREATE TABLE itest7b (a int);
494 CREATE TABLE itest7c (a int GENERATED ALWAYS AS IDENTITY) INHERITS (itest7b);
495 NOTICE: merging column "a" with inherited definition
496 INSERT INTO itest7c DEFAULT VALUES;
497 SELECT * FROM itest7c;
503 CREATE TABLE itest7d (a int not null);
504 CREATE TABLE itest7e () INHERITS (itest7d);
505 ALTER TABLE itest7d ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;
506 ALTER TABLE itest7d ADD COLUMN b int GENERATED ALWAYS AS IDENTITY; -- error
507 ERROR: cannot recursively add identity column to table that has child tables
508 SELECT table_name, column_name, is_nullable, is_identity, identity_generation FROM information_schema.columns WHERE table_name LIKE 'itest7%' ORDER BY 1, 2;
509 table_name | column_name | is_nullable | is_identity | identity_generation
510 ------------+-------------+-------------+-------------+---------------------
511 itest7 | a | NO | YES | ALWAYS
512 itest7a | a | NO | NO |
513 itest7a | b | YES | NO |
514 itest7b | a | YES | NO |
515 itest7c | a | NO | YES | ALWAYS
516 itest7d | a | NO | YES | ALWAYS
517 itest7e | a | NO | NO |
520 -- These ALTER TABLE variants will not recurse.
521 ALTER TABLE itest7 ALTER COLUMN a SET GENERATED BY DEFAULT;
522 ALTER TABLE itest7 ALTER COLUMN a RESTART;
523 ALTER TABLE itest7 ALTER COLUMN a DROP IDENTITY;
525 CREATE USER regress_identity_user1;
526 CREATE TABLE itest8 (a int GENERATED ALWAYS AS IDENTITY, b text);
527 GRANT SELECT, INSERT ON itest8 TO regress_identity_user1;
528 SET ROLE regress_identity_user1;
529 INSERT INTO itest8 DEFAULT VALUES;
530 SELECT * FROM itest8;
538 DROP USER regress_identity_user1;
539 -- multiple steps in ALTER TABLE
540 CREATE TABLE itest8 (f1 int);
542 ADD COLUMN f2 int NOT NULL,
543 ALTER COLUMN f2 ADD GENERATED ALWAYS AS IDENTITY;
545 ADD COLUMN f3 int NOT NULL,
546 ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY,
547 ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT 10;
551 ALTER COLUMN f4 SET NOT NULL,
552 ALTER COLUMN f4 ADD GENERATED ALWAYS AS IDENTITY,
553 ALTER COLUMN f4 SET DATA TYPE bigint;
555 ADD COLUMN f5 int GENERATED ALWAYS AS IDENTITY;
557 ALTER COLUMN f5 DROP IDENTITY,
558 ALTER COLUMN f5 DROP NOT NULL,
559 ALTER COLUMN f5 SET DATA TYPE bigint;
560 INSERT INTO itest8 VALUES(0), (1);
561 -- This does not work when the table isn't empty. That's intentional,
562 -- since ADD GENERATED should only affect later insertions:
564 ADD COLUMN f22 int NOT NULL,
565 ALTER COLUMN f22 ADD GENERATED ALWAYS AS IDENTITY;
566 ERROR: column "f22" of relation "itest8" contains null values
568 f1 | f2 | f3 | f4 | f5
569 ----+----+----+----+----
575 Table "public.itest8"
576 Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
577 --------+---------+-----------+----------+----------------------------------+---------+--------------+-------------
578 f1 | integer | | | | plain | |
579 f2 | integer | | not null | generated always as identity | plain | |
580 f3 | integer | | not null | generated by default as identity | plain | |
581 f4 | bigint | | not null | generated always as identity | plain | |
582 f5 | bigint | | | | plain | |
583 Not-null constraints:
584 "itest8_f2_not_null" NOT NULL "f2"
585 "itest8_f3_not_null" NOT NULL "f3"
586 "itest8_f4_not_null" NOT NULL "f4"
589 Sequence "public.itest8_f2_seq"
590 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
591 ---------+-------+---------+------------+-----------+---------+-------
592 integer | 1 | 1 | 2147483647 | 1 | no | 1
593 Sequence for identity column: public.itest8.f2
596 Sequence "public.itest8_f3_seq"
597 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
598 ---------+-------+---------+------------+-----------+---------+-------
599 integer | 1 | 1 | 2147483647 | 10 | no | 1
600 Sequence for identity column: public.itest8.f3
603 Sequence "public.itest8_f4_seq"
604 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
605 --------+-------+---------+---------------------+-----------+---------+-------
606 bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
607 Sequence for identity column: public.itest8.f4
611 -- typed tables (currently not supported)
612 CREATE TYPE itest_type AS (f1 integer, f2 text, f3 bigint);
613 CREATE TABLE itest12 OF itest_type (f1 WITH OPTIONS GENERATED ALWAYS AS IDENTITY); -- error
614 ERROR: identity columns are not supported on typed tables
615 DROP TYPE itest_type CASCADE;
617 -- partitions inherit identity column and share sequence
618 CREATE TABLE pitest1 (f1 date NOT NULL, f2 text, f3 bigint generated always as identity) PARTITION BY RANGE (f1);
620 CREATE TABLE pitest1_p1 PARTITION OF pitest1 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
621 INSERT into pitest1(f1, f2) VALUES ('2016-07-2', 'from pitest1');
622 INSERT into pitest1_p1 (f1, f2) VALUES ('2016-07-3', 'from pitest1_p1');
623 -- attached partition
624 CREATE TABLE pitest1_p2 (f3 bigint, f2 text, f1 date NOT NULL);
625 INSERT INTO pitest1_p2 (f1, f2, f3) VALUES ('2016-08-2', 'before attaching', 100);
626 ALTER TABLE pitest1 ATTACH PARTITION pitest1_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01'); -- requires NOT NULL constraint
627 ERROR: column "f3" in child table "pitest1_p2" must be marked NOT NULL
628 ALTER TABLE pitest1_p2 ALTER COLUMN f3 SET NOT NULL;
629 ALTER TABLE pitest1 ATTACH PARTITION pitest1_p2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01');
630 INSERT INTO pitest1_p2 (f1, f2) VALUES ('2016-08-3', 'from pitest1_p2');
631 INSERT INTO pitest1 (f1, f2) VALUES ('2016-08-4', 'from pitest1');
632 -- LIKE INCLUDING on partition
633 CREATE TABLE pitest1_p1_like (LIKE pitest1_p1 INCLUDING IDENTITY);
634 INSERT into pitest1_p1_like(f1, f2) VALUES ('2016-07-2', 'from pitest1_p1_like');
635 SELECT tableoid::regclass, f1, f2, f3 FROM pitest1;
636 tableoid | f1 | f2 | f3
637 ------------+------------+------------------+-----
638 pitest1_p1 | 07-02-2016 | from pitest1 | 1
639 pitest1_p1 | 07-03-2016 | from pitest1_p1 | 2
640 pitest1_p2 | 08-02-2016 | before attaching | 100
641 pitest1_p2 | 08-03-2016 | from pitest1_p2 | 3
642 pitest1_p2 | 08-04-2016 | from pitest1 | 4
645 SELECT tableoid::regclass, f1, f2, f3 FROM pitest1_p1_like;
646 tableoid | f1 | f2 | f3
647 -----------------+------------+----------------------+----
648 pitest1_p1_like | 07-02-2016 | from pitest1_p1_like | 1
651 ALTER TABLE pitest1 ALTER COLUMN f3 SET DATA TYPE bigint;
652 SELECT tableoid::regclass, f1, f2, f3, pg_typeof(f3) FROM pitest1;
653 tableoid | f1 | f2 | f3 | pg_typeof
654 ------------+------------+------------------+-----+-----------
655 pitest1_p1 | 07-02-2016 | from pitest1 | 1 | bigint
656 pitest1_p1 | 07-03-2016 | from pitest1_p1 | 2 | bigint
657 pitest1_p2 | 08-02-2016 | before attaching | 100 | bigint
658 pitest1_p2 | 08-03-2016 | from pitest1_p2 | 3 | bigint
659 pitest1_p2 | 08-04-2016 | from pitest1 | 4 | bigint
662 SELECT tableoid::regclass, f1, f2, f3, pg_typeof(f3) FROM pitest1_p2;
663 tableoid | f1 | f2 | f3 | pg_typeof
664 ------------+------------+------------------+-----+-----------
665 pitest1_p2 | 08-02-2016 | before attaching | 100 | bigint
666 pitest1_p2 | 08-03-2016 | from pitest1_p2 | 3 | bigint
667 pitest1_p2 | 08-04-2016 | from pitest1 | 4 | bigint
670 -- add identity column
671 CREATE TABLE pitest2 (f1 date NOT NULL, f2 text) PARTITION BY RANGE (f1);
672 CREATE TABLE pitest2_p1 PARTITION OF pitest2 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
673 CREATE TABLE pitest2_p2 PARTITION OF pitest2 FOR VALUES FROM ('2016-08-01') TO ('2016-09-01');
674 INSERT into pitest2(f1, f2) VALUES ('2016-07-2', 'from pitest2');
675 INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-2', 'from pitest2');
676 ALTER TABLE pitest2 ADD COLUMN f3 int GENERATED ALWAYS AS IDENTITY;
677 INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-3', 'from pitest2_p1');
678 INSERT INTO pitest2_p2 (f1, f2) VALUES ('2016-08-3', 'from pitest2_p2');
679 INSERT into pitest2(f1, f2) VALUES ('2016-07-4', 'from pitest2');
680 INSERT INTO pitest2 (f1, f2) VALUES ('2016-08-4', 'from pitest2');
681 SELECT tableoid::regclass, f1, f2, f3 FROM pitest2;
682 tableoid | f1 | f2 | f3
683 ------------+------------+-----------------+----
684 pitest2_p1 | 07-02-2016 | from pitest2 | 1
685 pitest2_p1 | 07-03-2016 | from pitest2_p1 | 3
686 pitest2_p1 | 07-04-2016 | from pitest2 | 5
687 pitest2_p2 | 08-02-2016 | from pitest2 | 2
688 pitest2_p2 | 08-03-2016 | from pitest2_p2 | 4
689 pitest2_p2 | 08-04-2016 | from pitest2 | 6
692 -- SET identity column
693 ALTER TABLE pitest2_p1 ALTER COLUMN f3 SET GENERATED BY DEFAULT; -- fails
694 ERROR: cannot change identity column of a partition
695 ALTER TABLE pitest2_p1 ALTER COLUMN f3 SET INCREMENT BY 2; -- fails
696 ERROR: cannot change identity column of a partition
697 ALTER TABLE ONLY pitest2 ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 1000 RESTART; -- fails
698 ERROR: cannot change identity column of only the partitioned table
699 HINT: Do not specify the ONLY keyword.
700 ALTER TABLE pitest2 ALTER COLUMN f3 SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 1000 RESTART;
701 INSERT into pitest2(f1, f2, f3) VALUES ('2016-07-5', 'from pitest2', 200);
702 INSERT INTO pitest2(f1, f2) VALUES ('2016-08-5', 'from pitest2');
703 INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-6', 'from pitest2_p1');
704 INSERT INTO pitest2_p2 (f1, f2, f3) VALUES ('2016-08-6', 'from pitest2_p2', 300);
705 SELECT tableoid::regclass, f1, f2, f3 FROM pitest2;
706 tableoid | f1 | f2 | f3
707 ------------+------------+-----------------+------
708 pitest2_p1 | 07-02-2016 | from pitest2 | 1
709 pitest2_p1 | 07-03-2016 | from pitest2_p1 | 3
710 pitest2_p1 | 07-04-2016 | from pitest2 | 5
711 pitest2_p1 | 07-05-2016 | from pitest2 | 200
712 pitest2_p1 | 07-06-2016 | from pitest2_p1 | 1002
713 pitest2_p2 | 08-02-2016 | from pitest2 | 2
714 pitest2_p2 | 08-03-2016 | from pitest2_p2 | 4
715 pitest2_p2 | 08-04-2016 | from pitest2 | 6
716 pitest2_p2 | 08-05-2016 | from pitest2 | 1000
717 pitest2_p2 | 08-06-2016 | from pitest2_p2 | 300
720 -- detaching a partition removes identity property
721 ALTER TABLE pitest2 DETACH PARTITION pitest2_p1;
722 INSERT into pitest2(f1, f2) VALUES ('2016-08-7', 'from pitest2');
723 INSERT into pitest2_p1 (f1, f2) VALUES ('2016-07-7', 'from pitest2_p1'); -- error
724 ERROR: null value in column "f3" of relation "pitest2_p1" violates not-null constraint
725 DETAIL: Failing row contains (07-07-2016, from pitest2_p1, null).
726 INSERT into pitest2_p1 (f1, f2, f3) VALUES ('2016-07-7', 'from pitest2_p1', 2000);
727 SELECT tableoid::regclass, f1, f2, f3 FROM pitest2;
728 tableoid | f1 | f2 | f3
729 ------------+------------+-----------------+------
730 pitest2_p2 | 08-02-2016 | from pitest2 | 2
731 pitest2_p2 | 08-03-2016 | from pitest2_p2 | 4
732 pitest2_p2 | 08-04-2016 | from pitest2 | 6
733 pitest2_p2 | 08-05-2016 | from pitest2 | 1000
734 pitest2_p2 | 08-06-2016 | from pitest2_p2 | 300
735 pitest2_p2 | 08-07-2016 | from pitest2 | 1004
738 SELECT tableoid::regclass, f1, f2, f3 FROM pitest2_p1;
739 tableoid | f1 | f2 | f3
740 ------------+------------+-----------------+------
741 pitest2_p1 | 07-02-2016 | from pitest2 | 1
742 pitest2_p1 | 07-03-2016 | from pitest2_p1 | 3
743 pitest2_p1 | 07-04-2016 | from pitest2 | 5
744 pitest2_p1 | 07-05-2016 | from pitest2 | 200
745 pitest2_p1 | 07-06-2016 | from pitest2_p1 | 1002
746 pitest2_p1 | 07-07-2016 | from pitest2_p1 | 2000
749 DROP TABLE pitest2_p1;
750 -- changing a regular column to identity column in a partitioned table
751 CREATE TABLE pitest3 (f1 date NOT NULL, f2 text, f3 int) PARTITION BY RANGE (f1);
752 CREATE TABLE pitest3_p1 PARTITION OF pitest3 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
753 INSERT into pitest3 VALUES ('2016-07-2', 'from pitest3', 1);
754 INSERT into pitest3_p1 VALUES ('2016-07-3', 'from pitest3_p1', 2);
755 -- fails, changing only a partition not allowed
756 ALTER TABLE pitest3_p1
757 ALTER COLUMN f3 SET NOT NULL,
758 ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3);
759 ERROR: cannot add identity to a column of a partition
760 -- fails, changing only the partitioned table not allowed
762 ALTER TABLE pitest3_p1 ALTER COLUMN f3 SET NOT NULL;
763 ALTER TABLE ONLY pitest3
764 ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3);
765 ERROR: cannot add identity to a column of only the partitioned table
766 HINT: Do not specify the ONLY keyword.
769 ALTER COLUMN f3 SET NOT NULL,
770 ALTER COLUMN f3 ADD GENERATED ALWAYS AS IDENTITY (START WITH 3);
771 INSERT into pitest3(f1, f2) VALUES ('2016-07-4', 'from pitest3');
772 INSERT into pitest3_p1 (f1, f2) VALUES ('2016-07-5', 'from pitest3_p1');
773 SELECT tableoid::regclass, f1, f2, f3 FROM pitest3;
774 tableoid | f1 | f2 | f3
775 ------------+------------+-----------------+----
776 pitest3_p1 | 07-02-2016 | from pitest3 | 1
777 pitest3_p1 | 07-03-2016 | from pitest3_p1 | 2
778 pitest3_p1 | 07-04-2016 | from pitest3 | 3
779 pitest3_p1 | 07-05-2016 | from pitest3_p1 | 4
782 -- changing an identity column to a non-identity column in a partitioned table
783 ALTER TABLE pitest3_p1 ALTER COLUMN f3 DROP IDENTITY; -- fails
784 ERROR: cannot drop identity from a column of a partition
785 ALTER TABLE ONLY pitest3 ALTER COLUMN f3 DROP IDENTITY; -- fails
786 ERROR: cannot drop identity from a column of only the partitioned table
787 HINT: Do not specify the ONLY keyword.
788 ALTER TABLE pitest3 ALTER COLUMN f3 DROP IDENTITY;
789 INSERT into pitest3(f1, f2) VALUES ('2016-07-4', 'from pitest3'); -- fails
790 ERROR: null value in column "f3" of relation "pitest3_p1" violates not-null constraint
791 DETAIL: Failing row contains (07-04-2016, from pitest3, null).
792 INSERT into pitest3_p1 (f1, f2) VALUES ('2016-07-5', 'from pitest3_p1'); -- fails
793 ERROR: null value in column "f3" of relation "pitest3_p1" violates not-null constraint
794 DETAIL: Failing row contains (07-05-2016, from pitest3_p1, null).
795 INSERT into pitest3(f1, f2, f3) VALUES ('2016-07-6', 'from pitest3', 5);
796 INSERT into pitest3_p1 (f1, f2, f3) VALUES ('2016-07-7', 'from pitest3_p1', 6);
797 SELECT tableoid::regclass, f1, f2, f3 FROM pitest3;
798 tableoid | f1 | f2 | f3
799 ------------+------------+-----------------+----
800 pitest3_p1 | 07-02-2016 | from pitest3 | 1
801 pitest3_p1 | 07-03-2016 | from pitest3_p1 | 2
802 pitest3_p1 | 07-04-2016 | from pitest3 | 3
803 pitest3_p1 | 07-05-2016 | from pitest3_p1 | 4
804 pitest3_p1 | 07-06-2016 | from pitest3 | 5
805 pitest3_p1 | 07-07-2016 | from pitest3_p1 | 6
808 -- Changing NOT NULL constraint of identity columns is not allowed
809 ALTER TABLE pitest1_p1 ALTER COLUMN f3 DROP NOT NULL;
810 ERROR: column "f3" of relation "pitest1_p1" is an identity column
811 ALTER TABLE pitest1 ALTER COLUMN f3 DROP NOT NULL;
812 ERROR: column "f3" of relation "pitest1" is an identity column
813 -- Identity columns have their own default
814 ALTER TABLE pitest1_p2 ALTER COLUMN f3 SET DEFAULT 10000;
815 ERROR: column "f3" of relation "pitest1_p2" is an identity column
816 ALTER TABLE pitest1 ALTER COLUMN f3 SET DEFAULT 10000;
817 ERROR: column "f3" of relation "pitest1" is an identity column
818 -- Adding identity to an identity column is not allowed
819 ALTER TABLE pitest1_p2 ALTER COLUMN f3 ADD GENERATED BY DEFAULT AS IDENTITY;
820 ERROR: cannot add identity to a column of a partition
821 ALTER TABLE pitest1 ALTER COLUMN f3 ADD GENERATED BY DEFAULT AS IDENTITY;
822 ERROR: column "f3" of relation "pitest1" is already an identity column
823 -- partitions with their own identity columns are not allowed, even if the
824 -- partitioned table does not have an identity column.
825 CREATE TABLE pitest1_pfail PARTITION OF pitest1 (
826 f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY
827 ) FOR VALUES FROM ('2016-11-01') TO ('2016-12-01');
828 ERROR: identity columns are not supported on partitions
829 CREATE TABLE pitest_pfail PARTITION OF pitest3 (
830 f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY
831 ) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
832 ERROR: identity columns are not supported on partitions
833 CREATE TABLE pitest1_pfail (f1 date NOT NULL, f2 text, f3 bigint GENERATED ALWAYS AS IDENTITY);
834 ALTER TABLE pitest1 ATTACH PARTITION pitest1_pfail FOR VALUES FROM ('2016-11-01') TO ('2016-12-01');
835 ERROR: table "pitest1_pfail" being attached contains an identity column "f3"
836 DETAIL: The new partition may not contain an identity column.
837 ALTER TABLE pitest3 ATTACH PARTITION pitest1_pfail FOR VALUES FROM ('2016-11-01') TO ('2016-12-01');
838 ERROR: table "pitest1_pfail" being attached contains an identity column "f3"
839 DETAIL: The new partition may not contain an identity column.
840 DROP TABLE pitest1_pfail;
842 -- test that sequence of half-dropped serial column is properly ignored
843 CREATE TABLE itest14 (id serial);
844 ALTER TABLE itest14 ALTER id DROP DEFAULT;
845 ALTER TABLE itest14 ALTER id ADD GENERATED BY DEFAULT AS IDENTITY;
846 INSERT INTO itest14 (id) VALUES (DEFAULT);
847 -- Identity columns must be NOT NULL (cf bug #16913)
848 CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NULL); -- fail
849 ERROR: conflicting NULL/NOT NULL declarations for column "id" of table "itest15"
850 LINE 1: ...ABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NULL);
852 CREATE TABLE itest15 (id integer NULL GENERATED ALWAYS AS IDENTITY); -- fail
853 ERROR: conflicting NULL/NOT NULL declarations for column "id" of table "itest15"
854 LINE 1: CREATE TABLE itest15 (id integer NULL GENERATED ALWAYS AS ID...
856 CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NOT NULL);
858 CREATE TABLE itest15 (id integer NOT NULL GENERATED ALWAYS AS IDENTITY);
861 CREATE TABLE itest15 (a int GENERATED ALWAYS AS IDENTITY, b text);
862 CREATE TABLE itest16 (a int GENERATED BY DEFAULT AS IDENTITY, b text);
864 USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s
866 WHEN NOT MATCHED THEN
867 INSERT (a, b) VALUES (s.s_a, s.s_b);
868 ERROR: cannot insert a non-DEFAULT value into column "a"
869 DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
870 HINT: Use OVERRIDING SYSTEM VALUE to override.
871 -- Used to fail, but now it works and ignores the user supplied value
873 USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s
875 WHEN NOT MATCHED THEN
876 INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b);
878 USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s
880 WHEN NOT MATCHED THEN
881 INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b);
883 USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s
885 WHEN NOT MATCHED THEN
886 INSERT (a, b) VALUES (s.s_a, s.s_b);
888 USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s
890 WHEN NOT MATCHED THEN
891 INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b);
893 USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s
895 WHEN NOT MATCHED THEN
896 INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b);
897 SELECT * FROM itest15;
899 ----+-------------------
900 1 | inserted by merge
901 30 | inserted by merge
904 SELECT * FROM itest16;
906 ----+-------------------
907 10 | inserted by merge
908 1 | inserted by merge
909 30 | inserted by merge
914 -- For testing of pg_dump and pg_upgrade, leave behind some identity
915 -- sequences whose logged-ness doesn't match their owning table's.
916 CREATE TABLE identity_dump_logged (a INT GENERATED ALWAYS AS IDENTITY);
917 ALTER SEQUENCE identity_dump_logged_a_seq SET UNLOGGED;
918 CREATE UNLOGGED TABLE identity_dump_unlogged (a INT GENERATED ALWAYS AS IDENTITY);
919 ALTER SEQUENCE identity_dump_unlogged_a_seq SET LOGGED;
920 SELECT relname, relpersistence FROM pg_class
921 WHERE relname ~ '^identity_dump_' ORDER BY 1;
922 relname | relpersistence
923 ------------------------------+----------------
924 identity_dump_logged | p
925 identity_dump_logged_a_seq | u
926 identity_dump_unlogged | u
927 identity_dump_unlogged_a_seq | p