4 -- Clean up in case a prior regression run failed
5 SET client_min_messages TO 'warning';
6 DROP ROLE IF EXISTS regress_alter_table_user1;
7 RESET client_min_messages;
8 CREATE USER regress_alter_table_user1;
12 CREATE TABLE attmp (initial int4);
13 COMMENT ON TABLE attmp_wrong IS 'table comment';
14 ERROR: relation "attmp_wrong" does not exist
15 COMMENT ON TABLE attmp IS 'table comment';
16 COMMENT ON TABLE attmp IS NULL;
17 ALTER TABLE attmp ADD COLUMN xmin integer; -- fails
18 ERROR: column name "xmin" conflicts with a system column name
19 ALTER TABLE attmp ADD COLUMN a int4 default 3;
20 ALTER TABLE attmp ADD COLUMN b name;
21 ALTER TABLE attmp ADD COLUMN c text;
22 ALTER TABLE attmp ADD COLUMN d float8;
23 ALTER TABLE attmp ADD COLUMN e float4;
24 ALTER TABLE attmp ADD COLUMN f int2;
25 ALTER TABLE attmp ADD COLUMN g polygon;
26 ALTER TABLE attmp ADD COLUMN i char;
27 ALTER TABLE attmp ADD COLUMN k int4;
28 ALTER TABLE attmp ADD COLUMN l tid;
29 ALTER TABLE attmp ADD COLUMN m xid;
30 ALTER TABLE attmp ADD COLUMN n oidvector;
31 --ALTER TABLE attmp ADD COLUMN o lock;
32 ALTER TABLE attmp ADD COLUMN p boolean;
33 ALTER TABLE attmp ADD COLUMN q point;
34 ALTER TABLE attmp ADD COLUMN r lseg;
35 ALTER TABLE attmp ADD COLUMN s path;
36 ALTER TABLE attmp ADD COLUMN t box;
37 ALTER TABLE attmp ADD COLUMN v timestamp;
38 ALTER TABLE attmp ADD COLUMN w interval;
39 ALTER TABLE attmp ADD COLUMN x float8[];
40 ALTER TABLE attmp ADD COLUMN y float4[];
41 ALTER TABLE attmp ADD COLUMN z int2[];
42 INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t,
44 VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)',
46 314159, '(1,1)', '512',
47 '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)',
48 '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)',
49 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}');
51 initial | a | b | c | d | e | f | g | i | k | l | m | n | p | q | r | s | t | v | w | x | y | z
52 ---------+---+------+------+-----+-----+---+-----------------------+---+--------+-------+-----+-----------------+---+-----------+-----------------------+-----------------------------+---------------------+--------------------------+------------------+-----------+-----------+-----------
53 | 4 | name | text | 4.1 | 4.1 | 2 | ((4.1,4.1),(3.1,3.1)) | c | 314159 | (1,1) | 512 | 1 2 3 4 5 6 7 8 | t | (1.1,1.1) | [(4.1,4.1),(3.1,3.1)] | ((0,2),(4.1,4.1),(3.1,3.1)) | (4.1,4.1),(3.1,3.1) | Thu Jan 01 00:00:00 1970 | @ 1 hour 10 secs | {1,2,3,4} | {1,2,3,4} | {1,2,3,4}
57 -- the wolf bug - schema mods caused inconsistent row descriptors
61 ALTER TABLE attmp ADD COLUMN a int4;
62 ALTER TABLE attmp ADD COLUMN b name;
63 ALTER TABLE attmp ADD COLUMN c text;
64 ALTER TABLE attmp ADD COLUMN d float8;
65 ALTER TABLE attmp ADD COLUMN e float4;
66 ALTER TABLE attmp ADD COLUMN f int2;
67 ALTER TABLE attmp ADD COLUMN g polygon;
68 ALTER TABLE attmp ADD COLUMN i char;
69 ALTER TABLE attmp ADD COLUMN k int4;
70 ALTER TABLE attmp ADD COLUMN l tid;
71 ALTER TABLE attmp ADD COLUMN m xid;
72 ALTER TABLE attmp ADD COLUMN n oidvector;
73 --ALTER TABLE attmp ADD COLUMN o lock;
74 ALTER TABLE attmp ADD COLUMN p boolean;
75 ALTER TABLE attmp ADD COLUMN q point;
76 ALTER TABLE attmp ADD COLUMN r lseg;
77 ALTER TABLE attmp ADD COLUMN s path;
78 ALTER TABLE attmp ADD COLUMN t box;
79 ALTER TABLE attmp ADD COLUMN v timestamp;
80 ALTER TABLE attmp ADD COLUMN w interval;
81 ALTER TABLE attmp ADD COLUMN x float8[];
82 ALTER TABLE attmp ADD COLUMN y float4[];
83 ALTER TABLE attmp ADD COLUMN z int2[];
84 INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t,
86 VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)',
88 314159, '(1,1)', '512',
89 '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)',
90 '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)',
91 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}');
93 initial | a | b | c | d | e | f | g | i | k | l | m | n | p | q | r | s | t | v | w | x | y | z
94 ---------+---+------+------+-----+-----+---+-----------------------+---+--------+-------+-----+-----------------+---+-----------+-----------------------+-----------------------------+---------------------+--------------------------+------------------+-----------+-----------+-----------
95 | 4 | name | text | 4.1 | 4.1 | 2 | ((4.1,4.1),(3.1,3.1)) | c | 314159 | (1,1) | 512 | 1 2 3 4 5 6 7 8 | t | (1.1,1.1) | [(4.1,4.1),(3.1,3.1)] | ((0,2),(4.1,4.1),(3.1,3.1)) | (4.1,4.1),(3.1,3.1) | Thu Jan 01 00:00:00 1970 | @ 1 hour 10 secs | {1,2,3,4} | {1,2,3,4} | {1,2,3,4}
98 CREATE INDEX attmp_idx ON attmp (a, (d + e), b);
99 ALTER INDEX attmp_idx ALTER COLUMN 0 SET STATISTICS 1000;
100 ERROR: column number must be in range from 1 to 32767
101 LINE 1: ALTER INDEX attmp_idx ALTER COLUMN 0 SET STATISTICS 1000;
103 ALTER INDEX attmp_idx ALTER COLUMN 1 SET STATISTICS 1000;
104 ERROR: cannot alter statistics on non-expression column "a" of index "attmp_idx"
105 HINT: Alter statistics on table column instead.
106 ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000;
108 Index "public.attmp_idx"
109 Column | Type | Key? | Definition | Storage | Stats target
110 --------+------------------+------+------------+---------+--------------
111 a | integer | yes | a | plain |
112 expr | double precision | yes | (d + e) | plain | 1000
113 b | cstring | yes | b | plain |
114 btree, for table "public.attmp"
116 ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000;
117 ERROR: cannot alter statistics on non-expression column "b" of index "attmp_idx"
118 HINT: Alter statistics on table column instead.
119 ALTER INDEX attmp_idx ALTER COLUMN 4 SET STATISTICS 1000;
120 ERROR: column number 4 of relation "attmp_idx" does not exist
121 ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS -1;
124 -- rename - check on both non-temp and temp tables
126 CREATE TABLE attmp (regtable int);
127 CREATE TEMP TABLE attmp (attmptable int);
128 ALTER TABLE attmp RENAME TO attmp_new;
134 SELECT * FROM attmp_new;
139 ALTER TABLE attmp RENAME TO attmp_new2;
140 SELECT * FROM attmp; -- should fail
141 ERROR: relation "attmp" does not exist
142 LINE 1: SELECT * FROM attmp;
144 SELECT * FROM attmp_new;
149 SELECT * FROM attmp_new2;
154 DROP TABLE attmp_new;
155 DROP TABLE attmp_new2;
156 -- check rename of partitioned tables and indexes also
157 CREATE TABLE part_attmp (a int primary key) partition by range (a);
158 CREATE TABLE part_attmp1 PARTITION OF part_attmp FOR VALUES FROM (0) TO (100);
159 ALTER INDEX part_attmp_pkey RENAME TO part_attmp_index;
160 ALTER INDEX part_attmp1_pkey RENAME TO part_attmp1_index;
161 ALTER TABLE part_attmp RENAME TO part_at2tmp;
162 ALTER TABLE part_attmp1 RENAME TO part_at2tmp1;
163 SET ROLE regress_alter_table_user1;
164 ALTER INDEX part_attmp_index RENAME TO fail;
165 ERROR: must be owner of index part_attmp_index
166 ALTER INDEX part_attmp1_index RENAME TO fail;
167 ERROR: must be owner of index part_attmp1_index
168 ALTER TABLE part_at2tmp RENAME TO fail;
169 ERROR: must be owner of table part_at2tmp
170 ALTER TABLE part_at2tmp1 RENAME TO fail;
171 ERROR: must be owner of table part_at2tmp1
173 DROP TABLE part_at2tmp;
175 -- check renaming to a table's array type's autogenerated name
176 -- (the array type's name should get out of the way)
178 CREATE TABLE attmp_array (id int);
179 CREATE TABLE attmp_array2 (id int);
180 SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
186 SELECT typname FROM pg_type WHERE oid = 'attmp_array2[]'::regtype;
192 ALTER TABLE attmp_array2 RENAME TO _attmp_array;
193 SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
199 SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype;
205 DROP TABLE _attmp_array;
206 DROP TABLE attmp_array;
207 -- renaming to table's own array type's name is an interesting corner case
208 CREATE TABLE attmp_array (id int);
209 SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
215 ALTER TABLE attmp_array RENAME TO _attmp_array;
216 SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype;
222 DROP TABLE _attmp_array;
223 -- ALTER TABLE ... RENAME on non-table relations
224 -- renaming indexes (FIXME: this should probably test the index's functionality)
225 ALTER INDEX IF EXISTS __onek_unique1 RENAME TO attmp_onek_unique1;
226 NOTICE: relation "__onek_unique1" does not exist, skipping
227 ALTER INDEX IF EXISTS __attmp_onek_unique1 RENAME TO onek_unique1;
228 NOTICE: relation "__attmp_onek_unique1" does not exist, skipping
229 ALTER INDEX onek_unique1 RENAME TO attmp_onek_unique1;
230 ALTER INDEX attmp_onek_unique1 RENAME TO onek_unique1;
231 SET ROLE regress_alter_table_user1;
232 ALTER INDEX onek_unique1 RENAME TO fail; -- permission denied
233 ERROR: must be owner of index onek_unique1
235 -- rename statements with mismatching statement and object types
236 CREATE TABLE alter_idx_rename_test (a INT);
237 CREATE INDEX alter_idx_rename_test_idx ON alter_idx_rename_test (a);
238 CREATE TABLE alter_idx_rename_test_parted (a INT) PARTITION BY LIST (a);
239 CREATE INDEX alter_idx_rename_test_parted_idx ON alter_idx_rename_test_parted (a);
241 ALTER INDEX alter_idx_rename_test RENAME TO alter_idx_rename_test_2;
242 ALTER INDEX alter_idx_rename_test_parted RENAME TO alter_idx_rename_test_parted_2;
243 SELECT relation::regclass, mode FROM pg_locks
244 WHERE pid = pg_backend_pid() AND locktype = 'relation'
245 AND relation::regclass::text LIKE 'alter\_idx%'
246 ORDER BY relation::regclass::text COLLATE "C";
248 --------------------------------+---------------------
249 alter_idx_rename_test_2 | AccessExclusiveLock
250 alter_idx_rename_test_parted_2 | AccessExclusiveLock
255 ALTER INDEX alter_idx_rename_test_idx RENAME TO alter_idx_rename_test_idx_2;
256 ALTER INDEX alter_idx_rename_test_parted_idx RENAME TO alter_idx_rename_test_parted_idx_2;
257 SELECT relation::regclass, mode FROM pg_locks
258 WHERE pid = pg_backend_pid() AND locktype = 'relation'
259 AND relation::regclass::text LIKE 'alter\_idx%'
260 ORDER BY relation::regclass::text COLLATE "C";
262 ------------------------------------+--------------------------
263 alter_idx_rename_test_idx_2 | ShareUpdateExclusiveLock
264 alter_idx_rename_test_parted_idx_2 | ShareUpdateExclusiveLock
269 ALTER TABLE alter_idx_rename_test_idx_2 RENAME TO alter_idx_rename_test_idx_3;
270 ALTER TABLE alter_idx_rename_test_parted_idx_2 RENAME TO alter_idx_rename_test_parted_idx_3;
271 SELECT relation::regclass, mode FROM pg_locks
272 WHERE pid = pg_backend_pid() AND locktype = 'relation'
273 AND relation::regclass::text LIKE 'alter\_idx%'
274 ORDER BY relation::regclass::text COLLATE "C";
276 ------------------------------------+---------------------
277 alter_idx_rename_test_idx_3 | AccessExclusiveLock
278 alter_idx_rename_test_parted_idx_3 | AccessExclusiveLock
282 DROP TABLE alter_idx_rename_test_2;
284 CREATE VIEW attmp_view (unique1) AS SELECT unique1 FROM tenk1;
285 ALTER TABLE attmp_view RENAME TO attmp_view_new;
286 SET ROLE regress_alter_table_user1;
287 ALTER VIEW attmp_view_new RENAME TO fail; -- permission denied
288 ERROR: must be owner of view attmp_view_new
290 -- hack to ensure we get an indexscan here
291 set enable_seqscan to off;
292 set enable_bitmapscan to off;
294 SELECT unique1 FROM tenk1 WHERE unique1 < 5;
304 reset enable_seqscan;
305 reset enable_bitmapscan;
306 DROP VIEW attmp_view_new;
307 -- toast-like relation name
308 alter table stud_emp rename to pg_toast_stud_emp;
309 alter table pg_toast_stud_emp rename to stud_emp;
310 -- renaming index should rename constraint as well
311 ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1);
312 ALTER INDEX onek_unique1_constraint RENAME TO onek_unique1_constraint_foo;
313 ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo;
314 -- renaming constraint
315 ALTER TABLE onek ADD CONSTRAINT onek_check_constraint CHECK (unique1 >= 0);
316 ALTER TABLE onek RENAME CONSTRAINT onek_check_constraint TO onek_check_constraint_foo;
317 ALTER TABLE onek DROP CONSTRAINT onek_check_constraint_foo;
318 -- renaming constraint should rename index as well
319 ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1);
320 DROP INDEX onek_unique1_constraint; -- to see whether it's there
321 ERROR: cannot drop index onek_unique1_constraint because constraint onek_unique1_constraint on table onek requires it
322 HINT: You can drop constraint onek_unique1_constraint on table onek instead.
323 ALTER TABLE onek RENAME CONSTRAINT onek_unique1_constraint TO onek_unique1_constraint_foo;
324 DROP INDEX onek_unique1_constraint_foo; -- to see whether it's there
325 ERROR: cannot drop index onek_unique1_constraint_foo because constraint onek_unique1_constraint_foo on table onek requires it
326 HINT: You can drop constraint onek_unique1_constraint_foo on table onek instead.
327 ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo;
328 -- renaming constraints vs. inheritance
329 CREATE TABLE constraint_rename_test (a int CONSTRAINT con1 CHECK (a > 0), b int, c int);
330 \d constraint_rename_test
331 Table "public.constraint_rename_test"
332 Column | Type | Collation | Nullable | Default
333 --------+---------+-----------+----------+---------
340 CREATE TABLE constraint_rename_test2 (a int CONSTRAINT con1 CHECK (a > 0), d int) INHERITS (constraint_rename_test);
341 NOTICE: merging column "a" with inherited definition
342 NOTICE: merging constraint "con1" with inherited definition
343 \d constraint_rename_test2
344 Table "public.constraint_rename_test2"
345 Column | Type | Collation | Nullable | Default
346 --------+---------+-----------+----------+---------
353 Inherits: constraint_rename_test
355 ALTER TABLE constraint_rename_test2 RENAME CONSTRAINT con1 TO con1foo; -- fail
356 ERROR: cannot rename inherited constraint "con1"
357 ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con1 TO con1foo; -- fail
358 ERROR: inherited constraint "con1" must be renamed in child tables too
359 ALTER TABLE constraint_rename_test RENAME CONSTRAINT con1 TO con1foo; -- ok
360 \d constraint_rename_test
361 Table "public.constraint_rename_test"
362 Column | Type | Collation | Nullable | Default
363 --------+---------+-----------+----------+---------
368 "con1foo" CHECK (a > 0)
369 Number of child tables: 1 (Use \d+ to list them.)
371 \d constraint_rename_test2
372 Table "public.constraint_rename_test2"
373 Column | Type | Collation | Nullable | Default
374 --------+---------+-----------+----------+---------
380 "con1foo" CHECK (a > 0)
381 Inherits: constraint_rename_test
383 ALTER TABLE constraint_rename_test ADD CONSTRAINT con2 CHECK (b > 0) NO INHERIT;
384 ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con2 TO con2foo; -- ok
385 ALTER TABLE constraint_rename_test RENAME CONSTRAINT con2foo TO con2bar; -- ok
386 \d constraint_rename_test
387 Table "public.constraint_rename_test"
388 Column | Type | Collation | Nullable | Default
389 --------+---------+-----------+----------+---------
394 "con1foo" CHECK (a > 0)
395 "con2bar" CHECK (b > 0) NO INHERIT
396 Number of child tables: 1 (Use \d+ to list them.)
398 \d constraint_rename_test2
399 Table "public.constraint_rename_test2"
400 Column | Type | Collation | Nullable | Default
401 --------+---------+-----------+----------+---------
407 "con1foo" CHECK (a > 0)
408 Inherits: constraint_rename_test
410 ALTER TABLE constraint_rename_test ADD CONSTRAINT con3 PRIMARY KEY (a);
411 ALTER TABLE constraint_rename_test RENAME CONSTRAINT con3 TO con3foo; -- ok
412 \d constraint_rename_test
413 Table "public.constraint_rename_test"
414 Column | Type | Collation | Nullable | Default
415 --------+---------+-----------+----------+---------
416 a | integer | | not null |
420 "con3foo" PRIMARY KEY, btree (a)
422 "con1foo" CHECK (a > 0)
423 "con2bar" CHECK (b > 0) NO INHERIT
424 Number of child tables: 1 (Use \d+ to list them.)
426 \d constraint_rename_test2
427 Table "public.constraint_rename_test2"
428 Column | Type | Collation | Nullable | Default
429 --------+---------+-----------+----------+---------
430 a | integer | | not null |
435 "con1foo" CHECK (a > 0)
436 Inherits: constraint_rename_test
438 DROP TABLE constraint_rename_test2;
439 DROP TABLE constraint_rename_test;
440 ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo; -- ok
441 NOTICE: relation "constraint_not_exist" does not exist, skipping
442 ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
443 NOTICE: relation "constraint_rename_test" does not exist, skipping
444 -- renaming constraints with cache reset of target relation
445 CREATE TABLE constraint_rename_cache (a int,
446 CONSTRAINT chk_a CHECK (a > 0),
448 ALTER TABLE constraint_rename_cache
449 RENAME CONSTRAINT chk_a TO chk_a_new;
450 ALTER TABLE constraint_rename_cache
451 RENAME CONSTRAINT constraint_rename_cache_pkey TO constraint_rename_pkey_new;
452 CREATE TABLE like_constraint_rename_cache
453 (LIKE constraint_rename_cache INCLUDING ALL);
454 \d like_constraint_rename_cache
455 Table "public.like_constraint_rename_cache"
456 Column | Type | Collation | Nullable | Default
457 --------+---------+-----------+----------+---------
458 a | integer | | not null |
460 "like_constraint_rename_cache_pkey" PRIMARY KEY, btree (a)
462 "chk_a_new" CHECK (a > 0)
464 DROP TABLE constraint_rename_cache;
465 DROP TABLE like_constraint_rename_cache;
466 -- FOREIGN KEY CONSTRAINT adding TEST
467 CREATE TABLE attmp2 (a int primary key);
468 CREATE TABLE attmp3 (a int, b int);
469 CREATE TABLE attmp4 (a int, b int, unique(a,b));
470 CREATE TABLE attmp5 (a int, b int);
471 -- Insert rows into attmp2 (pktable)
472 INSERT INTO attmp2 values (1);
473 INSERT INTO attmp2 values (2);
474 INSERT INTO attmp2 values (3);
475 INSERT INTO attmp2 values (4);
476 -- Insert rows into attmp3
477 INSERT INTO attmp3 values (1,10);
478 INSERT INTO attmp3 values (1,20);
479 INSERT INTO attmp3 values (5,50);
480 -- Try (and fail) to add constraint due to invalid source columns
481 ALTER TABLE attmp3 add constraint attmpconstr foreign key(c) references attmp2 match full;
482 ERROR: column "c" referenced in foreign key constraint does not exist
483 -- Try (and fail) to add constraint due to invalid destination columns explicitly given
484 ALTER TABLE attmp3 add constraint attmpconstr foreign key(a) references attmp2(b) match full;
485 ERROR: column "b" referenced in foreign key constraint does not exist
486 -- Try (and fail) to add constraint due to invalid data
487 ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full;
488 ERROR: insert or update on table "attmp3" violates foreign key constraint "attmpconstr"
489 DETAIL: Key (a)=(5) is not present in table "attmp2".
490 -- Delete failing row
491 DELETE FROM attmp3 where a=5;
493 ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full;
494 ALTER TABLE attmp3 drop constraint attmpconstr;
495 INSERT INTO attmp3 values (5,50);
496 -- Try NOT VALID and then VALIDATE CONSTRAINT, but fails. Delete failure then re-validate
497 ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full NOT VALID;
498 ALTER TABLE attmp3 validate constraint attmpconstr;
499 ERROR: insert or update on table "attmp3" violates foreign key constraint "attmpconstr"
500 DETAIL: Key (a)=(5) is not present in table "attmp2".
501 -- Delete failing row
502 DELETE FROM attmp3 where a=5;
503 -- Try (and succeed) and repeat to show it works on already valid constraint
504 ALTER TABLE attmp3 validate constraint attmpconstr;
505 ALTER TABLE attmp3 validate constraint attmpconstr;
506 -- Try a non-verified CHECK constraint
507 ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail
508 ERROR: check constraint "b_greater_than_ten" of relation "attmp3" is violated by some row
509 ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; -- succeeds
510 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- fails
511 ERROR: check constraint "b_greater_than_ten" of relation "attmp3" is violated by some row
512 DELETE FROM attmp3 WHERE NOT b > 10;
513 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
514 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
515 -- Test inherited NOT VALID CHECK constraints
516 select * from attmp3;
522 CREATE TABLE attmp6 () INHERITS (attmp3);
523 CREATE TABLE attmp7 () INHERITS (attmp3);
524 INSERT INTO attmp6 VALUES (6, 30), (7, 16);
525 ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID;
526 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20; -- fails
527 ERROR: check constraint "b_le_20" of relation "attmp6" is violated by some row
528 DELETE FROM attmp6 WHERE b > 20;
529 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20; -- succeeds
530 -- An already validated constraint must not be revalidated
531 CREATE FUNCTION boo(int) RETURNS int IMMUTABLE STRICT LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'boo: %', $1; RETURN $1; END; $$;
532 INSERT INTO attmp7 VALUES (8, 18);
533 ALTER TABLE attmp7 ADD CONSTRAINT identity CHECK (b = boo(b));
535 ALTER TABLE attmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID;
536 NOTICE: merging constraint "identity" with inherited definition
537 ALTER TABLE attmp3 VALIDATE CONSTRAINT identity;
540 -- A NO INHERIT constraint should not be looked for in children during VALIDATE CONSTRAINT
541 create table parent_noinh_convalid (a int);
542 create table child_noinh_convalid () inherits (parent_noinh_convalid);
543 insert into parent_noinh_convalid values (1);
544 insert into child_noinh_convalid values (1);
545 alter table parent_noinh_convalid add constraint check_a_is_2 check (a = 2) no inherit not valid;
546 -- fail, because of the row in parent
547 alter table parent_noinh_convalid validate constraint check_a_is_2;
548 ERROR: check constraint "check_a_is_2" of relation "parent_noinh_convalid" is violated by some row
549 delete from only parent_noinh_convalid;
550 -- ok (parent itself contains no violating rows)
551 alter table parent_noinh_convalid validate constraint check_a_is_2;
552 select convalidated from pg_constraint where conrelid = 'parent_noinh_convalid'::regclass and conname = 'check_a_is_2';
559 drop table parent_noinh_convalid, child_noinh_convalid;
560 -- Try (and fail) to create constraint from attmp5(a) to attmp4(a) - unique constraint on
562 ALTER TABLE attmp5 add constraint attmpconstr foreign key(a) references attmp4(a) match full;
563 ERROR: there is no unique constraint matching given keys for referenced table "attmp4"
570 -- NOT VALID with plan invalidation -- ensure we don't use a constraint for
571 -- exclusion until validated
572 set constraint_exclusion TO 'partition';
573 create table nv_parent (d date, check (false) no inherit not valid);
574 -- not valid constraint added at creation time should automatically become valid
576 Table "public.nv_parent"
577 Column | Type | Collation | Nullable | Default
578 --------+------+-----------+----------+---------
581 "nv_parent_check" CHECK (false) NO INHERIT
583 create table nv_child_2010 () inherits (nv_parent);
584 create table nv_child_2011 () inherits (nv_parent);
585 alter table nv_child_2010 add check (d between '2010-01-01'::date and '2010-12-31'::date) not valid;
586 alter table nv_child_2011 add check (d between '2011-01-01'::date and '2011-12-31'::date) not valid;
587 explain (costs off) select * from nv_parent where d between '2011-08-01' and '2011-08-31';
589 ---------------------------------------------------------------------------
591 -> Seq Scan on nv_parent nv_parent_1
592 Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
593 -> Seq Scan on nv_child_2010 nv_parent_2
594 Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
595 -> Seq Scan on nv_child_2011 nv_parent_3
596 Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
599 create table nv_child_2009 (check (d between '2009-01-01'::date and '2009-12-31'::date)) inherits (nv_parent);
600 explain (costs off) select * from nv_parent where d between '2011-08-01'::date and '2011-08-31'::date;
602 ---------------------------------------------------------------------------
604 -> Seq Scan on nv_parent nv_parent_1
605 Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
606 -> Seq Scan on nv_child_2010 nv_parent_2
607 Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
608 -> Seq Scan on nv_child_2011 nv_parent_3
609 Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
612 explain (costs off) select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date;
614 ---------------------------------------------------------------------------
616 -> Seq Scan on nv_parent nv_parent_1
617 Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
618 -> Seq Scan on nv_child_2010 nv_parent_2
619 Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
620 -> Seq Scan on nv_child_2011 nv_parent_3
621 Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
622 -> Seq Scan on nv_child_2009 nv_parent_4
623 Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
626 -- after validation, the constraint should be used
627 alter table nv_child_2011 VALIDATE CONSTRAINT nv_child_2011_d_check;
628 explain (costs off) select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date;
630 ---------------------------------------------------------------------------
632 -> Seq Scan on nv_parent nv_parent_1
633 Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
634 -> Seq Scan on nv_child_2010 nv_parent_2
635 Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
636 -> Seq Scan on nv_child_2009 nv_parent_3
637 Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
640 -- add an inherited NOT VALID constraint
641 alter table nv_parent add check (d between '2001-01-01'::date and '2099-12-31'::date) not valid;
643 Table "public.nv_child_2009"
644 Column | Type | Collation | Nullable | Default
645 --------+------+-----------+----------+---------
648 "nv_child_2009_d_check" CHECK (d >= '01-01-2009'::date AND d <= '12-31-2009'::date)
649 "nv_parent_d_check" CHECK (d >= '01-01-2001'::date AND d <= '12-31-2099'::date) NOT VALID
652 -- we leave nv_parent and children around to help test pg_dump logic
653 -- Foreign key adding test with mixed types
654 -- Note: these tables are TEMP to avoid name conflicts when this test
655 -- is run in parallel with foreign_key.sql.
656 CREATE TEMP TABLE PKTABLE (ptest1 int PRIMARY KEY);
657 INSERT INTO PKTABLE VALUES(42);
658 CREATE TEMP TABLE FKTABLE (ftest1 inet);
659 -- This next should fail, because int=inet does not exist
660 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
661 ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
662 DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
663 -- This should also fail for the same reason, but here we
664 -- give the column name
665 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
666 ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
667 DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
669 -- This should succeed, even though they are different types,
670 -- because int=int8 exists and is a member of the integer opfamily
671 CREATE TEMP TABLE FKTABLE (ftest1 int8);
672 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
673 -- Check it actually works
674 INSERT INTO FKTABLE VALUES(42); -- should succeed
675 INSERT INTO FKTABLE VALUES(43); -- should fail
676 ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey"
677 DETAIL: Key (ftest1)=(43) is not present in table "pktable".
679 -- This should fail, because we'd have to cast numeric to int which is
680 -- not an implicit coercion (or use numeric=numeric, but that's not part
681 -- of the integer opfamily)
682 CREATE TEMP TABLE FKTABLE (ftest1 numeric);
683 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
684 ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
685 DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: numeric and integer.
688 -- On the other hand, this should work because int implicitly promotes to
689 -- numeric, and we allow promotion on the FK side
690 CREATE TEMP TABLE PKTABLE (ptest1 numeric PRIMARY KEY);
691 INSERT INTO PKTABLE VALUES(42);
692 CREATE TEMP TABLE FKTABLE (ftest1 int);
693 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
694 -- Check it actually works
695 INSERT INTO FKTABLE VALUES(42); -- should succeed
696 INSERT INTO FKTABLE VALUES(43); -- should fail
697 ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey"
698 DETAIL: Key (ftest1)=(43) is not present in table "pktable".
701 CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
702 PRIMARY KEY(ptest1, ptest2));
703 -- This should fail, because we just chose really odd types
704 CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp);
705 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable;
706 ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
707 DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: cidr and integer.
709 -- Again, so should this...
710 CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp);
711 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
712 references pktable(ptest1, ptest2);
713 ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
714 DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: cidr and integer.
716 -- This fails because we mixed up the column ordering
717 CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet);
718 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
719 references pktable(ptest2, ptest1);
720 ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
721 DETAIL: Key columns "ftest1" of the referencing table and "ptest2" of the referenced table are of incompatible types: integer and inet.
723 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1)
724 references pktable(ptest1, ptest2);
725 ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented
726 DETAIL: Key columns "ftest2" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
729 -- Test that ALTER CONSTRAINT updates trigger deferrability properly
730 CREATE TEMP TABLE PKTABLE (ptest1 int primary key);
731 CREATE TEMP TABLE FKTABLE (ftest1 int);
732 ALTER TABLE FKTABLE ADD CONSTRAINT fknd FOREIGN KEY(ftest1) REFERENCES pktable
733 ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE;
734 ALTER TABLE FKTABLE ADD CONSTRAINT fkdd FOREIGN KEY(ftest1) REFERENCES pktable
735 ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED;
736 ALTER TABLE FKTABLE ADD CONSTRAINT fkdi FOREIGN KEY(ftest1) REFERENCES pktable
737 ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY IMMEDIATE;
738 ALTER TABLE FKTABLE ADD CONSTRAINT fknd2 FOREIGN KEY(ftest1) REFERENCES pktable
739 ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED;
740 ALTER TABLE FKTABLE ALTER CONSTRAINT fknd2 NOT DEFERRABLE;
741 ALTER TABLE FKTABLE ADD CONSTRAINT fkdd2 FOREIGN KEY(ftest1) REFERENCES pktable
742 ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE;
743 ALTER TABLE FKTABLE ALTER CONSTRAINT fkdd2 DEFERRABLE INITIALLY DEFERRED;
744 ALTER TABLE FKTABLE ADD CONSTRAINT fkdi2 FOREIGN KEY(ftest1) REFERENCES pktable
745 ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE;
746 ALTER TABLE FKTABLE ALTER CONSTRAINT fkdi2 DEFERRABLE INITIALLY IMMEDIATE;
747 SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred
748 FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint
749 WHERE tgrelid = 'pktable'::regclass
751 conname | tgfoid | tgtype | tgdeferrable | tginitdeferred
752 ---------+------------------------+--------+--------------+----------------
753 fkdd | "RI_FKey_cascade_del" | 9 | f | f
754 fkdd | "RI_FKey_noaction_upd" | 17 | t | t
755 fkdd2 | "RI_FKey_cascade_del" | 9 | f | f
756 fkdd2 | "RI_FKey_noaction_upd" | 17 | t | t
757 fkdi | "RI_FKey_cascade_del" | 9 | f | f
758 fkdi | "RI_FKey_noaction_upd" | 17 | t | f
759 fkdi2 | "RI_FKey_cascade_del" | 9 | f | f
760 fkdi2 | "RI_FKey_noaction_upd" | 17 | t | f
761 fknd | "RI_FKey_cascade_del" | 9 | f | f
762 fknd | "RI_FKey_noaction_upd" | 17 | f | f
763 fknd2 | "RI_FKey_cascade_del" | 9 | f | f
764 fknd2 | "RI_FKey_noaction_upd" | 17 | f | f
767 SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred
768 FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint
769 WHERE tgrelid = 'fktable'::regclass
771 conname | tgfoid | tgtype | tgdeferrable | tginitdeferred
772 ---------+---------------------+--------+--------------+----------------
773 fkdd | "RI_FKey_check_ins" | 5 | t | t
774 fkdd | "RI_FKey_check_upd" | 17 | t | t
775 fkdd2 | "RI_FKey_check_ins" | 5 | t | t
776 fkdd2 | "RI_FKey_check_upd" | 17 | t | t
777 fkdi | "RI_FKey_check_ins" | 5 | t | f
778 fkdi | "RI_FKey_check_upd" | 17 | t | f
779 fkdi2 | "RI_FKey_check_ins" | 5 | t | f
780 fkdi2 | "RI_FKey_check_upd" | 17 | t | f
781 fknd | "RI_FKey_check_ins" | 5 | f | f
782 fknd | "RI_FKey_check_upd" | 17 | f | f
783 fknd2 | "RI_FKey_check_ins" | 5 | f | f
784 fknd2 | "RI_FKey_check_upd" | 17 | f | f
787 -- temp tables should go away by themselves, need not drop them.
788 -- test check constraint adding
789 create table atacc1 ( test int );
790 -- add a check constraint
791 alter table atacc1 add constraint atacc_test1 check (test>3);
793 insert into atacc1 (test) values (2);
794 ERROR: new row for relation "atacc1" violates check constraint "atacc_test1"
795 DETAIL: Failing row contains (2).
797 insert into atacc1 (test) values (4);
799 -- let's do one where the check fails when added
800 create table atacc1 ( test int );
801 -- insert a soon to be failing row
802 insert into atacc1 (test) values (2);
803 -- add a check constraint (fails)
804 alter table atacc1 add constraint atacc_test1 check (test>3);
805 ERROR: check constraint "atacc_test1" of relation "atacc1" is violated by some row
806 insert into atacc1 (test) values (4);
808 -- let's do one where the check fails because the column doesn't exist
809 create table atacc1 ( test int );
810 -- add a check constraint (fails)
811 alter table atacc1 add constraint atacc_test1 check (test1>3);
812 ERROR: column "test1" does not exist
813 HINT: Perhaps you meant to reference the column "atacc1.test".
815 -- something a little more complicated
816 create table atacc1 ( test int, test2 int, test3 int);
817 -- add a check constraint (fails)
818 alter table atacc1 add constraint atacc_test1 check (test+test2<test3*4);
820 insert into atacc1 (test,test2,test3) values (4,4,2);
821 ERROR: new row for relation "atacc1" violates check constraint "atacc_test1"
822 DETAIL: Failing row contains (4, 4, 2).
824 insert into atacc1 (test,test2,test3) values (4,4,5);
826 -- lets do some naming tests
827 create table atacc1 (test int check (test>3), test2 int);
828 alter table atacc1 add check (test2>test);
829 -- should fail for $2
830 insert into atacc1 (test2, test) values (3, 4);
831 ERROR: new row for relation "atacc1" violates check constraint "atacc1_check"
832 DETAIL: Failing row contains (4, 3).
834 -- inheritance related tests
835 create table atacc1 (test int);
836 create table atacc2 (test2 int);
837 create table atacc3 (test3 int) inherits (atacc1, atacc2);
838 alter table atacc2 add constraint foo check (test2>0);
839 -- fail and then succeed on atacc2
840 insert into atacc2 (test2) values (-3);
841 ERROR: new row for relation "atacc2" violates check constraint "foo"
842 DETAIL: Failing row contains (-3).
843 insert into atacc2 (test2) values (3);
844 -- fail and then succeed on atacc3
845 insert into atacc3 (test2) values (-3);
846 ERROR: new row for relation "atacc3" violates check constraint "foo"
847 DETAIL: Failing row contains (null, -3, null).
848 insert into atacc3 (test2) values (3);
852 -- same things with one created with INHERIT
853 create table atacc1 (test int);
854 create table atacc2 (test2 int);
855 create table atacc3 (test3 int) inherits (atacc1, atacc2);
856 alter table atacc3 no inherit atacc2;
858 alter table atacc3 no inherit atacc2;
859 ERROR: relation "atacc2" is not a parent of relation "atacc3"
860 -- make sure it really isn't a child
861 insert into atacc3 (test2) values (3);
862 select test2 from atacc2;
867 -- fail due to missing constraint
868 alter table atacc2 add constraint foo check (test2>0);
869 alter table atacc3 inherit atacc2;
870 ERROR: child table is missing constraint "foo"
871 -- fail due to missing column
872 alter table atacc3 rename test2 to testx;
873 alter table atacc3 inherit atacc2;
874 ERROR: child table is missing column "test2"
875 -- fail due to mismatched data type
876 alter table atacc3 add test2 bool;
877 alter table atacc3 inherit atacc2;
878 ERROR: child table "atacc3" has different type for column "test2"
879 alter table atacc3 drop test2;
881 alter table atacc3 add test2 int;
882 update atacc3 set test2 = 4 where test2 is null;
883 alter table atacc3 add constraint foo check (test2>0);
884 alter table atacc3 inherit atacc2;
885 -- fail due to duplicates and circular inheritance
886 alter table atacc3 inherit atacc2;
887 ERROR: relation "atacc2" would be inherited from more than once
888 alter table atacc2 inherit atacc3;
889 ERROR: circular inheritance not allowed
890 DETAIL: "atacc3" is already a child of "atacc2".
891 alter table atacc2 inherit atacc2;
892 ERROR: circular inheritance not allowed
893 DETAIL: "atacc2" is already a child of "atacc2".
894 -- test that we really are a child now (should see 4 not 3 and cascade should go through)
895 select test2 from atacc2;
901 drop table atacc2 cascade;
902 NOTICE: drop cascades to table atacc3
904 -- adding only to a parent is allowed as of 9.2
905 create table atacc1 (test int);
906 create table atacc2 (test2 int) inherits (atacc1);
908 alter table atacc1 add constraint foo check (test>0) no inherit;
909 -- check constraint is not there on child
910 insert into atacc2 (test) values (-3);
911 -- check constraint is there on parent
912 insert into atacc1 (test) values (-3);
913 ERROR: new row for relation "atacc1" violates check constraint "foo"
914 DETAIL: Failing row contains (-3).
915 insert into atacc1 (test) values (3);
916 -- fail, violating row:
917 alter table atacc2 add constraint foo check (test>0) no inherit;
918 ERROR: check constraint "foo" of relation "atacc2" is violated by some row
921 -- test unique constraint adding
922 create table atacc1 ( test int ) ;
923 -- add a unique constraint
924 alter table atacc1 add constraint atacc_test1 unique (test);
925 -- insert first value
926 insert into atacc1 (test) values (2);
928 insert into atacc1 (test) values (2);
929 ERROR: duplicate key value violates unique constraint "atacc_test1"
930 DETAIL: Key (test)=(2) already exists.
932 insert into atacc1 (test) values (4);
933 -- try to create duplicates via alter table using - should fail
934 alter table atacc1 alter column test type integer using 0;
935 ERROR: could not create unique index "atacc_test1"
936 DETAIL: Key (test)=(0) is duplicated.
938 -- let's do one where the unique constraint fails when added
939 create table atacc1 ( test int );
940 -- insert soon to be failing rows
941 insert into atacc1 (test) values (2);
942 insert into atacc1 (test) values (2);
943 -- add a unique constraint (fails)
944 alter table atacc1 add constraint atacc_test1 unique (test);
945 ERROR: could not create unique index "atacc_test1"
946 DETAIL: Key (test)=(2) is duplicated.
947 insert into atacc1 (test) values (3);
949 -- let's do one where the unique constraint fails
950 -- because the column doesn't exist
951 create table atacc1 ( test int );
952 -- add a unique constraint (fails)
953 alter table atacc1 add constraint atacc_test1 unique (test1);
954 ERROR: column "test1" named in key does not exist
956 -- something a little more complicated
957 create table atacc1 ( test int, test2 int);
958 -- add a unique constraint
959 alter table atacc1 add constraint atacc_test1 unique (test, test2);
960 -- insert initial value
961 insert into atacc1 (test,test2) values (4,4);
963 insert into atacc1 (test,test2) values (4,4);
964 ERROR: duplicate key value violates unique constraint "atacc_test1"
965 DETAIL: Key (test, test2)=(4, 4) already exists.
966 -- should all succeed
967 insert into atacc1 (test,test2) values (4,5);
968 insert into atacc1 (test,test2) values (5,4);
969 insert into atacc1 (test,test2) values (5,5);
971 -- lets do some naming tests
972 create table atacc1 (test int, test2 int, unique(test));
973 alter table atacc1 add unique (test2);
974 -- should fail for @@ second one @@
975 insert into atacc1 (test2, test) values (3, 3);
976 insert into atacc1 (test2, test) values (2, 3);
977 ERROR: duplicate key value violates unique constraint "atacc1_test_key"
978 DETAIL: Key (test)=(3) already exists.
980 -- test primary key constraint adding
981 create table atacc1 ( id serial, test int) ;
982 -- add a primary key constraint
983 alter table atacc1 add constraint atacc_test1 primary key (test);
984 -- insert first value
985 insert into atacc1 (test) values (2);
987 insert into atacc1 (test) values (2);
988 ERROR: duplicate key value violates unique constraint "atacc_test1"
989 DETAIL: Key (test)=(2) already exists.
991 insert into atacc1 (test) values (4);
992 -- inserting NULL should fail
993 insert into atacc1 (test) values(NULL);
994 ERROR: null value in column "test" of relation "atacc1" violates not-null constraint
995 DETAIL: Failing row contains (4, null).
996 -- try adding a second primary key (should fail)
997 alter table atacc1 add constraint atacc_oid1 primary key(id);
998 ERROR: multiple primary keys for table "atacc1" are not allowed
999 -- drop first primary key constraint
1000 alter table atacc1 drop constraint atacc_test1 restrict;
1001 -- try adding a primary key on oid (should succeed)
1002 alter table atacc1 add constraint atacc_oid1 primary key(id);
1004 -- let's do one where the primary key constraint fails when added
1005 create table atacc1 ( test int );
1006 -- insert soon to be failing rows
1007 insert into atacc1 (test) values (2);
1008 insert into atacc1 (test) values (2);
1009 -- add a primary key (fails)
1010 alter table atacc1 add constraint atacc_test1 primary key (test);
1011 ERROR: could not create unique index "atacc_test1"
1012 DETAIL: Key (test)=(2) is duplicated.
1013 insert into atacc1 (test) values (3);
1015 -- let's do another one where the primary key constraint fails when added
1016 create table atacc1 ( test int );
1017 -- insert soon to be failing row
1018 insert into atacc1 (test) values (NULL);
1019 -- add a primary key (fails)
1020 alter table atacc1 add constraint atacc_test1 primary key (test);
1021 ERROR: column "test" of relation "atacc1" contains null values
1022 insert into atacc1 (test) values (3);
1024 -- let's do one where the primary key constraint fails
1025 -- because the column doesn't exist
1026 create table atacc1 ( test int );
1027 -- add a primary key constraint (fails)
1028 alter table atacc1 add constraint atacc_test1 primary key (test1);
1029 ERROR: column "test1" of relation "atacc1" does not exist
1031 -- adding a new column as primary key to a non-empty table.
1032 -- should fail unless the column has a non-null default value.
1033 create table atacc1 ( test int );
1034 insert into atacc1 (test) values (0);
1035 -- add a primary key column without a default (fails).
1036 alter table atacc1 add column test2 int primary key;
1037 ERROR: column "test2" of relation "atacc1" contains null values
1038 -- now add a primary key column with a default (succeeds).
1039 alter table atacc1 add column test2 int default 0 primary key;
1041 -- this combination used to have order-of-execution problems (bug #15580)
1042 create table atacc1 (a int);
1043 insert into atacc1 values(1);
1045 add column b float8 not null default random(),
1048 -- additionally, we've seen issues with foreign key validation not being
1049 -- properly delayed until after a table rewrite. Check that works ok.
1050 create table atacc1 (a int primary key);
1051 alter table atacc1 add constraint atacc1_fkey foreign key (a) references atacc1 (a) not valid;
1052 alter table atacc1 validate constraint atacc1_fkey, alter a type bigint;
1054 -- we've also seen issues with check constraints being validated at the wrong
1055 -- time when there's a pending table rewrite.
1056 create table atacc1 (a bigint, b int);
1057 insert into atacc1 values(1,1);
1058 alter table atacc1 add constraint atacc1_chk check(b = 1) not valid;
1059 alter table atacc1 validate constraint atacc1_chk, alter a type int;
1061 -- same as above, but ensure the constraint violation is detected
1062 create table atacc1 (a bigint, b int);
1063 insert into atacc1 values(1,2);
1064 alter table atacc1 add constraint atacc1_chk check(b = 1) not valid;
1065 alter table atacc1 validate constraint atacc1_chk, alter a type int;
1066 ERROR: check constraint "atacc1_chk" of relation "atacc1" is violated by some row
1068 -- something a little more complicated
1069 create table atacc1 ( test int, test2 int);
1070 -- add a primary key constraint
1071 alter table atacc1 add constraint atacc_test1 primary key (test, test2);
1072 -- try adding a second primary key - should fail
1073 alter table atacc1 add constraint atacc_test2 primary key (test);
1074 ERROR: multiple primary keys for table "atacc1" are not allowed
1075 -- insert initial value
1076 insert into atacc1 (test,test2) values (4,4);
1078 insert into atacc1 (test,test2) values (4,4);
1079 ERROR: duplicate key value violates unique constraint "atacc_test1"
1080 DETAIL: Key (test, test2)=(4, 4) already exists.
1081 insert into atacc1 (test,test2) values (NULL,3);
1082 ERROR: null value in column "test" of relation "atacc1" violates not-null constraint
1083 DETAIL: Failing row contains (null, 3).
1084 insert into atacc1 (test,test2) values (3, NULL);
1085 ERROR: null value in column "test2" of relation "atacc1" violates not-null constraint
1086 DETAIL: Failing row contains (3, null).
1087 insert into atacc1 (test,test2) values (NULL,NULL);
1088 ERROR: null value in column "test" of relation "atacc1" violates not-null constraint
1089 DETAIL: Failing row contains (null, null).
1090 -- should all succeed
1091 insert into atacc1 (test,test2) values (4,5);
1092 insert into atacc1 (test,test2) values (5,4);
1093 insert into atacc1 (test,test2) values (5,5);
1095 -- lets do some naming tests
1096 create table atacc1 (test int, test2 int, primary key(test));
1097 -- only first should succeed
1098 insert into atacc1 (test2, test) values (3, 3);
1099 insert into atacc1 (test2, test) values (2, 3);
1100 ERROR: duplicate key value violates unique constraint "atacc1_pkey"
1101 DETAIL: Key (test)=(3) already exists.
1102 insert into atacc1 (test2, test) values (1, NULL);
1103 ERROR: null value in column "test" of relation "atacc1" violates not-null constraint
1104 DETAIL: Failing row contains (null, 1).
1106 -- alter table / alter column [set/drop] not null tests
1107 -- try altering system catalogs, should fail
1108 alter table pg_class alter column relname drop not null;
1109 ERROR: permission denied: "pg_class" is a system catalog
1110 alter table pg_class alter relname set not null;
1111 ERROR: permission denied: "pg_class" is a system catalog
1112 -- try altering non-existent table, should fail
1113 alter table non_existent alter column bar set not null;
1114 ERROR: relation "non_existent" does not exist
1115 alter table non_existent alter column bar drop not null;
1116 ERROR: relation "non_existent" does not exist
1117 -- test setting columns to null and not null and vice versa
1118 -- test checking for null values and primary key
1119 create table atacc1 (test int not null);
1120 alter table atacc1 add constraint "atacc1_pkey" primary key (test);
1122 Table "public.atacc1"
1123 Column | Type | Collation | Nullable | Default
1124 --------+---------+-----------+----------+---------
1125 test | integer | | not null |
1127 "atacc1_pkey" PRIMARY KEY, btree (test)
1129 alter table atacc1 alter column test drop not null;
1130 ERROR: column "test" is in a primary key
1132 Table "public.atacc1"
1133 Column | Type | Collation | Nullable | Default
1134 --------+---------+-----------+----------+---------
1135 test | integer | | not null |
1137 "atacc1_pkey" PRIMARY KEY, btree (test)
1139 alter table atacc1 drop constraint "atacc1_pkey";
1140 alter table atacc1 alter column test drop not null;
1142 Table "public.atacc1"
1143 Column | Type | Collation | Nullable | Default
1144 --------+---------+-----------+----------+---------
1145 test | integer | | |
1147 insert into atacc1 values (null);
1148 alter table atacc1 alter test set not null;
1149 ERROR: column "test" of relation "atacc1" contains null values
1151 alter table atacc1 alter test set not null;
1152 -- try altering a non-existent column, should fail
1153 alter table atacc1 alter bar set not null;
1154 ERROR: column "bar" of relation "atacc1" does not exist
1155 alter table atacc1 alter bar drop not null;
1156 ERROR: column "bar" of relation "atacc1" does not exist
1157 -- try creating a view and altering that, should fail
1158 create view myview as select * from atacc1;
1159 alter table myview alter column test drop not null;
1160 ERROR: ALTER action ALTER COLUMN ... DROP NOT NULL cannot be performed on relation "myview"
1161 DETAIL: This operation is not supported for views.
1162 alter table myview alter column test set not null;
1163 ERROR: ALTER action ALTER COLUMN ... SET NOT NULL cannot be performed on relation "myview"
1164 DETAIL: This operation is not supported for views.
1167 -- set not null verified by constraints
1168 create table atacc1 (test_a int, test_b int);
1169 insert into atacc1 values (null, 1);
1170 -- constraint not cover all values, should fail
1171 alter table atacc1 add constraint atacc1_constr_or check(test_a is not null or test_b < 10);
1172 alter table atacc1 alter test_a set not null;
1173 ERROR: column "test_a" of relation "atacc1" contains null values
1174 alter table atacc1 drop constraint atacc1_constr_or;
1175 -- not valid constraint, should fail
1176 alter table atacc1 add constraint atacc1_constr_invalid check(test_a is not null) not valid;
1177 alter table atacc1 alter test_a set not null;
1178 ERROR: column "test_a" of relation "atacc1" contains null values
1179 alter table atacc1 drop constraint atacc1_constr_invalid;
1180 -- with valid constraint
1181 update atacc1 set test_a = 1;
1182 alter table atacc1 add constraint atacc1_constr_a_valid check(test_a is not null);
1183 alter table atacc1 alter test_a set not null;
1185 insert into atacc1 values (2, null);
1186 alter table atacc1 alter test_a drop not null;
1187 -- test multiple set not null at same time
1188 -- test_a checked by atacc1_constr_a_valid, test_b should fail by table scan
1189 alter table atacc1 alter test_a set not null, alter test_b set not null;
1190 ERROR: column "test_b" of relation "atacc1" contains null values
1191 -- commands order has no importance
1192 alter table atacc1 alter test_b set not null, alter test_a set not null;
1193 ERROR: column "test_b" of relation "atacc1" contains null values
1194 -- valid one by table scan, one by check constraints
1195 update atacc1 set test_b = 1;
1196 alter table atacc1 alter test_b set not null, alter test_a set not null;
1197 alter table atacc1 alter test_a drop not null, alter test_b drop not null;
1198 -- both column has check constraints
1199 alter table atacc1 add constraint atacc1_constr_b_valid check(test_b is not null);
1200 alter table atacc1 alter test_b set not null, alter test_a set not null;
1203 create table parent (a int);
1204 create table child (b varchar(255)) inherits (parent);
1205 alter table parent alter a set not null;
1206 insert into parent values (NULL);
1207 ERROR: null value in column "a" of relation "parent" violates not-null constraint
1208 DETAIL: Failing row contains (null).
1209 insert into child (a, b) values (NULL, 'foo');
1210 ERROR: null value in column "a" of relation "child" violates not-null constraint
1211 DETAIL: Failing row contains (null, foo).
1212 alter table parent alter a drop not null;
1213 insert into parent values (NULL);
1214 insert into child (a, b) values (NULL, 'foo');
1215 alter table only parent alter a set not null;
1216 ERROR: column "a" of relation "parent" contains null values
1217 alter table child alter a set not null;
1218 ERROR: column "a" of relation "child" contains null values
1221 -- test setting and removing default values
1222 create table def_test (
1224 c2 text default 'initial_default'
1226 insert into def_test default values;
1227 alter table def_test alter column c1 drop default;
1228 insert into def_test default values;
1229 alter table def_test alter column c2 drop default;
1230 insert into def_test default values;
1231 alter table def_test alter column c1 set default 10;
1232 alter table def_test alter column c2 set default 'new_default';
1233 insert into def_test default values;
1234 select * from def_test;
1236 ----+-----------------
1243 -- set defaults to an incorrect type: this should fail
1244 alter table def_test alter column c1 set default 'wrong_datatype';
1245 ERROR: invalid input syntax for type integer: "wrong_datatype"
1246 alter table def_test alter column c2 set default 20;
1247 -- set defaults on a non-existent column: this should fail
1248 alter table def_test alter column c3 set default 30;
1249 ERROR: column "c3" of relation "def_test" does not exist
1250 -- set defaults on views: we need to create a view, add a rule
1251 -- to allow insertions into it, and then alter the view to add
1253 create view def_view_test as select * from def_test;
1254 create rule def_view_test_ins as
1255 on insert to def_view_test
1256 do instead insert into def_test select new.*;
1257 insert into def_view_test default values;
1258 alter table def_view_test alter column c1 set default 45;
1259 insert into def_view_test default values;
1260 alter table def_view_test alter column c2 set default 'view_default';
1261 insert into def_view_test default values;
1262 select * from def_view_test;
1264 ----+-----------------
1274 drop rule def_view_test_ins on def_view_test;
1275 drop view def_view_test;
1276 drop table def_test;
1277 -- alter table / drop column tests
1278 -- try altering system catalogs, should fail
1279 alter table pg_class drop column relname;
1280 ERROR: permission denied: "pg_class" is a system catalog
1281 -- try altering non-existent table, should fail
1282 alter table nosuchtable drop column bar;
1283 ERROR: relation "nosuchtable" does not exist
1284 -- test dropping columns
1285 create table atacc1 (a int4 not null, b int4, c int4 not null, d int4);
1286 insert into atacc1 values (1, 2, 3, 4);
1287 alter table atacc1 drop a;
1288 alter table atacc1 drop a;
1289 ERROR: column "a" of relation "atacc1" does not exist
1291 select * from atacc1;
1297 select * from atacc1 order by a;
1298 ERROR: column "a" does not exist
1299 LINE 1: select * from atacc1 order by a;
1301 select * from atacc1 order by "........pg.dropped.1........";
1302 ERROR: column "........pg.dropped.1........" does not exist
1303 LINE 1: select * from atacc1 order by "........pg.dropped.1........"...
1305 select * from atacc1 group by a;
1306 ERROR: column "a" does not exist
1307 LINE 1: select * from atacc1 group by a;
1309 select * from atacc1 group by "........pg.dropped.1........";
1310 ERROR: column "........pg.dropped.1........" does not exist
1311 LINE 1: select * from atacc1 group by "........pg.dropped.1........"...
1313 select atacc1.* from atacc1;
1319 select a from atacc1;
1320 ERROR: column "a" does not exist
1321 LINE 1: select a from atacc1;
1323 select atacc1.a from atacc1;
1324 ERROR: column atacc1.a does not exist
1325 LINE 1: select atacc1.a from atacc1;
1327 select b,c,d from atacc1;
1333 select a,b,c,d from atacc1;
1334 ERROR: column "a" does not exist
1335 LINE 1: select a,b,c,d from atacc1;
1337 select * from atacc1 where a = 1;
1338 ERROR: column "a" does not exist
1339 LINE 1: select * from atacc1 where a = 1;
1341 select "........pg.dropped.1........" from atacc1;
1342 ERROR: column "........pg.dropped.1........" does not exist
1343 LINE 1: select "........pg.dropped.1........" from atacc1;
1345 select atacc1."........pg.dropped.1........" from atacc1;
1346 ERROR: column atacc1.........pg.dropped.1........ does not exist
1347 LINE 1: select atacc1."........pg.dropped.1........" from atacc1;
1349 select "........pg.dropped.1........",b,c,d from atacc1;
1350 ERROR: column "........pg.dropped.1........" does not exist
1351 LINE 1: select "........pg.dropped.1........",b,c,d from atacc1;
1353 select * from atacc1 where "........pg.dropped.1........" = 1;
1354 ERROR: column "........pg.dropped.1........" does not exist
1355 LINE 1: select * from atacc1 where "........pg.dropped.1........" = ...
1358 update atacc1 set a = 3;
1359 ERROR: column "a" of relation "atacc1" does not exist
1360 LINE 1: update atacc1 set a = 3;
1362 update atacc1 set b = 2 where a = 3;
1363 ERROR: column "a" does not exist
1364 LINE 1: update atacc1 set b = 2 where a = 3;
1366 update atacc1 set "........pg.dropped.1........" = 3;
1367 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1368 LINE 1: update atacc1 set "........pg.dropped.1........" = 3;
1370 update atacc1 set b = 2 where "........pg.dropped.1........" = 3;
1371 ERROR: column "........pg.dropped.1........" does not exist
1372 LINE 1: update atacc1 set b = 2 where "........pg.dropped.1........"...
1375 insert into atacc1 values (10, 11, 12, 13);
1376 ERROR: INSERT has more expressions than target columns
1377 LINE 1: insert into atacc1 values (10, 11, 12, 13);
1379 insert into atacc1 values (default, 11, 12, 13);
1380 ERROR: INSERT has more expressions than target columns
1381 LINE 1: insert into atacc1 values (default, 11, 12, 13);
1383 insert into atacc1 values (11, 12, 13);
1384 insert into atacc1 (a) values (10);
1385 ERROR: column "a" of relation "atacc1" does not exist
1386 LINE 1: insert into atacc1 (a) values (10);
1388 insert into atacc1 (a) values (default);
1389 ERROR: column "a" of relation "atacc1" does not exist
1390 LINE 1: insert into atacc1 (a) values (default);
1392 insert into atacc1 (a,b,c,d) values (10,11,12,13);
1393 ERROR: column "a" of relation "atacc1" does not exist
1394 LINE 1: insert into atacc1 (a,b,c,d) values (10,11,12,13);
1396 insert into atacc1 (a,b,c,d) values (default,11,12,13);
1397 ERROR: column "a" of relation "atacc1" does not exist
1398 LINE 1: insert into atacc1 (a,b,c,d) values (default,11,12,13);
1400 insert into atacc1 (b,c,d) values (11,12,13);
1401 insert into atacc1 ("........pg.dropped.1........") values (10);
1402 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1403 LINE 1: insert into atacc1 ("........pg.dropped.1........") values (...
1405 insert into atacc1 ("........pg.dropped.1........") values (default);
1406 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1407 LINE 1: insert into atacc1 ("........pg.dropped.1........") values (...
1409 insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13);
1410 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1411 LINE 1: insert into atacc1 ("........pg.dropped.1........",b,c,d) va...
1413 insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13);
1414 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1415 LINE 1: insert into atacc1 ("........pg.dropped.1........",b,c,d) va...
1418 delete from atacc1 where a = 3;
1419 ERROR: column "a" does not exist
1420 LINE 1: delete from atacc1 where a = 3;
1422 delete from atacc1 where "........pg.dropped.1........" = 3;
1423 ERROR: column "........pg.dropped.1........" does not exist
1424 LINE 1: delete from atacc1 where "........pg.dropped.1........" = 3;
1427 -- try dropping a non-existent column, should fail
1428 alter table atacc1 drop bar;
1429 ERROR: column "bar" of relation "atacc1" does not exist
1430 -- try removing an oid column, should succeed (as it's nonexistent)
1431 alter table atacc1 SET WITHOUT OIDS;
1432 -- try adding an oid column, should fail (not supported)
1433 alter table atacc1 SET WITH OIDS;
1434 ERROR: syntax error at or near "WITH"
1435 LINE 1: alter table atacc1 SET WITH OIDS;
1437 -- try dropping the xmin column, should fail
1438 alter table atacc1 drop xmin;
1439 ERROR: cannot drop system column "xmin"
1440 -- try creating a view and altering that, should fail
1441 create view myview as select * from atacc1;
1442 select * from myview;
1447 alter table myview drop d;
1448 ERROR: ALTER action DROP COLUMN cannot be performed on relation "myview"
1449 DETAIL: This operation is not supported for views.
1451 -- test some commands to make sure they fail on the dropped column
1453 ERROR: column "a" of relation "atacc1" does not exist
1454 analyze atacc1("........pg.dropped.1........");
1455 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1456 vacuum analyze atacc1(a);
1457 ERROR: column "a" of relation "atacc1" does not exist
1458 vacuum analyze atacc1("........pg.dropped.1........");
1459 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1460 comment on column atacc1.a is 'testing';
1461 ERROR: column "a" of relation "atacc1" does not exist
1462 comment on column atacc1."........pg.dropped.1........" is 'testing';
1463 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1464 alter table atacc1 alter a set storage plain;
1465 ERROR: column "a" of relation "atacc1" does not exist
1466 alter table atacc1 alter "........pg.dropped.1........" set storage plain;
1467 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1468 alter table atacc1 alter a set statistics 0;
1469 ERROR: column "a" of relation "atacc1" does not exist
1470 alter table atacc1 alter "........pg.dropped.1........" set statistics 0;
1471 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1472 alter table atacc1 alter a set default 3;
1473 ERROR: column "a" of relation "atacc1" does not exist
1474 alter table atacc1 alter "........pg.dropped.1........" set default 3;
1475 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1476 alter table atacc1 alter a drop default;
1477 ERROR: column "a" of relation "atacc1" does not exist
1478 alter table atacc1 alter "........pg.dropped.1........" drop default;
1479 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1480 alter table atacc1 alter a set not null;
1481 ERROR: column "a" of relation "atacc1" does not exist
1482 alter table atacc1 alter "........pg.dropped.1........" set not null;
1483 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1484 alter table atacc1 alter a drop not null;
1485 ERROR: column "a" of relation "atacc1" does not exist
1486 alter table atacc1 alter "........pg.dropped.1........" drop not null;
1487 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1488 alter table atacc1 rename a to x;
1489 ERROR: column "a" does not exist
1490 alter table atacc1 rename "........pg.dropped.1........" to x;
1491 ERROR: column "........pg.dropped.1........" does not exist
1492 alter table atacc1 add primary key(a);
1493 ERROR: column "a" of relation "atacc1" does not exist
1494 alter table atacc1 add primary key("........pg.dropped.1........");
1495 ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
1496 alter table atacc1 add unique(a);
1497 ERROR: column "a" named in key does not exist
1498 alter table atacc1 add unique("........pg.dropped.1........");
1499 ERROR: column "........pg.dropped.1........" named in key does not exist
1500 alter table atacc1 add check (a > 3);
1501 ERROR: column "a" does not exist
1502 alter table atacc1 add check ("........pg.dropped.1........" > 3);
1503 ERROR: column "........pg.dropped.1........" does not exist
1504 create table atacc2 (id int4 unique);
1505 alter table atacc1 add foreign key (a) references atacc2(id);
1506 ERROR: column "a" referenced in foreign key constraint does not exist
1507 alter table atacc1 add foreign key ("........pg.dropped.1........") references atacc2(id);
1508 ERROR: column "........pg.dropped.1........" referenced in foreign key constraint does not exist
1509 alter table atacc2 add foreign key (id) references atacc1(a);
1510 ERROR: column "a" referenced in foreign key constraint does not exist
1511 alter table atacc2 add foreign key (id) references atacc1("........pg.dropped.1........");
1512 ERROR: column "........pg.dropped.1........" referenced in foreign key constraint does not exist
1514 create index "testing_idx" on atacc1(a);
1515 ERROR: column "a" does not exist
1516 create index "testing_idx" on atacc1("........pg.dropped.1........");
1517 ERROR: column "........pg.dropped.1........" does not exist
1518 -- test create as and select into
1519 insert into atacc1 values (21, 22, 23);
1520 create table attest1 as select * from atacc1;
1521 select * from attest1;
1528 select * into attest2 from atacc1;
1529 select * from attest2;
1536 -- try dropping all columns
1537 alter table atacc1 drop c;
1538 alter table atacc1 drop d;
1539 alter table atacc1 drop b;
1540 select * from atacc1;
1545 -- test constraint error reporting in presence of dropped columns
1546 create table atacc1 (id serial primary key, value int check (value < 10));
1547 insert into atacc1(value) values (100);
1548 ERROR: new row for relation "atacc1" violates check constraint "atacc1_value_check"
1549 DETAIL: Failing row contains (1, 100).
1550 alter table atacc1 drop column value;
1551 alter table atacc1 add column value int check (value < 10);
1552 insert into atacc1(value) values (100);
1553 ERROR: new row for relation "atacc1" violates check constraint "atacc1_value_check"
1554 DETAIL: Failing row contains (2, 100).
1555 insert into atacc1(id, value) values (null, 0);
1556 ERROR: null value in column "id" of relation "atacc1" violates not-null constraint
1557 DETAIL: Failing row contains (null, 0).
1560 create table parent (a int, b int, c int);
1561 insert into parent values (1, 2, 3);
1562 alter table parent drop a;
1563 create table child (d varchar(255)) inherits (parent);
1564 insert into child values (12, 13, 'testing');
1565 select * from parent;
1572 select * from child;
1578 alter table parent drop c;
1579 select * from parent;
1586 select * from child;
1594 -- check error cases for inheritance column merging
1595 create table parent (a float8, b numeric(10,4), c text collate "C");
1596 create table child (a float4) inherits (parent); -- fail
1597 NOTICE: merging column "a" with inherited definition
1598 ERROR: column "a" has a type conflict
1599 DETAIL: double precision versus real
1600 create table child (b decimal(10,7)) inherits (parent); -- fail
1601 NOTICE: moving and merging column "b" with inherited definition
1602 DETAIL: User-specified column moved to the position of the inherited column.
1603 ERROR: column "b" has a type conflict
1604 DETAIL: numeric(10,4) versus numeric(10,7)
1605 create table child (c text collate "POSIX") inherits (parent); -- fail
1606 NOTICE: moving and merging column "c" with inherited definition
1607 DETAIL: User-specified column moved to the position of the inherited column.
1608 ERROR: column "c" has a collation conflict
1609 DETAIL: "C" versus "POSIX"
1610 create table child (a double precision, b decimal(10,4)) inherits (parent);
1611 NOTICE: merging column "a" with inherited definition
1612 NOTICE: merging column "b" with inherited definition
1616 create table attest (a int4, b int4, c int4);
1617 insert into attest values (1,2,3);
1618 alter table attest drop a;
1619 copy attest to stdout;
1621 copy attest(a) to stdout;
1622 ERROR: column "a" of relation "attest" does not exist
1623 copy attest("........pg.dropped.1........") to stdout;
1624 ERROR: column "........pg.dropped.1........" of relation "attest" does not exist
1625 copy attest from stdin;
1626 ERROR: extra data after last expected column
1627 CONTEXT: COPY attest, line 1: "10 11 12"
1628 select * from attest;
1634 copy attest from stdin;
1635 select * from attest;
1642 copy attest(a) from stdin;
1643 ERROR: column "a" of relation "attest" does not exist
1644 copy attest("........pg.dropped.1........") from stdin;
1645 ERROR: column "........pg.dropped.1........" of relation "attest" does not exist
1646 copy attest(b,c) from stdin;
1647 select * from attest;
1657 create table dropColumn (a int, b int, e int);
1658 create table dropColumnChild (c int) inherits (dropColumn);
1659 create table dropColumnAnother (d int) inherits (dropColumnChild);
1660 -- these two should fail
1661 alter table dropColumnchild drop column a;
1662 ERROR: cannot drop inherited column "a"
1663 alter table only dropColumnChild drop column b;
1664 ERROR: cannot drop inherited column "b"
1665 -- these three should work
1666 alter table only dropColumn drop column e;
1667 alter table dropColumnChild drop column c;
1668 alter table dropColumn drop column a;
1669 create table renameColumn (a int);
1670 create table renameColumnChild (b int) inherits (renameColumn);
1671 create table renameColumnAnother (c int) inherits (renameColumnChild);
1672 -- these three should fail
1673 alter table renameColumnChild rename column a to d;
1674 ERROR: cannot rename inherited column "a"
1675 alter table only renameColumnChild rename column a to d;
1676 ERROR: inherited column "a" must be renamed in child tables too
1677 alter table only renameColumn rename column a to d;
1678 ERROR: inherited column "a" must be renamed in child tables too
1679 -- these should work
1680 alter table renameColumn rename column a to d;
1681 alter table renameColumnChild rename column b to a;
1682 -- these should work
1683 alter table if exists doesnt_exist_tab rename column a to d;
1684 NOTICE: relation "doesnt_exist_tab" does not exist, skipping
1685 alter table if exists doesnt_exist_tab rename column b to a;
1686 NOTICE: relation "doesnt_exist_tab" does not exist, skipping
1688 alter table renameColumn add column w int;
1690 alter table only renameColumn add column x int;
1691 ERROR: column must be added to child tables too
1692 -- Test corner cases in dropping of inherited columns
1693 create table p1 (f1 int, f2 int);
1694 create table c1 (f1 int not null) inherits(p1);
1695 NOTICE: merging column "f1" with inherited definition
1696 -- should be rejected since c1.f1 is inherited
1697 alter table c1 drop column f1;
1698 ERROR: cannot drop inherited column "f1"
1700 alter table p1 drop column f1;
1701 -- c1.f1 is still there, but no longer inherited
1707 alter table c1 drop column f1;
1709 ERROR: column "f1" does not exist
1710 LINE 1: select f1 from c1;
1712 HINT: Perhaps you meant to reference the column "c1.f2".
1713 drop table p1 cascade;
1714 NOTICE: drop cascades to table c1
1715 create table p1 (f1 int, f2 int);
1716 create table c1 () inherits(p1);
1717 -- should be rejected since c1.f1 is inherited
1718 alter table c1 drop column f1;
1719 ERROR: cannot drop inherited column "f1"
1720 alter table p1 drop column f1;
1721 -- c1.f1 is dropped now, since there is no local definition for it
1723 ERROR: column "f1" does not exist
1724 LINE 1: select f1 from c1;
1726 HINT: Perhaps you meant to reference the column "c1.f2".
1727 drop table p1 cascade;
1728 NOTICE: drop cascades to table c1
1729 create table p1 (f1 int, f2 int);
1730 create table c1 () inherits(p1);
1731 -- should be rejected since c1.f1 is inherited
1732 alter table c1 drop column f1;
1733 ERROR: cannot drop inherited column "f1"
1734 alter table only p1 drop column f1;
1735 -- c1.f1 is NOT dropped, but must now be considered non-inherited
1736 alter table c1 drop column f1;
1737 drop table p1 cascade;
1738 NOTICE: drop cascades to table c1
1739 create table p1 (f1 int, f2 int);
1740 create table c1 (f1 int not null) inherits(p1);
1741 NOTICE: merging column "f1" with inherited definition
1742 -- should be rejected since c1.f1 is inherited
1743 alter table c1 drop column f1;
1744 ERROR: cannot drop inherited column "f1"
1745 alter table only p1 drop column f1;
1746 -- c1.f1 is still there, but no longer inherited
1747 alter table c1 drop column f1;
1748 drop table p1 cascade;
1749 NOTICE: drop cascades to table c1
1750 create table p1(id int, name text);
1751 create table p2(id2 int, name text, height int);
1752 create table c1(age int) inherits(p1,p2);
1753 NOTICE: merging multiple inherited definitions of column "name"
1754 create table gc1() inherits (c1);
1755 select relname, attname, attinhcount, attislocal
1756 from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid)
1757 where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped
1758 order by relname, attnum;
1759 relname | attname | attinhcount | attislocal
1760 ---------+---------+-------------+------------
1769 gc1 | height | 1 | f
1779 alter table only p1 drop column name;
1780 -- should work. Now c1.name is local and inhcount is 0.
1781 alter table p2 drop column name;
1782 -- should be rejected since its inherited
1783 alter table gc1 drop column name;
1784 ERROR: cannot drop inherited column "name"
1785 -- should work, and drop gc1.name along
1786 alter table c1 drop column name;
1787 -- should fail: column does not exist
1788 alter table gc1 drop column name;
1789 ERROR: column "name" of relation "gc1" does not exist
1790 -- should work and drop the attribute in all tables
1791 alter table p2 drop column height;
1793 create table dropColumnExists ();
1794 alter table dropColumnExists drop column non_existing; --fail
1795 ERROR: column "non_existing" of relation "dropcolumnexists" does not exist
1796 alter table dropColumnExists drop column if exists non_existing; --succeed
1797 NOTICE: column "non_existing" of relation "dropcolumnexists" does not exist, skipping
1798 select relname, attname, attinhcount, attislocal
1799 from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid)
1800 where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped
1801 order by relname, attnum;
1802 relname | attname | attinhcount | attislocal
1803 ---------+---------+-------------+------------
1814 drop table p1, p2 cascade;
1815 NOTICE: drop cascades to 2 other objects
1816 DETAIL: drop cascades to table c1
1817 drop cascades to table gc1
1818 -- test attinhcount tracking with merged columns
1819 create table depth0();
1820 create table depth1(c text) inherits (depth0);
1821 create table depth2() inherits (depth1);
1822 alter table depth0 add c text;
1823 NOTICE: merging definition of column "c" for child "depth1"
1824 select attrelid::regclass, attname, attinhcount, attislocal
1826 where attnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2')
1827 order by attrelid::regclass::text, attnum;
1828 attrelid | attname | attinhcount | attislocal
1829 ----------+---------+-------------+------------
1835 -- test renumbering of child-table columns in inherited operations
1836 create table p1 (f1 int);
1837 create table c1 (f2 text, f3 int) inherits (p1);
1838 alter table p1 add column a1 int check (a1 > 0);
1839 alter table p1 add column f2 text;
1840 NOTICE: merging definition of column "f2" for child "c1"
1841 insert into p1 values (1,2,'abc');
1842 insert into c1 values(11,'xyz',33,0); -- should fail
1843 ERROR: new row for relation "c1" violates check constraint "p1_a1_check"
1844 DETAIL: Failing row contains (11, xyz, 33, 0).
1845 insert into c1 values(11,'xyz',33,22);
1853 update p1 set a1 = a1 + 1, f2 = upper(f2);
1861 drop table p1 cascade;
1862 NOTICE: drop cascades to table c1
1863 -- test that operations with a dropped column do not try to reference
1865 create domain mytype as text;
1866 create temp table foo (f1 text, f2 mytype, f3 text);
1867 insert into foo values('bb','cc','dd');
1874 drop domain mytype cascade;
1875 NOTICE: drop cascades to column f2 of table foo
1882 insert into foo values('qq','rr');
1890 update foo set f3 = 'zz';
1898 select f3,max(f1) from foo group by f3;
1904 -- Simple tests for alter table column type
1905 alter table foo alter f1 TYPE integer; -- fails
1906 ERROR: column "f1" cannot be cast automatically to type integer
1907 HINT: You might need to specify "USING f1::integer".
1908 alter table foo alter f1 TYPE varchar(10);
1909 create table anothertab (atcol1 serial8, atcol2 boolean,
1910 constraint anothertab_chk check (atcol1 <= 3));
1911 insert into anothertab (atcol1, atcol2) values (default, true);
1912 insert into anothertab (atcol1, atcol2) values (default, false);
1913 select * from anothertab;
1920 alter table anothertab alter column atcol1 type boolean; -- fails
1921 ERROR: column "atcol1" cannot be cast automatically to type boolean
1922 HINT: You might need to specify "USING atcol1::boolean".
1923 alter table anothertab alter column atcol1 type boolean using atcol1::int; -- fails
1924 ERROR: result of USING clause for column "atcol1" cannot be cast automatically to type boolean
1925 HINT: You might need to add an explicit cast.
1926 alter table anothertab alter column atcol1 type integer;
1927 select * from anothertab;
1934 insert into anothertab (atcol1, atcol2) values (45, null); -- fails
1935 ERROR: new row for relation "anothertab" violates check constraint "anothertab_chk"
1936 DETAIL: Failing row contains (45, null).
1937 insert into anothertab (atcol1, atcol2) values (default, null);
1938 select * from anothertab;
1946 alter table anothertab alter column atcol2 type text
1947 using case when atcol2 is true then 'IT WAS TRUE'
1948 when atcol2 is false then 'IT WAS FALSE'
1949 else 'IT WAS NULL!' end;
1950 select * from anothertab;
1952 --------+--------------
1958 alter table anothertab alter column atcol1 type boolean
1959 using case when atcol1 % 2 = 0 then true else false end; -- fails
1960 ERROR: default for column "atcol1" cannot be cast automatically to type boolean
1961 alter table anothertab alter column atcol1 drop default;
1962 alter table anothertab alter column atcol1 type boolean
1963 using case when atcol1 % 2 = 0 then true else false end; -- fails
1964 ERROR: operator does not exist: boolean <= integer
1965 HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
1966 alter table anothertab drop constraint anothertab_chk;
1967 alter table anothertab drop constraint anothertab_chk; -- fails
1968 ERROR: constraint "anothertab_chk" of relation "anothertab" does not exist
1969 alter table anothertab drop constraint IF EXISTS anothertab_chk; -- succeeds
1970 NOTICE: constraint "anothertab_chk" of relation "anothertab" does not exist, skipping
1971 alter table anothertab alter column atcol1 type boolean
1972 using case when atcol1 % 2 = 0 then true else false end;
1973 select * from anothertab;
1975 --------+--------------
1981 drop table anothertab;
1982 -- Test index handling in alter table column type (cf. bugs #15835, #15865)
1983 create table anothertab(f1 int primary key, f2 int unique,
1984 f3 int, f4 int, f5 int);
1985 alter table anothertab
1986 add exclude using btree (f3 with =);
1987 alter table anothertab
1988 add exclude using btree (f4 with =) where (f4 is not null);
1989 alter table anothertab
1990 add exclude using btree (f4 with =) where (f5 > 0);
1991 alter table anothertab
1993 create index on anothertab(f2,f3);
1994 create unique index on anothertab(f4);
1996 Table "public.anothertab"
1997 Column | Type | Collation | Nullable | Default
1998 --------+---------+-----------+----------+---------
1999 f1 | integer | | not null |
2005 "anothertab_pkey" PRIMARY KEY, btree (f1)
2006 "anothertab_f1_f4_key" UNIQUE CONSTRAINT, btree (f1, f4)
2007 "anothertab_f2_f3_idx" btree (f2, f3)
2008 "anothertab_f2_key" UNIQUE CONSTRAINT, btree (f2)
2009 "anothertab_f3_excl" EXCLUDE USING btree (f3 WITH =)
2010 "anothertab_f4_excl" EXCLUDE USING btree (f4 WITH =) WHERE (f4 IS NOT NULL)
2011 "anothertab_f4_excl1" EXCLUDE USING btree (f4 WITH =) WHERE (f5 > 0)
2012 "anothertab_f4_idx" UNIQUE, btree (f4)
2014 alter table anothertab alter column f1 type bigint;
2015 alter table anothertab
2016 alter column f2 type bigint,
2017 alter column f3 type bigint,
2018 alter column f4 type bigint;
2019 alter table anothertab alter column f5 type bigint;
2021 Table "public.anothertab"
2022 Column | Type | Collation | Nullable | Default
2023 --------+--------+-----------+----------+---------
2024 f1 | bigint | | not null |
2030 "anothertab_pkey" PRIMARY KEY, btree (f1)
2031 "anothertab_f1_f4_key" UNIQUE CONSTRAINT, btree (f1, f4)
2032 "anothertab_f2_f3_idx" btree (f2, f3)
2033 "anothertab_f2_key" UNIQUE CONSTRAINT, btree (f2)
2034 "anothertab_f3_excl" EXCLUDE USING btree (f3 WITH =)
2035 "anothertab_f4_excl" EXCLUDE USING btree (f4 WITH =) WHERE (f4 IS NOT NULL)
2036 "anothertab_f4_excl1" EXCLUDE USING btree (f4 WITH =) WHERE (f5 > 0)
2037 "anothertab_f4_idx" UNIQUE, btree (f4)
2039 drop table anothertab;
2040 -- test that USING expressions are parsed before column alter type / drop steps
2041 create table another (f1 int, f2 text, f3 text);
2042 insert into another values(1, 'one', 'uno');
2043 insert into another values(2, 'two', 'due');
2044 insert into another values(3, 'three', 'tre');
2045 select * from another;
2054 alter f1 type text using f2 || ' and ' || f3 || ' more',
2055 alter f2 type bigint using f1 * 10,
2057 select * from another;
2059 --------------------+----
2060 one and uno more | 10
2061 two and due more | 20
2062 three and tre more | 30
2066 -- Create an index that skips WAL, then perform a SET DATA TYPE that skips
2067 -- rewriting the index.
2069 create table skip_wal_skip_rewrite_index (c varchar(10) primary key);
2070 alter table skip_wal_skip_rewrite_index alter c type varchar(20);
2072 -- We disallow changing table's row type if it's used for storage
2073 create table at_tab1 (a int, b text);
2074 create table at_tab2 (x int, y at_tab1);
2075 alter table at_tab1 alter column b type varchar; -- fails
2076 ERROR: cannot alter table "at_tab1" because column "at_tab2.y" uses its row type
2078 -- Use of row type in an expression is defended differently
2079 create table at_tab2 (x int, y text, check((x,y)::at_tab1 = (1,'42')::at_tab1));
2080 alter table at_tab1 alter column b type varchar; -- allowed, but ...
2081 insert into at_tab2 values(1,'42'); -- ... this will fail
2082 ERROR: ROW() column has type text instead of type character varying
2083 drop table at_tab1, at_tab2;
2084 -- Check it for a partitioned table, too
2085 create table at_tab1 (a int, b text) partition by list(a);
2086 create table at_tab2 (x int, y at_tab1);
2087 alter table at_tab1 alter column b type varchar; -- fails
2088 ERROR: cannot alter table "at_tab1" because column "at_tab2.y" uses its row type
2089 drop table at_tab1, at_tab2;
2090 -- Alter column type that's part of a partitioned index
2091 create table at_partitioned (a int, b text) partition by range (a);
2092 create table at_part_1 partition of at_partitioned for values from (0) to (1000);
2093 insert into at_partitioned values (512, '0.123');
2094 create table at_part_2 (b text, a int);
2095 insert into at_part_2 values ('1.234', 1024);
2096 create index on at_partitioned (b);
2097 create index on at_partitioned (a);
2099 Table "public.at_part_1"
2100 Column | Type | Collation | Nullable | Default
2101 --------+---------+-----------+----------+---------
2104 Partition of: at_partitioned FOR VALUES FROM (0) TO (1000)
2106 "at_part_1_a_idx" btree (a)
2107 "at_part_1_b_idx" btree (b)
2110 Table "public.at_part_2"
2111 Column | Type | Collation | Nullable | Default
2112 --------+---------+-----------+----------+---------
2116 alter table at_partitioned attach partition at_part_2 for values from (1000) to (2000);
2118 Table "public.at_part_2"
2119 Column | Type | Collation | Nullable | Default
2120 --------+---------+-----------+----------+---------
2123 Partition of: at_partitioned FOR VALUES FROM (1000) TO (2000)
2125 "at_part_2_a_idx" btree (a)
2126 "at_part_2_b_idx" btree (b)
2128 alter table at_partitioned alter column b type numeric using b::numeric;
2130 Table "public.at_part_1"
2131 Column | Type | Collation | Nullable | Default
2132 --------+---------+-----------+----------+---------
2135 Partition of: at_partitioned FOR VALUES FROM (0) TO (1000)
2137 "at_part_1_a_idx" btree (a)
2138 "at_part_1_b_idx" btree (b)
2141 Table "public.at_part_2"
2142 Column | Type | Collation | Nullable | Default
2143 --------+---------+-----------+----------+---------
2146 Partition of: at_partitioned FOR VALUES FROM (1000) TO (2000)
2148 "at_part_2_a_idx" btree (a)
2149 "at_part_2_b_idx" btree (b)
2151 drop table at_partitioned;
2152 -- Alter column type when no table rewrite is required
2153 -- Also check that comments are preserved
2154 create table at_partitioned(id int, name varchar(64), unique (id, name))
2155 partition by hash(id);
2156 comment on constraint at_partitioned_id_name_key on at_partitioned is 'parent constraint';
2157 comment on index at_partitioned_id_name_key is 'parent index';
2158 create table at_partitioned_0 partition of at_partitioned
2159 for values with (modulus 2, remainder 0);
2160 comment on constraint at_partitioned_0_id_name_key on at_partitioned_0 is 'child 0 constraint';
2161 comment on index at_partitioned_0_id_name_key is 'child 0 index';
2162 create table at_partitioned_1 partition of at_partitioned
2163 for values with (modulus 2, remainder 1);
2164 comment on constraint at_partitioned_1_id_name_key on at_partitioned_1 is 'child 1 constraint';
2165 comment on index at_partitioned_1_id_name_key is 'child 1 index';
2166 insert into at_partitioned values(1, 'foo');
2167 insert into at_partitioned values(3, 'bar');
2168 create temp table old_oids as
2169 select relname, oid as oldoid, relfilenode as oldfilenode
2170 from pg_class where relname like 'at_partitioned%';
2172 c.oid = oldoid as orig_oid,
2175 when c.oid then 'own'
2176 when oldfilenode then 'orig'
2179 obj_description(c.oid, 'pg_class') as desc
2180 from pg_class c left join old_oids using (relname)
2181 where relname like 'at_partitioned%'
2183 relname | orig_oid | storage | desc
2184 ------------------------------+----------+---------+---------------
2185 at_partitioned | t | none |
2186 at_partitioned_0 | t | own |
2187 at_partitioned_0_id_name_key | t | own | child 0 index
2188 at_partitioned_1 | t | own |
2189 at_partitioned_1_id_name_key | t | own | child 1 index
2190 at_partitioned_id_name_key | t | none | parent index
2193 select conname, obj_description(oid, 'pg_constraint') as desc
2194 from pg_constraint where conname like 'at_partitioned%'
2197 ------------------------------+--------------------
2198 at_partitioned_0_id_name_key | child 0 constraint
2199 at_partitioned_1_id_name_key | child 1 constraint
2200 at_partitioned_id_name_key | parent constraint
2203 alter table at_partitioned alter column name type varchar(127);
2205 c.oid = oldoid as orig_oid,
2208 when c.oid then 'own'
2209 when oldfilenode then 'orig'
2212 obj_description(c.oid, 'pg_class') as desc
2213 from pg_class c left join old_oids using (relname)
2214 where relname like 'at_partitioned%'
2216 relname | orig_oid | storage | desc
2217 ------------------------------+----------+---------+--------------
2218 at_partitioned | t | none |
2219 at_partitioned_0 | t | own |
2220 at_partitioned_0_id_name_key | f | own |
2221 at_partitioned_1 | t | own |
2222 at_partitioned_1_id_name_key | f | own |
2223 at_partitioned_id_name_key | f | none | parent index
2226 select conname, obj_description(oid, 'pg_constraint') as desc
2227 from pg_constraint where conname like 'at_partitioned%'
2230 ------------------------------+-------------------
2231 at_partitioned_0_id_name_key |
2232 at_partitioned_1_id_name_key |
2233 at_partitioned_id_name_key | parent constraint
2236 -- Don't remove this DROP, it exposes bug #15672
2237 drop table at_partitioned;
2238 -- disallow recursive containment of row types
2239 create temp table recur1 (f1 int);
2240 alter table recur1 add column f2 recur1; -- fails
2241 ERROR: composite type recur1 cannot be made a member of itself
2242 alter table recur1 add column f2 recur1[]; -- fails
2243 ERROR: composite type recur1 cannot be made a member of itself
2244 create domain array_of_recur1 as recur1[];
2245 alter table recur1 add column f2 array_of_recur1; -- fails
2246 ERROR: composite type recur1 cannot be made a member of itself
2247 create temp table recur2 (f1 int, f2 recur1);
2248 alter table recur1 add column f2 recur2; -- fails
2249 ERROR: composite type recur1 cannot be made a member of itself
2250 alter table recur1 add column f2 int;
2251 alter table recur1 alter column f2 type recur2; -- fails
2252 ERROR: composite type recur1 cannot be made a member of itself
2253 -- SET STORAGE may need to add a TOAST table
2254 create table test_storage (a text, c text storage plain);
2255 select reltoastrelid <> 0 as has_toast_table
2256 from pg_class where oid = 'test_storage'::regclass;
2262 alter table test_storage alter a set storage plain;
2263 -- rewrite table to remove its TOAST table; need a non-constant column default
2264 alter table test_storage add b int default random()::int;
2265 select reltoastrelid <> 0 as has_toast_table
2266 from pg_class where oid = 'test_storage'::regclass;
2272 alter table test_storage alter a set storage default; -- re-add TOAST table
2273 select reltoastrelid <> 0 as has_toast_table
2274 from pg_class where oid = 'test_storage'::regclass;
2280 -- check STORAGE correctness
2281 create table test_storage_failed (a text, b int storage extended);
2282 ERROR: column data type integer can only have storage PLAIN
2283 -- test that SET STORAGE propagates to index correctly
2284 create index test_storage_idx on test_storage (b, a);
2285 alter table test_storage alter column a set storage external;
2287 Table "public.test_storage"
2288 Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
2289 --------+---------+-----------+----------+-------------------+----------+--------------+-------------
2290 a | text | | | | external | |
2291 c | text | | | | plain | |
2292 b | integer | | | random()::integer | plain | |
2294 "test_storage_idx" btree (b, a)
2296 \d+ test_storage_idx
2297 Index "public.test_storage_idx"
2298 Column | Type | Key? | Definition | Storage | Stats target
2299 --------+---------+------+------------+----------+--------------
2300 b | integer | yes | b | plain |
2301 a | text | yes | a | external |
2302 btree, for table "public.test_storage"
2304 -- ALTER COLUMN TYPE with a check constraint and a child table (bug #13779)
2305 CREATE TABLE test_inh_check (a float check (a > 10.2), b float);
2306 CREATE TABLE test_inh_check_child() INHERITS(test_inh_check);
2308 Table "public.test_inh_check"
2309 Column | Type | Collation | Nullable | Default
2310 --------+------------------+-----------+----------+---------
2311 a | double precision | | |
2312 b | double precision | | |
2314 "test_inh_check_a_check" CHECK (a > 10.2::double precision)
2315 Number of child tables: 1 (Use \d+ to list them.)
2317 \d test_inh_check_child
2318 Table "public.test_inh_check_child"
2319 Column | Type | Collation | Nullable | Default
2320 --------+------------------+-----------+----------+---------
2321 a | double precision | | |
2322 b | double precision | | |
2324 "test_inh_check_a_check" CHECK (a > 10.2::double precision)
2325 Inherits: test_inh_check
2327 select relname, conname, coninhcount, conislocal, connoinherit
2328 from pg_constraint c, pg_class r
2329 where relname like 'test_inh_check%' and c.conrelid = r.oid
2331 relname | conname | coninhcount | conislocal | connoinherit
2332 ----------------------+------------------------+-------------+------------+--------------
2333 test_inh_check | test_inh_check_a_check | 0 | t | f
2334 test_inh_check_child | test_inh_check_a_check | 1 | f | f
2337 ALTER TABLE test_inh_check ALTER COLUMN a TYPE numeric;
2339 Table "public.test_inh_check"
2340 Column | Type | Collation | Nullable | Default
2341 --------+------------------+-----------+----------+---------
2343 b | double precision | | |
2345 "test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
2346 Number of child tables: 1 (Use \d+ to list them.)
2348 \d test_inh_check_child
2349 Table "public.test_inh_check_child"
2350 Column | Type | Collation | Nullable | Default
2351 --------+------------------+-----------+----------+---------
2353 b | double precision | | |
2355 "test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
2356 Inherits: test_inh_check
2358 select relname, conname, coninhcount, conislocal, connoinherit
2359 from pg_constraint c, pg_class r
2360 where relname like 'test_inh_check%' and c.conrelid = r.oid
2362 relname | conname | coninhcount | conislocal | connoinherit
2363 ----------------------+------------------------+-------------+------------+--------------
2364 test_inh_check | test_inh_check_a_check | 0 | t | f
2365 test_inh_check_child | test_inh_check_a_check | 1 | f | f
2368 -- also try noinherit, local, and local+inherited cases
2369 ALTER TABLE test_inh_check ADD CONSTRAINT bnoinherit CHECK (b > 100) NO INHERIT;
2370 ALTER TABLE test_inh_check_child ADD CONSTRAINT blocal CHECK (b < 1000);
2371 ALTER TABLE test_inh_check_child ADD CONSTRAINT bmerged CHECK (b > 1);
2372 ALTER TABLE test_inh_check ADD CONSTRAINT bmerged CHECK (b > 1);
2373 NOTICE: merging constraint "bmerged" with inherited definition
2375 Table "public.test_inh_check"
2376 Column | Type | Collation | Nullable | Default
2377 --------+------------------+-----------+----------+---------
2379 b | double precision | | |
2381 "bmerged" CHECK (b > 1::double precision)
2382 "bnoinherit" CHECK (b > 100::double precision) NO INHERIT
2383 "test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
2384 Number of child tables: 1 (Use \d+ to list them.)
2386 \d test_inh_check_child
2387 Table "public.test_inh_check_child"
2388 Column | Type | Collation | Nullable | Default
2389 --------+------------------+-----------+----------+---------
2391 b | double precision | | |
2393 "blocal" CHECK (b < 1000::double precision)
2394 "bmerged" CHECK (b > 1::double precision)
2395 "test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
2396 Inherits: test_inh_check
2398 select relname, conname, coninhcount, conislocal, connoinherit
2399 from pg_constraint c, pg_class r
2400 where relname like 'test_inh_check%' and c.conrelid = r.oid
2402 relname | conname | coninhcount | conislocal | connoinherit
2403 ----------------------+------------------------+-------------+------------+--------------
2404 test_inh_check | bmerged | 0 | t | f
2405 test_inh_check | bnoinherit | 0 | t | t
2406 test_inh_check | test_inh_check_a_check | 0 | t | f
2407 test_inh_check_child | blocal | 0 | t | f
2408 test_inh_check_child | bmerged | 1 | t | f
2409 test_inh_check_child | test_inh_check_a_check | 1 | f | f
2412 ALTER TABLE test_inh_check ALTER COLUMN b TYPE numeric;
2413 NOTICE: merging constraint "bmerged" with inherited definition
2415 Table "public.test_inh_check"
2416 Column | Type | Collation | Nullable | Default
2417 --------+---------+-----------+----------+---------
2421 "bmerged" CHECK (b::double precision > 1::double precision)
2422 "bnoinherit" CHECK (b::double precision > 100::double precision) NO INHERIT
2423 "test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
2424 Number of child tables: 1 (Use \d+ to list them.)
2426 \d test_inh_check_child
2427 Table "public.test_inh_check_child"
2428 Column | Type | Collation | Nullable | Default
2429 --------+---------+-----------+----------+---------
2433 "blocal" CHECK (b::double precision < 1000::double precision)
2434 "bmerged" CHECK (b::double precision > 1::double precision)
2435 "test_inh_check_a_check" CHECK (a::double precision > 10.2::double precision)
2436 Inherits: test_inh_check
2438 select relname, conname, coninhcount, conislocal, connoinherit
2439 from pg_constraint c, pg_class r
2440 where relname like 'test_inh_check%' and c.conrelid = r.oid
2442 relname | conname | coninhcount | conislocal | connoinherit
2443 ----------------------+------------------------+-------------+------------+--------------
2444 test_inh_check | bmerged | 0 | t | f
2445 test_inh_check | bnoinherit | 0 | t | t
2446 test_inh_check | test_inh_check_a_check | 0 | t | f
2447 test_inh_check_child | blocal | 0 | t | f
2448 test_inh_check_child | bmerged | 1 | t | f
2449 test_inh_check_child | test_inh_check_a_check | 1 | f | f
2452 -- ALTER COLUMN TYPE with different schema in children
2453 -- Bug at https://postgr.es/m/20170102225618.GA10071@telsasoft.com
2454 CREATE TABLE test_type_diff (f1 int);
2455 CREATE TABLE test_type_diff_c (extra smallint) INHERITS (test_type_diff);
2456 ALTER TABLE test_type_diff ADD COLUMN f2 int;
2457 INSERT INTO test_type_diff_c VALUES (1, 2, 3);
2458 ALTER TABLE test_type_diff ALTER COLUMN f2 TYPE bigint USING f2::bigint;
2459 CREATE TABLE test_type_diff2 (int_two int2, int_four int4, int_eight int8);
2460 CREATE TABLE test_type_diff2_c1 (int_four int4, int_eight int8, int_two int2);
2461 CREATE TABLE test_type_diff2_c2 (int_eight int8, int_two int2, int_four int4);
2462 CREATE TABLE test_type_diff2_c3 (int_two int2, int_four int4, int_eight int8);
2463 ALTER TABLE test_type_diff2_c1 INHERIT test_type_diff2;
2464 ALTER TABLE test_type_diff2_c2 INHERIT test_type_diff2;
2465 ALTER TABLE test_type_diff2_c3 INHERIT test_type_diff2;
2466 INSERT INTO test_type_diff2_c1 VALUES (1, 2, 3);
2467 INSERT INTO test_type_diff2_c2 VALUES (4, 5, 6);
2468 INSERT INTO test_type_diff2_c3 VALUES (7, 8, 9);
2469 ALTER TABLE test_type_diff2 ALTER COLUMN int_four TYPE int8 USING int_four::int8;
2470 -- whole-row references are disallowed
2471 ALTER TABLE test_type_diff2 ALTER COLUMN int_four TYPE int4 USING (pg_column_size(test_type_diff2));
2472 ERROR: cannot convert whole-row table reference
2473 DETAIL: USING expression contains a whole-row table reference.
2474 -- check for rollback of ANALYZE corrupting table property flags (bug #11638)
2475 CREATE TABLE check_fk_presence_1 (id int PRIMARY KEY, t text);
2476 CREATE TABLE check_fk_presence_2 (id int REFERENCES check_fk_presence_1, t text);
2478 ALTER TABLE check_fk_presence_2 DROP CONSTRAINT check_fk_presence_2_id_fkey;
2479 ANALYZE check_fk_presence_2;
2481 \d check_fk_presence_2
2482 Table "public.check_fk_presence_2"
2483 Column | Type | Collation | Nullable | Default
2484 --------+---------+-----------+----------+---------
2487 Foreign-key constraints:
2488 "check_fk_presence_2_id_fkey" FOREIGN KEY (id) REFERENCES check_fk_presence_1(id)
2490 DROP TABLE check_fk_presence_1, check_fk_presence_2;
2491 -- check column addition within a view (bug #14876)
2492 create table at_base_table(id int, stuff text);
2493 insert into at_base_table values (23, 'skidoo');
2494 create view at_view_1 as select * from at_base_table bt;
2495 create view at_view_2 as select *, to_json(v1) as j from at_view_1 v1;
2497 View "public.at_view_1"
2498 Column | Type | Collation | Nullable | Default | Storage | Description
2499 --------+---------+-----------+----------+---------+----------+-------------
2500 id | integer | | | | plain |
2501 stuff | text | | | | extended |
2505 FROM at_base_table bt;
2508 View "public.at_view_2"
2509 Column | Type | Collation | Nullable | Default | Storage | Description
2510 --------+---------+-----------+----------+---------+----------+-------------
2511 id | integer | | | | plain |
2512 stuff | text | | | | extended |
2513 j | json | | | | extended |
2520 explain (verbose, costs off) select * from at_view_2;
2522 ----------------------------------------------------------
2523 Seq Scan on public.at_base_table bt
2524 Output: bt.id, bt.stuff, to_json(ROW(bt.id, bt.stuff))
2527 select * from at_view_2;
2529 ----+--------+----------------------------
2530 23 | skidoo | {"id":23,"stuff":"skidoo"}
2533 create or replace view at_view_1 as select *, 2+2 as more from at_base_table bt;
2535 View "public.at_view_1"
2536 Column | Type | Collation | Nullable | Default | Storage | Description
2537 --------+---------+-----------+----------+---------+----------+-------------
2538 id | integer | | | | plain |
2539 stuff | text | | | | extended |
2540 more | integer | | | | plain |
2545 FROM at_base_table bt;
2548 View "public.at_view_2"
2549 Column | Type | Collation | Nullable | Default | Storage | Description
2550 --------+---------+-----------+----------+---------+----------+-------------
2551 id | integer | | | | plain |
2552 stuff | text | | | | extended |
2553 j | json | | | | extended |
2560 explain (verbose, costs off) select * from at_view_2;
2562 -------------------------------------------------------------
2563 Seq Scan on public.at_base_table bt
2564 Output: bt.id, bt.stuff, to_json(ROW(bt.id, bt.stuff, 4))
2567 select * from at_view_2;
2569 ----+--------+-------------------------------------
2570 23 | skidoo | {"id":23,"stuff":"skidoo","more":4}
2573 drop view at_view_2;
2574 drop view at_view_1;
2575 drop table at_base_table;
2576 -- related case (bug #17811)
2578 create temp table t1 as select * from int8_tbl;
2579 create temp view v1 as select 1::int8 as q1;
2580 create temp view v2 as select * from v1;
2581 create or replace temp view v1 with (security_barrier = true)
2582 as select * from t1;
2583 create temp table log (q1 int8, q2 int8);
2584 create rule v1_upd_rule as on update to v1
2585 do also insert into log values (new.*);
2586 update v2 set q1 = q1 + 1 where q1 = 123;
2589 ------------------+-------------------
2590 4567890123456789 | 123
2591 4567890123456789 | 4567890123456789
2592 4567890123456789 | -4567890123456789
2594 124 | 4567890123456789
2599 -----+------------------
2601 124 | 4567890123456789
2605 -- check adding a column not itself requiring a rewrite, together with
2606 -- a column requiring a default (bug #16038)
2607 -- ensure that rewrites aren't silently optimized away, removing the
2608 -- value of the test
2609 CREATE FUNCTION check_ddl_rewrite(p_tablename regclass, p_ddl text)
2611 LANGUAGE plpgsql AS $$
2615 v_relfilenode := relfilenode FROM pg_class WHERE oid = p_tablename;
2619 RETURN v_relfilenode <> (SELECT relfilenode FROM pg_class WHERE oid = p_tablename);
2622 CREATE TABLE rewrite_test(col text);
2623 INSERT INTO rewrite_test VALUES ('something');
2624 INSERT INTO rewrite_test VALUES (NULL);
2625 -- empty[12] don't need rewrite, but notempty[12]_rewrite will force one
2626 SELECT check_ddl_rewrite('rewrite_test', $$
2627 ALTER TABLE rewrite_test
2628 ADD COLUMN empty1 text,
2629 ADD COLUMN notempty1_rewrite serial;
2636 SELECT check_ddl_rewrite('rewrite_test', $$
2637 ALTER TABLE rewrite_test
2638 ADD COLUMN notempty2_rewrite serial,
2639 ADD COLUMN empty2 text;
2646 -- also check that fast defaults cause no problem, first without rewrite
2647 SELECT check_ddl_rewrite('rewrite_test', $$
2648 ALTER TABLE rewrite_test
2649 ADD COLUMN empty3 text,
2650 ADD COLUMN notempty3_norewrite int default 42;
2657 SELECT check_ddl_rewrite('rewrite_test', $$
2658 ALTER TABLE rewrite_test
2659 ADD COLUMN notempty4_norewrite int default 42,
2660 ADD COLUMN empty4 text;
2667 -- then with rewrite
2668 SELECT check_ddl_rewrite('rewrite_test', $$
2669 ALTER TABLE rewrite_test
2670 ADD COLUMN empty5 text,
2671 ADD COLUMN notempty5_norewrite int default 42,
2672 ADD COLUMN notempty5_rewrite serial;
2679 SELECT check_ddl_rewrite('rewrite_test', $$
2680 ALTER TABLE rewrite_test
2681 ADD COLUMN notempty6_rewrite serial,
2682 ADD COLUMN empty6 text,
2683 ADD COLUMN notempty6_norewrite int default 42;
2691 DROP FUNCTION check_ddl_rewrite(regclass, text);
2692 DROP TABLE rewrite_test;
2696 drop type lockmodes;
2697 ERROR: type "lockmodes" does not exist
2698 create type lockmodes as enum (
2703 ,'ShareUpdateExclusiveLock'
2705 ,'ShareRowExclusiveLock'
2707 ,'AccessExclusiveLock'
2710 ERROR: view "my_locks" does not exist
2711 create or replace view my_locks as
2712 select case when c.relname like 'pg_toast%' then 'pg_toast' else c.relname end, max(mode::lockmodes) as max_lockmode
2713 from pg_locks l join pg_class c on l.relation = c.oid
2714 where virtualtransaction = (
2715 select virtualtransaction
2717 where transactionid = pg_current_xact_id()::xid)
2718 and locktype = 'relation'
2719 and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
2720 and c.relname != 'my_locks'
2722 create table alterlock (f1 int primary key, f2 text);
2723 insert into alterlock values (1, 'foo');
2724 create table alterlock2 (f3 int primary key, f1 int);
2725 insert into alterlock2 values (1, 1);
2726 begin; alter table alterlock alter column f2 set statistics 150;
2727 select * from my_locks order by 1;
2728 relname | max_lockmode
2729 -----------+--------------------------
2730 alterlock | ShareUpdateExclusiveLock
2734 begin; alter table alterlock cluster on alterlock_pkey;
2735 select * from my_locks order by 1;
2736 relname | max_lockmode
2737 ----------------+--------------------------
2738 alterlock | ShareUpdateExclusiveLock
2739 alterlock_pkey | ShareUpdateExclusiveLock
2743 begin; alter table alterlock set without cluster;
2744 select * from my_locks order by 1;
2745 relname | max_lockmode
2746 -----------+--------------------------
2747 alterlock | ShareUpdateExclusiveLock
2751 begin; alter table alterlock set (fillfactor = 100);
2752 select * from my_locks order by 1;
2753 relname | max_lockmode
2754 -----------+--------------------------
2755 alterlock | ShareUpdateExclusiveLock
2756 pg_toast | ShareUpdateExclusiveLock
2760 begin; alter table alterlock reset (fillfactor);
2761 select * from my_locks order by 1;
2762 relname | max_lockmode
2763 -----------+--------------------------
2764 alterlock | ShareUpdateExclusiveLock
2765 pg_toast | ShareUpdateExclusiveLock
2769 begin; alter table alterlock set (toast.autovacuum_enabled = off);
2770 select * from my_locks order by 1;
2771 relname | max_lockmode
2772 -----------+--------------------------
2773 alterlock | ShareUpdateExclusiveLock
2774 pg_toast | ShareUpdateExclusiveLock
2778 begin; alter table alterlock set (autovacuum_enabled = off);
2779 select * from my_locks order by 1;
2780 relname | max_lockmode
2781 -----------+--------------------------
2782 alterlock | ShareUpdateExclusiveLock
2783 pg_toast | ShareUpdateExclusiveLock
2787 begin; alter table alterlock alter column f2 set (n_distinct = 1);
2788 select * from my_locks order by 1;
2789 relname | max_lockmode
2790 -----------+--------------------------
2791 alterlock | ShareUpdateExclusiveLock
2795 -- test that mixing options with different lock levels works as expected
2796 begin; alter table alterlock set (autovacuum_enabled = off, fillfactor = 80);
2797 select * from my_locks order by 1;
2798 relname | max_lockmode
2799 -----------+--------------------------
2800 alterlock | ShareUpdateExclusiveLock
2801 pg_toast | ShareUpdateExclusiveLock
2805 begin; alter table alterlock alter column f2 set storage extended;
2806 select * from my_locks order by 1;
2807 relname | max_lockmode
2808 -----------+---------------------
2809 alterlock | AccessExclusiveLock
2813 begin; alter table alterlock alter column f2 set default 'x';
2814 select * from my_locks order by 1;
2815 relname | max_lockmode
2816 -----------+---------------------
2817 alterlock | AccessExclusiveLock
2822 create trigger ttdummy
2823 before delete or update on alterlock
2827 select * from my_locks order by 1;
2828 relname | max_lockmode
2829 -----------+-----------------------
2830 alterlock | ShareRowExclusiveLock
2835 select * from my_locks order by 1;
2836 relname | max_lockmode
2837 ---------+--------------
2840 alter table alterlock2 add foreign key (f1) references alterlock (f1);
2841 select * from my_locks order by 1;
2842 relname | max_lockmode
2843 -----------------+-----------------------
2844 alterlock | ShareRowExclusiveLock
2845 alterlock2 | ShareRowExclusiveLock
2846 alterlock2_pkey | AccessShareLock
2847 alterlock_pkey | AccessShareLock
2852 alter table alterlock2
2853 add constraint alterlock2nv foreign key (f1) references alterlock (f1) NOT VALID;
2854 select * from my_locks order by 1;
2855 relname | max_lockmode
2856 ------------+-----------------------
2857 alterlock | ShareRowExclusiveLock
2858 alterlock2 | ShareRowExclusiveLock
2863 alter table alterlock2 validate constraint alterlock2nv;
2864 select * from my_locks order by 1;
2865 relname | max_lockmode
2866 -----------------+--------------------------
2867 alterlock | RowShareLock
2868 alterlock2 | ShareUpdateExclusiveLock
2869 alterlock2_pkey | AccessShareLock
2870 alterlock_pkey | AccessShareLock
2874 create or replace view my_locks as
2875 select case when c.relname like 'pg_toast%' then 'pg_toast' else c.relname end, max(mode::lockmodes) as max_lockmode
2876 from pg_locks l join pg_class c on l.relation = c.oid
2877 where virtualtransaction = (
2878 select virtualtransaction
2880 where transactionid = pg_current_xact_id()::xid)
2881 and locktype = 'relation'
2882 and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
2883 and c.relname = 'my_locks'
2886 alter table my_locks set (autovacuum_enabled = false);
2887 ERROR: unrecognized parameter "autovacuum_enabled"
2888 alter view my_locks set (autovacuum_enabled = false);
2889 ERROR: unrecognized parameter "autovacuum_enabled"
2890 alter table my_locks reset (autovacuum_enabled);
2891 alter view my_locks reset (autovacuum_enabled);
2893 alter view my_locks set (security_barrier=off);
2894 select * from my_locks order by 1;
2895 relname | max_lockmode
2896 ----------+---------------------
2897 my_locks | AccessExclusiveLock
2900 alter view my_locks reset (security_barrier);
2902 -- this test intentionally applies the ALTER TABLE command against a view, but
2903 -- uses a view option so we expect this to succeed. This form of SQL is
2904 -- accepted for historical reasons, as shown in the docs for ALTER VIEW
2906 alter table my_locks set (security_barrier=off);
2907 select * from my_locks order by 1;
2908 relname | max_lockmode
2909 ----------+---------------------
2910 my_locks | AccessExclusiveLock
2913 alter table my_locks reset (security_barrier);
2916 drop table alterlock2;
2917 drop table alterlock;
2919 drop type lockmodes;
2923 create function test_strict(text) returns text as
2924 'select coalesce($1, ''got passed a null'');'
2925 language sql returns null on null input;
2926 select test_strict(NULL);
2932 alter function test_strict(text) called on null input;
2933 select test_strict(NULL);
2939 create function non_strict(text) returns text as
2940 'select coalesce($1, ''got passed a null'');'
2941 language sql called on null input;
2942 select non_strict(NULL);
2948 alter function non_strict(text) returns null on null input;
2949 select non_strict(NULL);
2956 -- alter object set schema
2958 create schema alter1;
2959 create schema alter2;
2960 create table alter1.t1(f1 serial primary key, f2 int check (f2 > 0));
2961 create view alter1.v1 as select * from alter1.t1;
2962 create function alter1.plus1(int) returns int as 'select $1+1' language sql;
2963 create domain alter1.posint integer check (value > 0);
2964 create type alter1.ctype as (f1 int, f2 text);
2965 create function alter1.same(alter1.ctype, alter1.ctype) returns boolean language sql
2966 as 'select $1.f1 is not distinct from $2.f1 and $1.f2 is not distinct from $2.f2';
2967 create operator alter1.=(procedure = alter1.same, leftarg = alter1.ctype, rightarg = alter1.ctype);
2968 create operator class alter1.ctype_hash_ops default for type alter1.ctype using hash as
2969 operator 1 alter1.=(alter1.ctype, alter1.ctype);
2970 create conversion alter1.latin1_to_utf8 for 'latin1' to 'utf8' from iso8859_1_to_utf8;
2971 create text search parser alter1.prs(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
2972 create text search configuration alter1.cfg(parser = alter1.prs);
2973 create text search template alter1.tmpl(init = dsimple_init, lexize = dsimple_lexize);
2974 create text search dictionary alter1.dict(template = alter1.tmpl);
2975 insert into alter1.t1(f2) values(11);
2976 insert into alter1.t1(f2) values(12);
2977 alter table alter1.t1 set schema alter1; -- no-op, same schema
2978 alter table alter1.t1 set schema alter2;
2979 alter table alter1.v1 set schema alter2;
2980 alter function alter1.plus1(int) set schema alter2;
2981 alter domain alter1.posint set schema alter2;
2982 alter operator class alter1.ctype_hash_ops using hash set schema alter2;
2983 alter operator family alter1.ctype_hash_ops using hash set schema alter2;
2984 alter operator alter1.=(alter1.ctype, alter1.ctype) set schema alter2;
2985 alter function alter1.same(alter1.ctype, alter1.ctype) set schema alter2;
2986 alter type alter1.ctype set schema alter1; -- no-op, same schema
2987 alter type alter1.ctype set schema alter2;
2988 alter conversion alter1.latin1_to_utf8 set schema alter2;
2989 alter text search parser alter1.prs set schema alter2;
2990 alter text search configuration alter1.cfg set schema alter2;
2991 alter text search template alter1.tmpl set schema alter2;
2992 alter text search dictionary alter1.dict set schema alter2;
2993 -- this should succeed because nothing is left in alter1
2995 insert into alter2.t1(f2) values(13);
2996 insert into alter2.t1(f2) values(14);
2997 select * from alter2.t1;
3006 select * from alter2.v1;
3015 select alter2.plus1(41);
3022 drop schema alter2 cascade;
3023 NOTICE: drop cascades to 13 other objects
3024 DETAIL: drop cascades to table alter2.t1
3025 drop cascades to view alter2.v1
3026 drop cascades to function alter2.plus1(integer)
3027 drop cascades to type alter2.posint
3028 drop cascades to type alter2.ctype
3029 drop cascades to function alter2.same(alter2.ctype,alter2.ctype)
3030 drop cascades to operator alter2.=(alter2.ctype,alter2.ctype)
3031 drop cascades to operator family alter2.ctype_hash_ops for access method hash
3032 drop cascades to conversion alter2.latin1_to_utf8
3033 drop cascades to text search parser alter2.prs
3034 drop cascades to text search configuration alter2.cfg
3035 drop cascades to text search template alter2.tmpl
3036 drop cascades to text search dictionary alter2.dict
3040 CREATE TYPE test_type AS (a int);
3042 Composite type "public.test_type"
3043 Column | Type | Collation | Nullable | Default
3044 --------+---------+-----------+----------+---------
3047 ALTER TYPE nosuchtype ADD ATTRIBUTE b text; -- fails
3048 ERROR: relation "nosuchtype" does not exist
3049 ALTER TYPE test_type ADD ATTRIBUTE b text;
3051 Composite type "public.test_type"
3052 Column | Type | Collation | Nullable | Default
3053 --------+---------+-----------+----------+---------
3057 ALTER TYPE test_type ADD ATTRIBUTE b text; -- fails
3058 ERROR: column "b" of relation "test_type" already exists
3059 ALTER TYPE test_type ALTER ATTRIBUTE b SET DATA TYPE varchar;
3061 Composite type "public.test_type"
3062 Column | Type | Collation | Nullable | Default
3063 --------+-------------------+-----------+----------+---------
3065 b | character varying | | |
3067 ALTER TYPE test_type ALTER ATTRIBUTE b SET DATA TYPE integer;
3069 Composite type "public.test_type"
3070 Column | Type | Collation | Nullable | Default
3071 --------+---------+-----------+----------+---------
3075 ALTER TYPE test_type DROP ATTRIBUTE b;
3077 Composite type "public.test_type"
3078 Column | Type | Collation | Nullable | Default
3079 --------+---------+-----------+----------+---------
3082 ALTER TYPE test_type DROP ATTRIBUTE c; -- fails
3083 ERROR: column "c" of relation "test_type" does not exist
3084 ALTER TYPE test_type DROP ATTRIBUTE IF EXISTS c;
3085 NOTICE: column "c" of relation "test_type" does not exist, skipping
3086 ALTER TYPE test_type DROP ATTRIBUTE a, ADD ATTRIBUTE d boolean;
3088 Composite type "public.test_type"
3089 Column | Type | Collation | Nullable | Default
3090 --------+---------+-----------+----------+---------
3093 ALTER TYPE test_type RENAME ATTRIBUTE a TO aa;
3094 ERROR: column "a" does not exist
3095 ALTER TYPE test_type RENAME ATTRIBUTE d TO dd;
3097 Composite type "public.test_type"
3098 Column | Type | Collation | Nullable | Default
3099 --------+---------+-----------+----------+---------
3102 DROP TYPE test_type;
3103 CREATE TYPE test_type1 AS (a int, b text);
3104 CREATE TABLE test_tbl1 (x int, y test_type1);
3105 ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar; -- fails
3106 ERROR: cannot alter type "test_type1" because column "test_tbl1.y" uses it
3107 DROP TABLE test_tbl1;
3108 CREATE TABLE test_tbl1 (x int, y text);
3109 CREATE INDEX test_tbl1_idx ON test_tbl1((row(x,y)::test_type1));
3110 ALTER TYPE test_type1 ALTER ATTRIBUTE b TYPE varchar; -- fails
3111 ERROR: cannot alter type "test_type1" because column "test_tbl1_idx.row" uses it
3112 DROP TABLE test_tbl1;
3113 DROP TYPE test_type1;
3114 CREATE TYPE test_type2 AS (a int, b text);
3115 CREATE TABLE test_tbl2 OF test_type2;
3116 CREATE TABLE test_tbl2_subclass () INHERITS (test_tbl2);
3118 Composite type "public.test_type2"
3119 Column | Type | Collation | Nullable | Default
3120 --------+---------+-----------+----------+---------
3125 Table "public.test_tbl2"
3126 Column | Type | Collation | Nullable | Default
3127 --------+---------+-----------+----------+---------
3130 Number of child tables: 1 (Use \d+ to list them.)
3131 Typed table of type: test_type2
3133 ALTER TYPE test_type2 ADD ATTRIBUTE c text; -- fails
3134 ERROR: cannot alter type "test_type2" because it is the type of a typed table
3135 HINT: Use ALTER ... CASCADE to alter the typed tables too.
3136 ALTER TYPE test_type2 ADD ATTRIBUTE c text CASCADE;
3138 Composite type "public.test_type2"
3139 Column | Type | Collation | Nullable | Default
3140 --------+---------+-----------+----------+---------
3146 Table "public.test_tbl2"
3147 Column | Type | Collation | Nullable | Default
3148 --------+---------+-----------+----------+---------
3152 Number of child tables: 1 (Use \d+ to list them.)
3153 Typed table of type: test_type2
3155 ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar; -- fails
3156 ERROR: cannot alter type "test_type2" because it is the type of a typed table
3157 HINT: Use ALTER ... CASCADE to alter the typed tables too.
3158 ALTER TYPE test_type2 ALTER ATTRIBUTE b TYPE varchar CASCADE;
3160 Composite type "public.test_type2"
3161 Column | Type | Collation | Nullable | Default
3162 --------+-------------------+-----------+----------+---------
3164 b | character varying | | |
3168 Table "public.test_tbl2"
3169 Column | Type | Collation | Nullable | Default
3170 --------+-------------------+-----------+----------+---------
3172 b | character varying | | |
3174 Number of child tables: 1 (Use \d+ to list them.)
3175 Typed table of type: test_type2
3177 ALTER TYPE test_type2 DROP ATTRIBUTE b; -- fails
3178 ERROR: cannot alter type "test_type2" because it is the type of a typed table
3179 HINT: Use ALTER ... CASCADE to alter the typed tables too.
3180 ALTER TYPE test_type2 DROP ATTRIBUTE b CASCADE;
3182 Composite type "public.test_type2"
3183 Column | Type | Collation | Nullable | Default
3184 --------+---------+-----------+----------+---------
3189 Table "public.test_tbl2"
3190 Column | Type | Collation | Nullable | Default
3191 --------+---------+-----------+----------+---------
3194 Number of child tables: 1 (Use \d+ to list them.)
3195 Typed table of type: test_type2
3197 ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa; -- fails
3198 ERROR: cannot alter type "test_type2" because it is the type of a typed table
3199 HINT: Use ALTER ... CASCADE to alter the typed tables too.
3200 ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa CASCADE;
3202 Composite type "public.test_type2"
3203 Column | Type | Collation | Nullable | Default
3204 --------+---------+-----------+----------+---------
3209 Table "public.test_tbl2"
3210 Column | Type | Collation | Nullable | Default
3211 --------+---------+-----------+----------+---------
3214 Number of child tables: 1 (Use \d+ to list them.)
3215 Typed table of type: test_type2
3217 \d test_tbl2_subclass
3218 Table "public.test_tbl2_subclass"
3219 Column | Type | Collation | Nullable | Default
3220 --------+---------+-----------+----------+---------
3225 DROP TABLE test_tbl2_subclass, test_tbl2;
3226 DROP TYPE test_type2;
3227 CREATE TYPE test_typex AS (a int, b text);
3228 CREATE TABLE test_tblx (x int, y test_typex check ((y).a > 0));
3229 ALTER TYPE test_typex DROP ATTRIBUTE a; -- fails
3230 ERROR: cannot drop column a of composite type test_typex because other objects depend on it
3231 DETAIL: constraint test_tblx_y_check on table test_tblx depends on column a of composite type test_typex
3232 HINT: Use DROP ... CASCADE to drop the dependent objects too.
3233 ALTER TYPE test_typex DROP ATTRIBUTE a CASCADE;
3234 NOTICE: drop cascades to constraint test_tblx_y_check on table test_tblx
3236 Table "public.test_tblx"
3237 Column | Type | Collation | Nullable | Default
3238 --------+------------+-----------+----------+---------
3240 y | test_typex | | |
3242 DROP TABLE test_tblx;
3243 DROP TYPE test_typex;
3244 -- This test isn't that interesting on its own, but the purpose is to leave
3245 -- behind a table to test pg_upgrade with. The table has a composite type
3246 -- column in it, and the composite type has a dropped attribute.
3247 CREATE TYPE test_type3 AS (a int);
3248 CREATE TABLE test_tbl3 (c) AS SELECT '(1)'::test_type3;
3249 ALTER TYPE test_type3 DROP ATTRIBUTE a, ADD ATTRIBUTE b int;
3250 CREATE TYPE test_type_empty AS ();
3251 DROP TYPE test_type_empty;
3253 -- typed tables: OF / NOT OF
3255 CREATE TYPE tt_t0 AS (z inet, x int, y numeric(8,2));
3256 ALTER TYPE tt_t0 DROP ATTRIBUTE z;
3257 CREATE TABLE tt0 (x int NOT NULL, y numeric(8,2)); -- OK
3258 CREATE TABLE tt1 (x int, y bigint); -- wrong base type
3259 CREATE TABLE tt2 (x int, y numeric(9,2)); -- wrong typmod
3260 CREATE TABLE tt3 (y numeric(8,2), x int); -- wrong column order
3261 CREATE TABLE tt4 (x int); -- too few columns
3262 CREATE TABLE tt5 (x int, y numeric(8,2), z int); -- too few columns
3263 CREATE TABLE tt6 () INHERITS (tt0); -- can't have a parent
3264 CREATE TABLE tt7 (x int, q text, y numeric(8,2));
3265 ALTER TABLE tt7 DROP q; -- OK
3266 ALTER TABLE tt0 OF tt_t0;
3267 ALTER TABLE tt1 OF tt_t0;
3268 ERROR: table "tt1" has different type for column "y"
3269 ALTER TABLE tt2 OF tt_t0;
3270 ERROR: table "tt2" has different type for column "y"
3271 ALTER TABLE tt3 OF tt_t0;
3272 ERROR: table has column "y" where type requires "x"
3273 ALTER TABLE tt4 OF tt_t0;
3274 ERROR: table is missing column "y"
3275 ALTER TABLE tt5 OF tt_t0;
3276 ERROR: table has extra column "z"
3277 ALTER TABLE tt6 OF tt_t0;
3278 ERROR: typed tables cannot inherit
3279 ALTER TABLE tt7 OF tt_t0;
3280 CREATE TYPE tt_t1 AS (x int, y numeric(8,2));
3281 ALTER TABLE tt7 OF tt_t1; -- reassign an already-typed table
3282 ALTER TABLE tt7 NOT OF;
3285 Column | Type | Collation | Nullable | Default
3286 --------+--------------+-----------+----------+---------
3288 y | numeric(8,2) | | |
3290 -- make sure we can drop a constraint on the parent but it remains on the child
3291 CREATE TABLE test_drop_constr_parent (c text CHECK (c IS NOT NULL));
3292 CREATE TABLE test_drop_constr_child () INHERITS (test_drop_constr_parent);
3293 ALTER TABLE ONLY test_drop_constr_parent DROP CONSTRAINT "test_drop_constr_parent_c_check";
3295 INSERT INTO test_drop_constr_child (c) VALUES (NULL);
3296 ERROR: new row for relation "test_drop_constr_child" violates check constraint "test_drop_constr_parent_c_check"
3297 DETAIL: Failing row contains (null).
3298 DROP TABLE test_drop_constr_parent CASCADE;
3299 NOTICE: drop cascades to table test_drop_constr_child
3303 ALTER TABLE IF EXISTS tt8 ADD COLUMN f int;
3304 NOTICE: relation "tt8" does not exist, skipping
3305 ALTER TABLE IF EXISTS tt8 ADD CONSTRAINT xxx PRIMARY KEY(f);
3306 NOTICE: relation "tt8" does not exist, skipping
3307 ALTER TABLE IF EXISTS tt8 ADD CHECK (f BETWEEN 0 AND 10);
3308 NOTICE: relation "tt8" does not exist, skipping
3309 ALTER TABLE IF EXISTS tt8 ALTER COLUMN f SET DEFAULT 0;
3310 NOTICE: relation "tt8" does not exist, skipping
3311 ALTER TABLE IF EXISTS tt8 RENAME COLUMN f TO f1;
3312 NOTICE: relation "tt8" does not exist, skipping
3313 ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2;
3314 NOTICE: relation "tt8" does not exist, skipping
3315 CREATE TABLE tt8(a int);
3316 CREATE SCHEMA alter2;
3317 ALTER TABLE IF EXISTS tt8 ADD COLUMN f int;
3318 ALTER TABLE IF EXISTS tt8 ADD CONSTRAINT xxx PRIMARY KEY(f);
3319 ALTER TABLE IF EXISTS tt8 ADD CHECK (f BETWEEN 0 AND 10);
3320 ALTER TABLE IF EXISTS tt8 ALTER COLUMN f SET DEFAULT 0;
3321 ALTER TABLE IF EXISTS tt8 RENAME COLUMN f TO f1;
3322 ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2;
3325 Column | Type | Collation | Nullable | Default
3326 --------+---------+-----------+----------+---------
3328 f1 | integer | | not null | 0
3330 "xxx" PRIMARY KEY, btree (f1)
3332 "tt8_f_check" CHECK (f1 >= 0 AND f1 <= 10)
3334 DROP TABLE alter2.tt8;
3337 -- Check conflicts between index and CHECK constraint names
3339 CREATE TABLE tt9(c integer);
3340 ALTER TABLE tt9 ADD CHECK(c > 1);
3341 ALTER TABLE tt9 ADD CHECK(c > 2); -- picks nonconflicting name
3342 ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 3);
3343 ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 4); -- fail, dup name
3344 ERROR: constraint "foo" for relation "tt9" already exists
3345 ALTER TABLE tt9 ADD UNIQUE(c);
3346 ALTER TABLE tt9 ADD UNIQUE(c); -- picks nonconflicting name
3347 ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key UNIQUE(c); -- fail, dup name
3348 ERROR: relation "tt9_c_key" already exists
3349 ALTER TABLE tt9 ADD CONSTRAINT foo UNIQUE(c); -- fail, dup name
3350 ERROR: constraint "foo" for relation "tt9" already exists
3351 ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key CHECK(c > 5); -- fail, dup name
3352 ERROR: constraint "tt9_c_key" for relation "tt9" already exists
3353 ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key2 CHECK(c > 6);
3354 ALTER TABLE tt9 ADD UNIQUE(c); -- picks nonconflicting name
3357 Column | Type | Collation | Nullable | Default
3358 --------+---------+-----------+----------+---------
3361 "tt9_c_key" UNIQUE CONSTRAINT, btree (c)
3362 "tt9_c_key1" UNIQUE CONSTRAINT, btree (c)
3363 "tt9_c_key3" UNIQUE CONSTRAINT, btree (c)
3366 "tt9_c_check" CHECK (c > 1)
3367 "tt9_c_check1" CHECK (c > 2)
3368 "tt9_c_key2" CHECK (c > 6)
3371 -- Check that comments on constraints and indexes are not lost at ALTER TABLE.
3372 CREATE TABLE comment_test (
3374 constraint id_notnull_constraint not null id,
3375 positive_col int CHECK (positive_col > 0),
3377 CONSTRAINT comment_test_pk PRIMARY KEY (id));
3378 CREATE INDEX comment_test_index ON comment_test(indexed_col);
3379 COMMENT ON COLUMN comment_test.id IS 'Column ''id'' on comment_test';
3380 COMMENT ON INDEX comment_test_index IS 'Simple index on comment_test';
3381 COMMENT ON CONSTRAINT comment_test_positive_col_check ON comment_test IS 'CHECK constraint on comment_test.positive_col';
3382 COMMENT ON CONSTRAINT comment_test_pk ON comment_test IS 'PRIMARY KEY constraint of comment_test';
3383 COMMENT ON CONSTRAINT id_notnull_constraint ON comment_test IS 'NOT NULL constraint of comment_test';
3384 COMMENT ON INDEX comment_test_pk IS 'Index backing the PRIMARY KEY of comment_test';
3385 SELECT col_description('comment_test'::regclass, 1) as comment;
3387 -----------------------------
3388 Column 'id' on comment_test
3391 SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test'::regclass ORDER BY 1, 2;
3393 --------------------+-----------------------------------------------
3394 comment_test_index | Simple index on comment_test
3395 comment_test_pk | Index backing the PRIMARY KEY of comment_test
3398 SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test'::regclass ORDER BY 1, 2;
3399 constraint | comment
3400 ---------------------------------+-----------------------------------------------
3401 comment_test_pk | PRIMARY KEY constraint of comment_test
3402 comment_test_positive_col_check | CHECK constraint on comment_test.positive_col
3403 id_notnull_constraint | NOT NULL constraint of comment_test
3406 -- Change the datatype of all the columns. ALTER TABLE is optimized to not
3407 -- rebuild an index if the new data type is binary compatible with the old
3408 -- one. Check do a dummy ALTER TABLE that doesn't change the datatype
3409 -- first, to test that no-op codepath, and another one that does.
3410 ALTER TABLE comment_test ALTER COLUMN indexed_col SET DATA TYPE int;
3411 ALTER TABLE comment_test ALTER COLUMN indexed_col SET DATA TYPE text;
3412 ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int;
3413 ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE text;
3414 ALTER TABLE comment_test ALTER COLUMN positive_col SET DATA TYPE int;
3415 ALTER TABLE comment_test ALTER COLUMN positive_col SET DATA TYPE bigint;
3416 -- Some error cases.
3417 ALTER TABLE comment_test ALTER COLUMN xmin SET DATA TYPE x;
3418 ERROR: cannot alter system column "xmin"
3419 ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE x;
3420 ERROR: type "x" does not exist
3421 ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int COLLATE "C";
3422 ERROR: collations are not supported by type integer
3423 -- Check that the comments are intact.
3424 SELECT col_description('comment_test'::regclass, 1) as comment;
3426 -----------------------------
3427 Column 'id' on comment_test
3430 SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test'::regclass ORDER BY 1, 2;
3432 --------------------+-----------------------------------------------
3433 comment_test_index | Simple index on comment_test
3434 comment_test_pk | Index backing the PRIMARY KEY of comment_test
3437 SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test'::regclass ORDER BY 1, 2;
3438 constraint | comment
3439 ---------------------------------+-----------------------------------------------
3440 comment_test_pk | PRIMARY KEY constraint of comment_test
3441 comment_test_positive_col_check | CHECK constraint on comment_test.positive_col
3442 id_notnull_constraint | NOT NULL constraint of comment_test
3445 -- Check compatibility for foreign keys and comments. This is done
3446 -- separately as rebuilding the column type of the parent leads
3447 -- to an error and would reduce the test scope.
3448 CREATE TABLE comment_test_child (
3449 id text CONSTRAINT comment_test_child_fk REFERENCES comment_test);
3450 CREATE INDEX comment_test_child_fk ON comment_test_child(id);
3451 COMMENT ON COLUMN comment_test_child.id IS 'Column ''id'' on comment_test_child';
3452 COMMENT ON INDEX comment_test_child_fk IS 'Index backing the FOREIGN KEY of comment_test_child';
3453 COMMENT ON CONSTRAINT comment_test_child_fk ON comment_test_child IS 'FOREIGN KEY constraint of comment_test_child';
3454 -- Change column type of parent
3455 ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE text;
3456 ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int USING id::integer;
3457 ERROR: foreign key constraint "comment_test_child_fk" cannot be implemented
3458 DETAIL: Key columns "id" of the referencing table and "id" of the referenced table are of incompatible types: text and integer.
3459 -- Comments should be intact
3460 SELECT col_description('comment_test_child'::regclass, 1) as comment;
3462 -----------------------------------
3463 Column 'id' on comment_test_child
3466 SELECT indexrelid::regclass::text as index, obj_description(indexrelid, 'pg_class') as comment FROM pg_index where indrelid = 'comment_test_child'::regclass ORDER BY 1, 2;
3468 -----------------------+-----------------------------------------------------
3469 comment_test_child_fk | Index backing the FOREIGN KEY of comment_test_child
3472 SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment FROM pg_constraint where conrelid = 'comment_test_child'::regclass ORDER BY 1, 2;
3473 constraint | comment
3474 -----------------------+----------------------------------------------
3475 comment_test_child_fk | FOREIGN KEY constraint of comment_test_child
3478 -- Check that we map relation oids to filenodes and back correctly. Only
3479 -- display bad mappings so the test output doesn't change all the time. A
3480 -- filenode function call can return NULL for a relation dropped concurrently
3481 -- with the call's surrounding query, so ignore a NULL mapped_oid for
3482 -- relations that no longer exist after all calls finish.
3483 CREATE TEMP TABLE filenode_mapping AS
3485 oid, mapped_oid, reltablespace, relfilenode, relname
3487 pg_filenode_relation(reltablespace, pg_relation_filenode(oid)) AS mapped_oid
3488 WHERE relkind IN ('r', 'i', 'S', 't', 'm') AND mapped_oid IS DISTINCT FROM oid;
3489 SELECT m.* FROM filenode_mapping m LEFT JOIN pg_class c ON c.oid = m.oid
3490 WHERE c.oid IS NOT NULL OR m.mapped_oid IS NOT NULL;
3491 oid | mapped_oid | reltablespace | relfilenode | relname
3492 -----+------------+---------------+-------------+---------
3495 -- Checks on creating and manipulation of user defined relations in
3497 SHOW allow_system_table_mods;
3498 allow_system_table_mods
3499 -------------------------
3503 -- disallowed because of search_path issues with pg_dump
3504 CREATE TABLE pg_catalog.new_system_table();
3505 ERROR: permission denied to create "pg_catalog.new_system_table"
3506 DETAIL: System catalog modifications are currently disallowed.
3507 -- instead create in public first, move to catalog
3508 CREATE TABLE new_system_table(id serial primary key, othercol text);
3509 ALTER TABLE new_system_table SET SCHEMA pg_catalog;
3510 ALTER TABLE new_system_table SET SCHEMA public;
3511 ALTER TABLE new_system_table SET SCHEMA pg_catalog;
3512 -- will be ignored -- already there:
3513 ALTER TABLE new_system_table SET SCHEMA pg_catalog;
3514 ALTER TABLE new_system_table RENAME TO old_system_table;
3515 CREATE INDEX old_system_table__othercol ON old_system_table (othercol);
3516 INSERT INTO old_system_table(othercol) VALUES ('somedata'), ('otherdata');
3517 UPDATE old_system_table SET id = -id;
3518 DELETE FROM old_system_table WHERE othercol = 'somedata';
3519 TRUNCATE old_system_table;
3520 ALTER TABLE old_system_table DROP CONSTRAINT new_system_table_pkey;
3521 ALTER TABLE old_system_table DROP COLUMN othercol;
3522 DROP TABLE old_system_table;
3524 CREATE UNLOGGED TABLE unlogged1(f1 SERIAL PRIMARY KEY, f2 TEXT); -- has sequence, toast
3525 -- check relpersistence of an unlogged table
3526 SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged1'
3528 SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^unlogged1'
3530 SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^unlogged1'
3532 relname | relkind | relpersistence
3533 -----------------------+---------+----------------
3535 unlogged1 toast index | i | u
3536 unlogged1 toast table | t | u
3537 unlogged1_f1_seq | S | u
3538 unlogged1_pkey | i | u
3541 CREATE UNLOGGED TABLE unlogged2(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES unlogged1); -- foreign key
3542 CREATE UNLOGGED TABLE unlogged3(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES unlogged3); -- self-referencing foreign key
3543 ALTER TABLE unlogged3 SET LOGGED; -- skip self-referencing foreign key
3544 ALTER TABLE unlogged2 SET LOGGED; -- fails because a foreign key to an unlogged table exists
3545 ERROR: could not change table "unlogged2" to logged because it references unlogged table "unlogged1"
3546 ALTER TABLE unlogged1 SET LOGGED;
3547 -- check relpersistence of an unlogged table after changing to permanent
3548 SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged1'
3550 SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^unlogged1'
3552 SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^unlogged1'
3554 relname | relkind | relpersistence
3555 -----------------------+---------+----------------
3557 unlogged1 toast index | i | p
3558 unlogged1 toast table | t | p
3559 unlogged1_f1_seq | S | p
3560 unlogged1_pkey | i | p
3563 ALTER TABLE unlogged1 SET LOGGED; -- silently do nothing
3564 DROP TABLE unlogged3;
3565 DROP TABLE unlogged2;
3566 DROP TABLE unlogged1;
3568 CREATE TABLE logged1(f1 SERIAL PRIMARY KEY, f2 TEXT); -- has sequence, toast
3569 -- check relpersistence of a permanent table
3570 SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^logged1'
3572 SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^logged1'
3574 SELECT r.relname ||' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^logged1'
3576 relname | relkind | relpersistence
3577 ---------------------+---------+----------------
3579 logged1 toast index | i | p
3580 logged1 toast table | t | p
3581 logged1_f1_seq | S | p
3582 logged1_pkey | i | p
3585 CREATE TABLE logged2(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES logged1); -- foreign key
3586 CREATE TABLE logged3(f1 SERIAL PRIMARY KEY, f2 INTEGER REFERENCES logged3); -- self-referencing foreign key
3587 ALTER TABLE logged1 SET UNLOGGED; -- fails because a foreign key from a permanent table exists
3588 ERROR: could not change table "logged1" to unlogged because it references logged table "logged2"
3589 ALTER TABLE logged3 SET UNLOGGED; -- skip self-referencing foreign key
3590 ALTER TABLE logged2 SET UNLOGGED;
3591 ALTER TABLE logged1 SET UNLOGGED;
3592 -- check relpersistence of a permanent table after changing to unlogged
3593 SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^logged1'
3595 SELECT r.relname || ' toast table', t.relkind, t.relpersistence FROM pg_class r JOIN pg_class t ON t.oid = r.reltoastrelid WHERE r.relname ~ '^logged1'
3597 SELECT r.relname || ' toast index', ri.relkind, ri.relpersistence FROM pg_class r join pg_class t ON t.oid = r.reltoastrelid JOIN pg_index i ON i.indrelid = t.oid JOIN pg_class ri ON ri.oid = i.indexrelid WHERE r.relname ~ '^logged1'
3599 relname | relkind | relpersistence
3600 ---------------------+---------+----------------
3602 logged1 toast index | i | u
3603 logged1 toast table | t | u
3604 logged1_f1_seq | S | u
3605 logged1_pkey | i | u
3608 ALTER TABLE logged1 SET UNLOGGED; -- silently do nothing
3612 -- test ADD COLUMN IF NOT EXISTS
3613 CREATE TABLE test_add_column(c1 integer);
3615 Table "public.test_add_column"
3616 Column | Type | Collation | Nullable | Default
3617 --------+---------+-----------+----------+---------
3620 ALTER TABLE test_add_column
3621 ADD COLUMN c2 integer;
3623 Table "public.test_add_column"
3624 Column | Type | Collation | Nullable | Default
3625 --------+---------+-----------+----------+---------
3629 ALTER TABLE test_add_column
3630 ADD COLUMN c2 integer; -- fail because c2 already exists
3631 ERROR: column "c2" of relation "test_add_column" already exists
3632 ALTER TABLE ONLY test_add_column
3633 ADD COLUMN c2 integer; -- fail because c2 already exists
3634 ERROR: column "c2" of relation "test_add_column" already exists
3636 Table "public.test_add_column"
3637 Column | Type | Collation | Nullable | Default
3638 --------+---------+-----------+----------+---------
3642 ALTER TABLE test_add_column
3643 ADD COLUMN IF NOT EXISTS c2 integer; -- skipping because c2 already exists
3644 NOTICE: column "c2" of relation "test_add_column" already exists, skipping
3645 ALTER TABLE ONLY test_add_column
3646 ADD COLUMN IF NOT EXISTS c2 integer; -- skipping because c2 already exists
3647 NOTICE: column "c2" of relation "test_add_column" already exists, skipping
3649 Table "public.test_add_column"
3650 Column | Type | Collation | Nullable | Default
3651 --------+---------+-----------+----------+---------
3655 ALTER TABLE test_add_column
3656 ADD COLUMN c2 integer, -- fail because c2 already exists
3657 ADD COLUMN c3 integer primary key;
3658 ERROR: column "c2" of relation "test_add_column" already exists
3660 Table "public.test_add_column"
3661 Column | Type | Collation | Nullable | Default
3662 --------+---------+-----------+----------+---------
3666 ALTER TABLE test_add_column
3667 ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists
3668 ADD COLUMN c3 integer primary key;
3669 NOTICE: column "c2" of relation "test_add_column" already exists, skipping
3671 Table "public.test_add_column"
3672 Column | Type | Collation | Nullable | Default
3673 --------+---------+-----------+----------+---------
3676 c3 | integer | | not null |
3678 "test_add_column_pkey" PRIMARY KEY, btree (c3)
3680 ALTER TABLE test_add_column
3681 ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists
3682 ADD COLUMN IF NOT EXISTS c3 integer primary key; -- skipping because c3 already exists
3683 NOTICE: column "c2" of relation "test_add_column" already exists, skipping
3684 NOTICE: column "c3" of relation "test_add_column" already exists, skipping
3686 Table "public.test_add_column"
3687 Column | Type | Collation | Nullable | Default
3688 --------+---------+-----------+----------+---------
3691 c3 | integer | | not null |
3693 "test_add_column_pkey" PRIMARY KEY, btree (c3)
3695 ALTER TABLE test_add_column
3696 ADD COLUMN IF NOT EXISTS c2 integer, -- skipping because c2 already exists
3697 ADD COLUMN IF NOT EXISTS c3 integer, -- skipping because c3 already exists
3698 ADD COLUMN c4 integer REFERENCES test_add_column;
3699 NOTICE: column "c2" of relation "test_add_column" already exists, skipping
3700 NOTICE: column "c3" of relation "test_add_column" already exists, skipping
3702 Table "public.test_add_column"
3703 Column | Type | Collation | Nullable | Default
3704 --------+---------+-----------+----------+---------
3707 c3 | integer | | not null |
3710 "test_add_column_pkey" PRIMARY KEY, btree (c3)
3711 Foreign-key constraints:
3712 "test_add_column_c4_fkey" FOREIGN KEY (c4) REFERENCES test_add_column(c3)
3714 TABLE "test_add_column" CONSTRAINT "test_add_column_c4_fkey" FOREIGN KEY (c4) REFERENCES test_add_column(c3)
3716 ALTER TABLE test_add_column
3717 ADD COLUMN IF NOT EXISTS c4 integer REFERENCES test_add_column;
3718 NOTICE: column "c4" of relation "test_add_column" already exists, skipping
3720 Table "public.test_add_column"
3721 Column | Type | Collation | Nullable | Default
3722 --------+---------+-----------+----------+---------
3725 c3 | integer | | not null |
3728 "test_add_column_pkey" PRIMARY KEY, btree (c3)
3729 Foreign-key constraints:
3730 "test_add_column_c4_fkey" FOREIGN KEY (c4) REFERENCES test_add_column(c3)
3732 TABLE "test_add_column" CONSTRAINT "test_add_column_c4_fkey" FOREIGN KEY (c4) REFERENCES test_add_column(c3)
3734 ALTER TABLE test_add_column
3735 ADD COLUMN IF NOT EXISTS c5 SERIAL CHECK (c5 > 8);
3737 Table "public.test_add_column"
3738 Column | Type | Collation | Nullable | Default
3739 --------+---------+-----------+----------+---------------------------------------------
3742 c3 | integer | | not null |
3744 c5 | integer | | not null | nextval('test_add_column_c5_seq'::regclass)
3746 "test_add_column_pkey" PRIMARY KEY, btree (c3)
3748 "test_add_column_c5_check" CHECK (c5 > 8)
3749 Foreign-key constraints:
3750 "test_add_column_c4_fkey" FOREIGN KEY (c4) REFERENCES test_add_column(c3)
3752 TABLE "test_add_column" CONSTRAINT "test_add_column_c4_fkey" FOREIGN KEY (c4) REFERENCES test_add_column(c3)
3754 ALTER TABLE test_add_column
3755 ADD COLUMN IF NOT EXISTS c5 SERIAL CHECK (c5 > 10);
3756 NOTICE: column "c5" of relation "test_add_column" already exists, skipping
3758 Table "public.test_add_column"
3759 Column | Type | Collation | Nullable | Default
3760 --------+---------+-----------+----------+---------------------------------------------
3763 c3 | integer | | not null |
3765 c5 | integer | | not null | nextval('test_add_column_c5_seq'::regclass)
3767 "test_add_column_pkey" PRIMARY KEY, btree (c3)
3769 "test_add_column_c5_check" CHECK (c5 > 8)
3770 Foreign-key constraints:
3771 "test_add_column_c4_fkey" FOREIGN KEY (c4) REFERENCES test_add_column(c3)
3773 TABLE "test_add_column" CONSTRAINT "test_add_column_c4_fkey" FOREIGN KEY (c4) REFERENCES test_add_column(c3)
3775 Sequence "public.test_add_column_c5_seq"
3776 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
3777 ---------+-------+---------+------------+-----------+---------+-------
3778 integer | 1 | 1 | 2147483647 | 1 | no | 1
3779 Owned by: public.test_add_column.c5
3781 Index "public.test_add_column_pkey"
3782 Column | Type | Key? | Definition
3783 --------+---------+------+------------
3784 c3 | integer | yes | c3
3785 primary key, btree, for table "public.test_add_column"
3787 DROP TABLE test_add_column;
3789 -- assorted cases with multiple ALTER TABLE steps
3790 CREATE TABLE ataddindex(f1 INT);
3791 INSERT INTO ataddindex VALUES (42), (43);
3792 CREATE UNIQUE INDEX ataddindexi0 ON ataddindex(f1);
3793 ALTER TABLE ataddindex
3794 ADD PRIMARY KEY USING INDEX ataddindexi0,
3795 ALTER f1 TYPE BIGINT;
3797 Table "public.ataddindex"
3798 Column | Type | Collation | Nullable | Default
3799 --------+--------+-----------+----------+---------
3800 f1 | bigint | | not null |
3802 "ataddindexi0" PRIMARY KEY, btree (f1)
3804 DROP TABLE ataddindex;
3805 CREATE TABLE ataddindex(f1 VARCHAR(10));
3806 INSERT INTO ataddindex(f1) VALUES ('foo'), ('a');
3807 ALTER TABLE ataddindex
3808 ALTER f1 SET DATA TYPE TEXT,
3809 ADD EXCLUDE ((f1 LIKE 'a') WITH =);
3811 Table "public.ataddindex"
3812 Column | Type | Collation | Nullable | Default
3813 --------+------+-----------+----------+---------
3816 "ataddindex_expr_excl" EXCLUDE USING btree ((f1 ~~ 'a'::text) WITH =)
3818 DROP TABLE ataddindex;
3819 CREATE TABLE ataddindex(id int, ref_id int);
3820 ALTER TABLE ataddindex
3821 ADD PRIMARY KEY (id),
3822 ADD FOREIGN KEY (ref_id) REFERENCES ataddindex;
3824 Table "public.ataddindex"
3825 Column | Type | Collation | Nullable | Default
3826 --------+---------+-----------+----------+---------
3827 id | integer | | not null |
3828 ref_id | integer | | |
3830 "ataddindex_pkey" PRIMARY KEY, btree (id)
3831 Foreign-key constraints:
3832 "ataddindex_ref_id_fkey" FOREIGN KEY (ref_id) REFERENCES ataddindex(id)
3834 TABLE "ataddindex" CONSTRAINT "ataddindex_ref_id_fkey" FOREIGN KEY (ref_id) REFERENCES ataddindex(id)
3836 DROP TABLE ataddindex;
3837 CREATE TABLE ataddindex(id int, ref_id int);
3838 ALTER TABLE ataddindex
3840 ADD FOREIGN KEY (ref_id) REFERENCES ataddindex (id);
3842 Table "public.ataddindex"
3843 Column | Type | Collation | Nullable | Default
3844 --------+---------+-----------+----------+---------
3846 ref_id | integer | | |
3848 "ataddindex_id_key" UNIQUE CONSTRAINT, btree (id)
3849 Foreign-key constraints:
3850 "ataddindex_ref_id_fkey" FOREIGN KEY (ref_id) REFERENCES ataddindex(id)
3852 TABLE "ataddindex" CONSTRAINT "ataddindex_ref_id_fkey" FOREIGN KEY (ref_id) REFERENCES ataddindex(id)
3854 DROP TABLE ataddindex;
3855 CREATE TABLE atnotnull1 ();
3856 ALTER TABLE atnotnull1
3858 ALTER a SET NOT NULL;
3859 ALTER TABLE atnotnull1
3862 ALTER TABLE atnotnull1
3864 ADD PRIMARY KEY (c);
3866 Table "public.atnotnull1"
3867 Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
3868 --------+---------+-----------+----------+---------+---------+--------------+-------------
3869 a | integer | | not null | | plain | |
3870 b | integer | | not null | | plain | |
3871 c | integer | | not null | | plain | |
3873 "atnotnull1_pkey" PRIMARY KEY, btree (c)
3874 Not-null constraints:
3875 "atnotnull1_a_not_null" NOT NULL "a"
3876 "atnotnull1_b_not_null" NOT NULL "b"
3877 "atnotnull1_c_not_null" NOT NULL "c"
3879 -- cannot drop column that is part of the partition key
3880 CREATE TABLE partitioned (
3883 ) PARTITION BY RANGE (a, (a+b+1));
3884 ALTER TABLE partitioned DROP COLUMN a;
3885 ERROR: cannot drop column "a" because it is part of the partition key of relation "partitioned"
3886 ALTER TABLE partitioned ALTER COLUMN a TYPE char(5);
3887 ERROR: cannot alter column "a" because it is part of the partition key of relation "partitioned"
3888 ALTER TABLE partitioned DROP COLUMN b;
3889 ERROR: cannot drop column "b" because it is part of the partition key of relation "partitioned"
3890 ALTER TABLE partitioned ALTER COLUMN b TYPE char(5);
3891 ERROR: cannot alter column "b" because it is part of the partition key of relation "partitioned"
3892 -- specifying storage parameters for partitioned tables is not supported
3893 ALTER TABLE partitioned SET (fillfactor=100);
3894 ERROR: cannot specify storage parameters for a partitioned table
3895 HINT: Specify storage parameters for its leaf partitions instead.
3896 -- partitioned table cannot participate in regular inheritance
3897 CREATE TABLE nonpartitioned (
3901 ALTER TABLE partitioned INHERIT nonpartitioned;
3902 ERROR: cannot change inheritance of partitioned table
3903 ALTER TABLE nonpartitioned INHERIT partitioned;
3904 ERROR: cannot inherit from partitioned table "partitioned"
3905 -- cannot add NO INHERIT constraint to partitioned tables
3906 ALTER TABLE partitioned ADD CONSTRAINT chk_a CHECK (a > 0) NO INHERIT;
3907 ERROR: cannot add NO INHERIT constraint to partitioned table "partitioned"
3908 DROP TABLE partitioned, nonpartitioned;
3912 -- check that target table is partitioned
3913 CREATE TABLE unparted (
3916 CREATE TABLE fail_part (like unparted);
3917 ALTER TABLE unparted ATTACH PARTITION fail_part FOR VALUES IN ('a');
3918 ERROR: ALTER action ATTACH PARTITION cannot be performed on relation "unparted"
3919 DETAIL: This operation is not supported for tables.
3920 DROP TABLE unparted, fail_part;
3921 -- check that partition bound is compatible
3922 CREATE TABLE list_parted (
3924 b char(2) COLLATE "C",
3925 CONSTRAINT check_a CHECK (a > 0)
3926 ) PARTITION BY LIST (a);
3927 CREATE TABLE fail_part (LIKE list_parted);
3928 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES FROM (1) TO (10);
3929 ERROR: invalid bound specification for a list partition
3930 LINE 1: ...list_parted ATTACH PARTITION fail_part FOR VALUES FROM (1) T...
3932 DROP TABLE fail_part;
3933 -- check that the table being attached exists
3934 ALTER TABLE list_parted ATTACH PARTITION nonexistent FOR VALUES IN (1);
3935 ERROR: relation "nonexistent" does not exist
3936 -- check ownership of the source table
3937 CREATE ROLE regress_test_me;
3938 CREATE ROLE regress_test_not_me;
3939 CREATE TABLE not_owned_by_me (LIKE list_parted);
3940 ALTER TABLE not_owned_by_me OWNER TO regress_test_not_me;
3941 SET SESSION AUTHORIZATION regress_test_me;
3942 CREATE TABLE owned_by_me (
3944 ) PARTITION BY LIST (a);
3945 ALTER TABLE owned_by_me ATTACH PARTITION not_owned_by_me FOR VALUES IN (1);
3946 ERROR: must be owner of table not_owned_by_me
3947 RESET SESSION AUTHORIZATION;
3948 DROP TABLE owned_by_me, not_owned_by_me;
3949 DROP ROLE regress_test_not_me;
3950 DROP ROLE regress_test_me;
3951 -- check that the table being attached is not part of regular inheritance
3952 CREATE TABLE parent (LIKE list_parted);
3953 CREATE TABLE child () INHERITS (parent);
3954 ALTER TABLE list_parted ATTACH PARTITION child FOR VALUES IN (1);
3955 ERROR: cannot attach inheritance child as partition
3956 ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
3957 ERROR: cannot attach inheritance parent as partition
3959 -- now it should work, with a little tweak
3960 ALTER TABLE parent ADD CONSTRAINT check_a CHECK (a > 0);
3961 ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
3962 -- test insert/update, per bug #18550
3963 INSERT INTO parent VALUES (1);
3964 UPDATE parent SET a = 2 WHERE a = 1;
3965 ERROR: new row for relation "parent" violates partition constraint
3966 DETAIL: Failing row contains (2, null).
3967 DROP TABLE parent CASCADE;
3968 -- check any TEMP-ness
3969 CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a);
3970 CREATE TABLE perm_part (a int);
3971 ALTER TABLE temp_parted ATTACH PARTITION perm_part FOR VALUES IN (1);
3972 ERROR: cannot attach a permanent relation as partition of temporary relation "temp_parted"
3973 DROP TABLE temp_parted, perm_part;
3974 -- check that the table being attached is not a typed table
3975 CREATE TYPE mytype AS (a int);
3976 CREATE TABLE fail_part OF mytype;
3977 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
3978 ERROR: cannot attach a typed table as partition
3979 DROP TYPE mytype CASCADE;
3980 NOTICE: drop cascades to table fail_part
3981 -- check that the table being attached has only columns present in the parent
3982 CREATE TABLE fail_part (like list_parted, c int);
3983 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
3984 ERROR: table "fail_part" contains column "c" not found in parent "list_parted"
3985 DETAIL: The new partition may contain only the columns present in parent.
3986 DROP TABLE fail_part;
3987 -- check that the table being attached has every column of the parent
3988 CREATE TABLE fail_part (a int NOT NULL);
3989 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
3990 ERROR: child table is missing column "b"
3991 DROP TABLE fail_part;
3992 -- check that columns match in type, collation and NOT NULL status
3993 CREATE TABLE fail_part (
3997 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
3998 ERROR: child table "fail_part" has different type for column "b"
3999 ALTER TABLE fail_part ALTER b TYPE char (2) COLLATE "POSIX";
4000 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
4001 ERROR: child table "fail_part" has different collation for column "b"
4002 DROP TABLE fail_part;
4003 -- check that the table being attached has all constraints of the parent
4004 CREATE TABLE fail_part (
4005 b char(2) COLLATE "C",
4008 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
4009 ERROR: child table is missing constraint "check_a"
4010 -- check that the constraint matches in definition with parent's constraint
4011 ALTER TABLE fail_part ADD CONSTRAINT check_a CHECK (a >= 0);
4012 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
4013 ERROR: child table "fail_part" has different definition for check constraint "check_a"
4014 DROP TABLE fail_part;
4015 -- check the attributes and constraints after partition is attached
4016 CREATE TABLE part_1 (
4018 b char(2) COLLATE "C",
4019 CONSTRAINT check_a CHECK (a > 0)
4021 ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (1);
4022 -- attislocal and conislocal are always false for merged attributes and constraints respectively.
4023 SELECT attislocal, attinhcount FROM pg_attribute WHERE attrelid = 'part_1'::regclass AND attnum > 0;
4024 attislocal | attinhcount
4025 ------------+-------------
4030 SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_1'::regclass AND conname = 'check_a';
4031 conislocal | coninhcount
4032 ------------+-------------
4036 -- check that NOT NULL NO INHERIT cannot be merged to a normal NOT NULL
4037 CREATE TABLE part_fail (a int NOT NULL NO INHERIT,
4038 b char(2) COLLATE "C",
4039 CONSTRAINT check_a CHECK (a > 0)
4041 ALTER TABLE list_parted ATTACH PARTITION part_fail FOR VALUES IN (2);
4042 ERROR: constraint "part_fail_a_not_null" conflicts with non-inherited constraint on child table "part_fail"
4043 DROP TABLE part_fail;
4044 -- check that the new partition won't overlap with an existing partition
4045 CREATE TABLE fail_part (LIKE part_1 INCLUDING CONSTRAINTS);
4046 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
4047 ERROR: partition "fail_part" would overlap partition "part_1"
4048 LINE 1: ...LE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
4050 DROP TABLE fail_part;
4051 -- check that an existing table can be attached as a default partition
4052 CREATE TABLE def_part (LIKE list_parted INCLUDING CONSTRAINTS);
4053 ALTER TABLE list_parted ATTACH PARTITION def_part DEFAULT;
4054 -- check attaching default partition fails if a default partition already
4056 CREATE TABLE fail_def_part (LIKE part_1 INCLUDING CONSTRAINTS);
4057 ALTER TABLE list_parted ATTACH PARTITION fail_def_part DEFAULT;
4058 ERROR: partition "fail_def_part" conflicts with existing default partition "def_part"
4059 LINE 1: ...ER TABLE list_parted ATTACH PARTITION fail_def_part DEFAULT;
4061 -- check validation when attaching list partitions
4062 CREATE TABLE list_parted2 (
4065 ) PARTITION BY LIST (a);
4066 -- check that violating rows are correctly reported
4067 CREATE TABLE part_2 (LIKE list_parted2);
4068 INSERT INTO part_2 VALUES (3, 'a');
4069 ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);
4070 ERROR: partition constraint of relation "part_2" is violated by some row
4071 -- should be ok after deleting the bad row
4073 ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);
4074 -- check partition cannot be attached if default has some row for its values
4075 CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT;
4076 INSERT INTO list_parted2_def VALUES (11, 'z');
4077 CREATE TABLE part_3 (LIKE list_parted2);
4078 ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11);
4079 ERROR: updated partition constraint for default partition "list_parted2_def" would be violated by some row
4080 -- should be ok after deleting the bad row
4081 DELETE FROM list_parted2_def WHERE a = 11;
4082 ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11);
4083 -- adding constraints that describe the desired partition constraint
4084 -- (or more restrictive) will help skip the validation scan
4085 CREATE TABLE part_3_4 (
4087 CONSTRAINT check_a CHECK (a IN (3))
4089 -- however, if a list partition does not accept nulls, there should be
4090 -- an explicit NOT NULL constraint on the partition key column for the
4091 -- validation scan to be skipped;
4092 ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4);
4093 -- adding a NOT NULL constraint will cause the scan to be skipped
4094 ALTER TABLE list_parted2 DETACH PARTITION part_3_4;
4095 ALTER TABLE part_3_4 ALTER a SET NOT NULL;
4096 ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4);
4097 -- check if default partition scan skipped
4098 ALTER TABLE list_parted2_def ADD CONSTRAINT check_a CHECK (a IN (5, 6));
4099 CREATE TABLE part_55_66 PARTITION OF list_parted2 FOR VALUES IN (55, 66);
4100 -- check validation when attaching range partitions
4101 CREATE TABLE range_parted (
4104 ) PARTITION BY RANGE (a, b);
4105 -- check that violating rows are correctly reported
4106 CREATE TABLE part1 (
4107 a int NOT NULL CHECK (a = 1),
4108 b int NOT NULL CHECK (b >= 1 AND b <= 10)
4110 INSERT INTO part1 VALUES (1, 10);
4111 -- Remember the TO bound is exclusive
4112 ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10);
4113 ERROR: partition constraint of relation "part1" is violated by some row
4114 -- should be ok after deleting the bad row
4116 ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10);
4117 -- adding constraints that describe the desired partition constraint
4118 -- (or more restrictive) will help skip the validation scan
4119 CREATE TABLE part2 (
4120 a int NOT NULL CHECK (a = 1),
4121 b int NOT NULL CHECK (b >= 10 AND b < 18)
4123 ALTER TABLE range_parted ATTACH PARTITION part2 FOR VALUES FROM (1, 10) TO (1, 20);
4124 -- Create default partition
4125 CREATE TABLE partr_def1 PARTITION OF range_parted DEFAULT;
4126 -- Only one default partition is allowed, hence, following should give error
4127 CREATE TABLE partr_def2 (LIKE part1 INCLUDING CONSTRAINTS);
4128 ALTER TABLE range_parted ATTACH PARTITION partr_def2 DEFAULT;
4129 ERROR: partition "partr_def2" conflicts with existing default partition "partr_def1"
4130 LINE 1: ...LTER TABLE range_parted ATTACH PARTITION partr_def2 DEFAULT;
4132 -- Overlapping partitions cannot be attached, hence, following should give error
4133 INSERT INTO partr_def1 VALUES (2, 10);
4134 CREATE TABLE part3 (LIKE range_parted);
4135 ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (2, 10) TO (2, 20);
4136 ERROR: updated partition constraint for default partition "partr_def1" would be violated by some row
4137 -- Attaching partitions should be successful when there are no overlapping rows
4138 ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (3, 10) TO (3, 20);
4139 -- check that leaf partitions are scanned when attaching a partitioned
4141 CREATE TABLE part_5 (
4143 ) PARTITION BY LIST (b);
4144 -- check that violating rows are correctly reported
4145 CREATE TABLE part_5_a PARTITION OF part_5 FOR VALUES IN ('a');
4146 INSERT INTO part_5_a (a, b) VALUES (6, 'a');
4147 ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5);
4148 ERROR: partition constraint of relation "part_5_a" is violated by some row
4149 -- delete the faulting row and also add a constraint to skip the scan
4150 DELETE FROM part_5_a WHERE a NOT IN (3);
4151 ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 5);
4152 ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5);
4153 ALTER TABLE list_parted2 DETACH PARTITION part_5;
4154 ALTER TABLE part_5 DROP CONSTRAINT check_a;
4155 -- scan should again be skipped, even though NOT NULL is now a column property
4156 ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IN (5)), ALTER a SET NOT NULL;
4157 ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5);
4158 -- Check the case where attnos of the partitioning columns in the table being
4159 -- attached differs from the parent. It should not affect the constraint-
4160 -- checking logic that allows to skip the scan.
4161 CREATE TABLE part_6 (
4164 CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 6)
4166 ALTER TABLE part_6 DROP c;
4167 ALTER TABLE list_parted2 ATTACH PARTITION part_6 FOR VALUES IN (6);
4168 -- Similar to above, but the table being attached is a partitioned table
4169 -- whose partition has still different attnos for the root partitioning
4171 CREATE TABLE part_7 (
4173 CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7)
4174 ) PARTITION BY LIST (b);
4175 CREATE TABLE part_7_a_null (
4179 LIKE list_parted2, -- 'a' will have attnum = 4
4180 CONSTRAINT check_b CHECK (b IS NULL OR b = 'a'),
4181 CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7)
4183 ALTER TABLE part_7_a_null DROP c, DROP d, DROP e;
4184 ALTER TABLE part_7 ATTACH PARTITION part_7_a_null FOR VALUES IN ('a', null);
4185 ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7);
4186 -- Same example, but check this time that the constraint correctly detects
4188 ALTER TABLE list_parted2 DETACH PARTITION part_7;
4189 ALTER TABLE part_7 DROP CONSTRAINT check_a; -- thusly, scan won't be skipped
4190 INSERT INTO part_7 (a, b) VALUES (8, null), (9, 'a');
4191 SELECT tableoid::regclass, a, b FROM part_7 order by a;
4193 ---------------+---+---
4195 part_7_a_null | 9 | a
4198 ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7);
4199 ERROR: partition constraint of relation "part_7_a_null" is violated by some row
4200 -- check that leaf partitions of default partition are scanned when
4201 -- attaching a partitioned table.
4202 ALTER TABLE part_5 DROP CONSTRAINT check_a;
4203 CREATE TABLE part5_def PARTITION OF part_5 DEFAULT PARTITION BY LIST(a);
4204 CREATE TABLE part5_def_p1 PARTITION OF part5_def FOR VALUES IN (5);
4205 INSERT INTO part5_def_p1 VALUES (5, 'y');
4206 CREATE TABLE part5_p1 (LIKE part_5);
4207 ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y');
4208 ERROR: updated partition constraint for default partition "part5_def_p1" would be violated by some row
4209 -- should be ok after deleting the bad row
4210 DELETE FROM part5_def_p1 WHERE b = 'y';
4211 ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y');
4212 -- check that the table being attached is not already a partition
4213 ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);
4214 ERROR: "part_2" is already a partition
4215 -- check that circular inheritance is not allowed
4216 ALTER TABLE part_5 ATTACH PARTITION list_parted2 FOR VALUES IN ('b');
4217 ERROR: circular inheritance not allowed
4218 DETAIL: "part_5" is already a child of "list_parted2".
4219 ALTER TABLE list_parted2 ATTACH PARTITION list_parted2 FOR VALUES IN (0);
4220 ERROR: circular inheritance not allowed
4221 DETAIL: "list_parted2" is already a child of "list_parted2".
4222 -- If a partitioned table being created or an existing table being attached
4223 -- as a partition does not have a constraint that would allow validation scan
4224 -- to be skipped, but an individual partition does, then the partition's
4225 -- validation scan is skipped.
4226 CREATE TABLE quuux (a int, b text) PARTITION BY LIST (a);
4227 CREATE TABLE quuux_default PARTITION OF quuux DEFAULT PARTITION BY LIST (b);
4228 CREATE TABLE quuux_default1 PARTITION OF quuux_default (
4229 CONSTRAINT check_1 CHECK (a IS NOT NULL AND a = 1)
4230 ) FOR VALUES IN ('b');
4231 CREATE TABLE quuux1 (a int, b text);
4232 ALTER TABLE quuux ATTACH PARTITION quuux1 FOR VALUES IN (1); -- validate!
4233 CREATE TABLE quuux2 (a int, b text);
4234 ALTER TABLE quuux ATTACH PARTITION quuux2 FOR VALUES IN (2); -- skip validation
4235 DROP TABLE quuux1, quuux2;
4236 -- should validate for quuux1, but not for quuux2
4237 CREATE TABLE quuux1 PARTITION OF quuux FOR VALUES IN (1);
4238 CREATE TABLE quuux2 PARTITION OF quuux FOR VALUES IN (2);
4240 -- check validation when attaching hash partitions
4241 -- Use hand-rolled hash functions and operator class to get predictable result
4242 -- on different machines. part_test_int4_ops is defined in test_setup.sql.
4243 -- check that the new partition won't overlap with an existing partition
4244 CREATE TABLE hash_parted (
4247 ) PARTITION BY HASH (a part_test_int4_ops);
4248 CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 0);
4249 CREATE TABLE fail_part (LIKE hpart_1);
4250 ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 4);
4251 ERROR: partition "fail_part" would overlap partition "hpart_1"
4252 LINE 1: ...hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODU...
4254 ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 0);
4255 ERROR: partition "fail_part" would overlap partition "hpart_1"
4256 LINE 1: ...hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODU...
4258 DROP TABLE fail_part;
4259 -- check validation when attaching hash partitions
4260 -- check that violating rows are correctly reported
4261 CREATE TABLE hpart_2 (LIKE hash_parted);
4262 INSERT INTO hpart_2 VALUES (3, 0);
4263 ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1);
4264 ERROR: partition constraint of relation "hpart_2" is violated by some row
4265 -- should be ok after deleting the bad row
4266 DELETE FROM hpart_2;
4267 ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1);
4268 -- check that leaf partitions are scanned when attaching a partitioned
4270 CREATE TABLE hpart_5 (
4272 ) PARTITION BY LIST (b);
4273 -- check that violating rows are correctly reported
4274 CREATE TABLE hpart_5_a PARTITION OF hpart_5 FOR VALUES IN ('1', '2', '3');
4275 INSERT INTO hpart_5_a (a, b) VALUES (7, 1);
4276 ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2);
4277 ERROR: partition constraint of relation "hpart_5_a" is violated by some row
4278 -- should be ok after deleting the bad row
4279 DELETE FROM hpart_5_a;
4280 ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2);
4281 -- check that the table being attach is with valid modulus and remainder value
4282 CREATE TABLE fail_part(LIKE hash_parted);
4283 ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 0, REMAINDER 1);
4284 ERROR: modulus for hash partition must be an integer value greater than zero
4285 ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 8);
4286 ERROR: remainder for hash partition must be less than modulus
4287 ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 3, REMAINDER 2);
4288 ERROR: every hash partition modulus must be a factor of the next larger modulus
4289 DETAIL: The new modulus 3 is not a factor of 4, the modulus of existing partition "hpart_1".
4290 DROP TABLE fail_part;
4294 -- check that the table is partitioned at all
4295 CREATE TABLE regular_table (a int);
4296 ALTER TABLE regular_table DETACH PARTITION any_name;
4297 ERROR: ALTER action DETACH PARTITION cannot be performed on relation "regular_table"
4298 DETAIL: This operation is not supported for tables.
4299 ALTER TABLE regular_table DETACH PARTITION any_name CONCURRENTLY;
4300 ERROR: ALTER action DETACH PARTITION cannot be performed on relation "regular_table"
4301 DETAIL: This operation is not supported for tables.
4302 ALTER TABLE regular_table DETACH PARTITION any_name FINALIZE;
4303 ERROR: ALTER action DETACH PARTITION ... FINALIZE cannot be performed on relation "regular_table"
4304 DETAIL: This operation is not supported for tables.
4305 DROP TABLE regular_table;
4306 -- check that the partition being detached exists at all
4307 ALTER TABLE list_parted2 DETACH PARTITION part_4;
4308 ERROR: relation "part_4" does not exist
4309 ALTER TABLE hash_parted DETACH PARTITION hpart_4;
4310 ERROR: relation "hpart_4" does not exist
4311 -- check that the partition being detached is actually a partition of the parent
4312 CREATE TABLE not_a_part (a int);
4313 ALTER TABLE list_parted2 DETACH PARTITION not_a_part;
4314 ERROR: relation "not_a_part" is not a partition of relation "list_parted2"
4315 ALTER TABLE list_parted2 DETACH PARTITION part_1;
4316 ERROR: relation "part_1" is not a partition of relation "list_parted2"
4317 ALTER TABLE hash_parted DETACH PARTITION not_a_part;
4318 ERROR: relation "not_a_part" is not a partition of relation "hash_parted"
4319 DROP TABLE not_a_part;
4320 -- check that, after being detached, attinhcount/coninhcount is dropped to 0 and
4321 -- attislocal/conislocal is set to true
4322 ALTER TABLE list_parted2 DETACH PARTITION part_3_4;
4323 SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::regclass AND attnum > 0;
4324 attinhcount | attislocal
4325 -------------+------------
4330 SELECT coninhcount, conislocal FROM pg_constraint WHERE conrelid = 'part_3_4'::regclass AND conname = 'check_a';
4331 coninhcount | conislocal
4332 -------------+------------
4336 DROP TABLE part_3_4;
4337 -- check that a detached partition is not dropped on dropping a partitioned table
4338 CREATE TABLE range_parted2 (
4340 ) PARTITION BY RANGE(a);
4341 CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100);
4342 ALTER TABLE range_parted2 DETACH PARTITION part_rp;
4343 DROP TABLE range_parted2;
4344 SELECT * from part_rp;
4350 -- concurrent detach
4351 CREATE TABLE range_parted2 (
4353 ) PARTITION BY RANGE(a);
4354 CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100);
4356 -- doesn't work in a partition block
4357 ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY;
4358 ERROR: ALTER TABLE ... DETACH CONCURRENTLY cannot run inside a transaction block
4360 CREATE TABLE part_rpd PARTITION OF range_parted2 DEFAULT;
4361 -- doesn't work if there's a default partition
4362 ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY;
4363 ERROR: cannot detach partitions concurrently when a default partition exists
4364 -- doesn't work for the default partition
4365 ALTER TABLE range_parted2 DETACH PARTITION part_rpd CONCURRENTLY;
4366 ERROR: cannot detach partitions concurrently when a default partition exists
4367 DROP TABLE part_rpd;
4369 ALTER TABLE range_parted2 DETACH PARTITION part_rp CONCURRENTLY;
4371 Partitioned table "public.range_parted2"
4372 Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
4373 --------+---------+-----------+----------+---------+---------+--------------+-------------
4374 a | integer | | | | plain | |
4375 Partition key: RANGE (a)
4376 Number of partitions: 0
4378 -- constraint should be created
4380 Table "public.part_rp"
4381 Column | Type | Collation | Nullable | Default
4382 --------+---------+-----------+----------+---------
4385 "part_rp_a_check" CHECK (a IS NOT NULL AND a >= 0 AND a < 100)
4387 CREATE TABLE part_rp100 PARTITION OF range_parted2 (CHECK (a>=123 AND a<133 AND a IS NOT NULL)) FOR VALUES FROM (100) to (200);
4388 ALTER TABLE range_parted2 DETACH PARTITION part_rp100 CONCURRENTLY;
4389 -- redundant constraint should not be created
4391 Table "public.part_rp100"
4392 Column | Type | Collation | Nullable | Default
4393 --------+---------+-----------+----------+---------
4396 "part_rp100_a_check" CHECK (a >= 123 AND a < 133 AND a IS NOT NULL)
4398 DROP TABLE range_parted2;
4399 -- Check ALTER TABLE commands for partitioned tables and partitions
4400 -- cannot add/drop column to/from *only* the parent
4401 ALTER TABLE ONLY list_parted2 ADD COLUMN c int;
4402 ERROR: column must be added to child tables too
4403 ALTER TABLE ONLY list_parted2 DROP COLUMN b;
4404 ERROR: cannot drop column from only the partitioned table when partitions exist
4405 HINT: Do not specify the ONLY keyword.
4406 -- cannot add a column to partition or drop an inherited one
4407 ALTER TABLE part_2 ADD COLUMN c text;
4408 ERROR: cannot add column to a partition
4409 ALTER TABLE part_2 DROP COLUMN b;
4410 ERROR: cannot drop inherited column "b"
4411 -- Nor rename, alter type
4412 ALTER TABLE part_2 RENAME COLUMN b to c;
4413 ERROR: cannot rename inherited column "b"
4414 ALTER TABLE part_2 ALTER COLUMN b TYPE text;
4415 ERROR: cannot alter inherited column "b"
4416 -- cannot add NOT NULL or check constraints to *only* the parent, when
4418 ALTER TABLE ONLY list_parted2 ALTER b SET NOT NULL;
4419 ERROR: constraint must be added to child tables too
4420 HINT: Do not specify the ONLY keyword.
4421 ALTER TABLE ONLY list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz');
4422 ERROR: constraint must be added to child tables too
4423 -- dropping them is ok though
4424 ALTER TABLE list_parted2 ALTER b SET NOT NULL;
4425 ALTER TABLE ONLY list_parted2 ALTER b DROP NOT NULL;
4426 ALTER TABLE list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz');
4427 ALTER TABLE ONLY list_parted2 DROP CONSTRAINT check_b;
4428 -- ... and the partitions should still have both
4430 Table "public.part_2"
4431 Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
4432 --------+--------------+-----------+----------+---------+----------+--------------+-------------
4433 a | integer | | | | plain | |
4434 b | character(1) | | not null | | extended | |
4435 Partition of: list_parted2 FOR VALUES IN (2)
4436 Partition constraint: ((a IS NOT NULL) AND (a = 2))
4438 "check_b" CHECK (b <> 'zz'::bpchar)
4439 Not-null constraints:
4440 "list_parted2_b_not_null" NOT NULL "b"
4442 -- It's alright though, if no partitions are yet created
4443 CREATE TABLE parted_no_parts (a int) PARTITION BY LIST (a);
4444 ALTER TABLE ONLY parted_no_parts ALTER a SET NOT NULL;
4445 ALTER TABLE ONLY parted_no_parts ADD CONSTRAINT check_a CHECK (a > 0);
4446 DROP TABLE parted_no_parts;
4447 -- cannot drop inherited NOT NULL or check constraints from partition
4448 ALTER TABLE list_parted2 ALTER b SET NOT NULL, ADD CONSTRAINT check_a2 CHECK (a > 0);
4449 ALTER TABLE part_2 ALTER b DROP NOT NULL;
4450 ERROR: column "b" is marked NOT NULL in parent table
4451 ALTER TABLE part_2 DROP CONSTRAINT check_a2;
4452 ERROR: cannot drop inherited constraint "check_a2" of relation "part_2"
4453 -- can't drop NOT NULL from under an invalid PK
4454 CREATE TABLE list_parted3 (a int NOT NULL) PARTITION BY LIST (a);
4455 CREATE TABLE list_parted3_1 PARTITION OF list_parted3 FOR VALUES IN (1);
4456 ALTER TABLE ONLY list_parted3 ADD PRIMARY KEY (a);
4457 ALTER TABLE ONLY list_parted3 DROP CONSTRAINT list_parted3_a_not_null;
4458 ERROR: column "a" is in a primary key
4459 -- Doesn't make sense to add NO INHERIT constraints on partitioned tables
4460 ALTER TABLE list_parted2 add constraint check_b2 check (b <> 'zz') NO INHERIT;
4461 ERROR: cannot add NO INHERIT constraint to partitioned table "list_parted2"
4462 -- check that a partition cannot participate in regular inheritance
4463 CREATE TABLE inh_test () INHERITS (part_2);
4464 ERROR: cannot inherit from partition "part_2"
4465 CREATE TABLE inh_test (LIKE part_2);
4466 ALTER TABLE inh_test INHERIT part_2;
4467 ERROR: cannot inherit from a partition
4468 ALTER TABLE part_2 INHERIT inh_test;
4469 ERROR: cannot change inheritance of a partition
4470 -- cannot drop or alter type of partition key columns of lower level
4471 -- partitioned tables; for example, part_5, which is list_parted2's
4472 -- partition, is partitioned on b;
4473 ALTER TABLE list_parted2 DROP COLUMN b;
4474 ERROR: cannot drop column "b" because it is part of the partition key of relation "part_5"
4475 ALTER TABLE list_parted2 ALTER COLUMN b TYPE text;
4476 ERROR: cannot alter column "b" because it is part of the partition key of relation "part_5"
4477 -- dropping non-partition key columns should be allowed on the parent table.
4478 ALTER TABLE list_parted DROP COLUMN b;
4479 SELECT * FROM list_parted;
4485 DROP TABLE list_parted, list_parted2, range_parted, list_parted3;
4486 DROP TABLE fail_def_part;
4487 DROP TABLE hash_parted;
4488 -- more tests for certain multi-level partitioning scenarios
4489 create table p (a int, b int) partition by range (a, b);
4490 create table p1 (b int, a int not null) partition by range (b);
4491 create table p11 (like p1);
4492 alter table p11 drop a;
4493 alter table p11 add a int;
4494 alter table p11 drop a;
4495 alter table p11 add a int not null;
4496 -- attnum for key attribute 'a' is different in p, p1, and p11
4497 select attrelid::regclass, attname, attnum
4500 and (attrelid = 'p'::regclass
4501 or attrelid = 'p1'::regclass
4502 or attrelid = 'p11'::regclass)
4503 order by attrelid::regclass::text;
4504 attrelid | attname | attnum
4505 ----------+---------+--------
4511 alter table p1 attach partition p11 for values from (2) to (5);
4512 insert into p1 (a, b) values (2, 3);
4513 -- check that partition validation scan correctly detects violating rows
4514 alter table p attach partition p1 for values from (1, 2) to (1, 10);
4515 ERROR: partition constraint of relation "p11" is violated by some row
4519 -- validate constraint on partitioned tables should only scan leaf partitions
4520 create table parted_validate_test (a int) partition by list (a);
4521 create table parted_validate_test_1 partition of parted_validate_test for values in (0, 1);
4522 alter table parted_validate_test add constraint parted_validate_test_chka check (a > 0) not valid;
4523 alter table parted_validate_test validate constraint parted_validate_test_chka;
4524 drop table parted_validate_test;
4525 -- test alter column options
4526 CREATE TABLE attmp(i integer);
4527 INSERT INTO attmp VALUES (1);
4528 ALTER TABLE attmp ALTER COLUMN i SET (n_distinct = 1, n_distinct_inherited = 2);
4529 ALTER TABLE attmp ALTER COLUMN i RESET (n_distinct_inherited);
4532 DROP USER regress_alter_table_user1;
4533 -- check that violating rows are correctly reported when attaching as the
4534 -- default partition
4535 create table defpart_attach_test (a int) partition by list (a);
4536 create table defpart_attach_test1 partition of defpart_attach_test for values in (1);
4537 create table defpart_attach_test_d (b int, a int);
4538 alter table defpart_attach_test_d drop b;
4539 insert into defpart_attach_test_d values (1), (2);
4540 -- error because its constraint as the default partition would be violated
4541 -- by the row containing 1
4542 alter table defpart_attach_test attach partition defpart_attach_test_d default;
4543 ERROR: partition constraint of relation "defpart_attach_test_d" is violated by some row
4544 delete from defpart_attach_test_d where a = 1;
4545 alter table defpart_attach_test_d add check (a > 1);
4546 -- should be attached successfully and without needing to be scanned
4547 alter table defpart_attach_test attach partition defpart_attach_test_d default;
4548 -- check that attaching a partition correctly reports any rows in the default
4549 -- partition that should not be there for the new partition to be attached
4551 create table defpart_attach_test_2 (like defpart_attach_test_d);
4552 alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2);
4553 ERROR: updated partition constraint for default partition "defpart_attach_test_d" would be violated by some row
4554 drop table defpart_attach_test;
4555 -- check combinations of temporary and permanent relations when attaching
4557 create table perm_part_parent (a int) partition by list (a);
4558 create temp table temp_part_parent (a int) partition by list (a);
4559 create table perm_part_child (a int);
4560 create temp table temp_part_child (a int);
4561 alter table temp_part_parent attach partition perm_part_child default; -- error
4562 ERROR: cannot attach a permanent relation as partition of temporary relation "temp_part_parent"
4563 alter table perm_part_parent attach partition temp_part_child default; -- error
4564 ERROR: cannot attach a temporary relation as partition of permanent relation "perm_part_parent"
4565 alter table temp_part_parent attach partition temp_part_child default; -- ok
4566 drop table perm_part_parent cascade;
4567 drop table temp_part_parent cascade;
4568 -- check that attaching partitions to a table while it is being used is
4570 create table tab_part_attach (a int) partition by list (a);
4571 create or replace function func_part_attach() returns trigger
4572 language plpgsql as $$
4574 execute 'create table tab_part_attach_1 (a int)';
4575 execute 'alter table tab_part_attach attach partition tab_part_attach_1 for values in (1)';
4578 create trigger trig_part_attach before insert on tab_part_attach
4579 for each statement execute procedure func_part_attach();
4580 insert into tab_part_attach values (1);
4581 ERROR: cannot ALTER TABLE "tab_part_attach" because it is being used by active queries in this session
4582 CONTEXT: SQL statement "alter table tab_part_attach attach partition tab_part_attach_1 for values in (1)"
4583 PL/pgSQL function func_part_attach() line 4 at EXECUTE
4584 drop table tab_part_attach;
4585 drop function func_part_attach();
4586 -- test case where the partitioning operator is a SQL function whose
4587 -- evaluation results in the table's relcache being rebuilt partway through
4588 -- the execution of an ATTACH PARTITION command
4589 create function at_test_sql_partop (int4, int4) returns int language sql
4590 as $$ select case when $1 = $2 then 0 when $1 > $2 then 1 else -1 end; $$;
4591 create operator class at_test_sql_partop for type int4 using btree as
4592 operator 1 < (int4, int4), operator 2 <= (int4, int4),
4593 operator 3 = (int4, int4), operator 4 >= (int4, int4),
4594 operator 5 > (int4, int4), function 1 at_test_sql_partop(int4, int4);
4595 create table at_test_sql_partop (a int) partition by range (a at_test_sql_partop);
4596 create table at_test_sql_partop_1 (a int);
4597 alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values from (0) to (10);
4598 drop table at_test_sql_partop;
4599 drop operator class at_test_sql_partop using btree;
4600 drop function at_test_sql_partop;
4601 /* Test case for bug #16242 */
4602 -- We create a parent and child where the child has missing
4603 -- non-null attribute values, and arrange to pass them through
4604 -- tuple conversion from the child to the parent tupdesc
4605 create table bar1 (a integer, b integer not null default 1)
4606 partition by range (a);
4607 create table bar2 (a integer);
4608 insert into bar2 values (1);
4609 alter table bar2 add column b integer not null default 1;
4610 -- (at this point bar2 contains tuple with natts=1)
4611 alter table bar1 attach partition bar2 default;
4619 -- this exercises tuple conversion:
4620 create function xtrig()
4621 returns trigger language plpgsql
4626 for r in select * from old loop
4627 raise info 'a=%, b=%', r.a, r.b;
4632 create trigger xtrig
4633 after update on bar1
4634 referencing old table as old
4635 for each statement execute procedure xtrig();
4636 update bar1 set a = a + 1;
4638 /* End test case for bug #16242 */
4639 /* Test case for bug #17409 */
4640 create table attbl (p1 int constraint pk_attbl primary key);
4641 create table atref (c1 int references attbl(p1));
4642 cluster attbl using pk_attbl;
4643 alter table attbl alter column p1 set data type bigint;
4644 alter table atref alter column c1 set data type bigint;
4645 drop table attbl, atref;
4646 create table attbl (p1 int constraint pk_attbl primary key);
4647 alter table attbl replica identity using index pk_attbl;
4648 create table atref (c1 int references attbl(p1));
4649 alter table attbl alter column p1 set data type bigint;
4650 alter table atref alter column c1 set data type bigint;
4651 drop table attbl, atref;
4652 /* End test case for bug #17409 */
4653 -- Test that ALTER TABLE rewrite preserves a clustered index
4654 -- for normal indexes and indexes on constraints.
4655 create table alttype_cluster (a int);
4656 alter table alttype_cluster add primary key (a);
4657 create index alttype_cluster_ind on alttype_cluster (a);
4658 alter table alttype_cluster cluster on alttype_cluster_ind;
4659 -- Normal index remains clustered.
4660 select indexrelid::regclass, indisclustered from pg_index
4661 where indrelid = 'alttype_cluster'::regclass
4662 order by indexrelid::regclass::text;
4663 indexrelid | indisclustered
4664 ----------------------+----------------
4665 alttype_cluster_ind | t
4666 alttype_cluster_pkey | f
4669 alter table alttype_cluster alter a type bigint;
4670 select indexrelid::regclass, indisclustered from pg_index
4671 where indrelid = 'alttype_cluster'::regclass
4672 order by indexrelid::regclass::text;
4673 indexrelid | indisclustered
4674 ----------------------+----------------
4675 alttype_cluster_ind | t
4676 alttype_cluster_pkey | f
4679 -- Constraint index remains clustered.
4680 alter table alttype_cluster cluster on alttype_cluster_pkey;
4681 select indexrelid::regclass, indisclustered from pg_index
4682 where indrelid = 'alttype_cluster'::regclass
4683 order by indexrelid::regclass::text;
4684 indexrelid | indisclustered
4685 ----------------------+----------------
4686 alttype_cluster_ind | f
4687 alttype_cluster_pkey | t
4690 alter table alttype_cluster alter a type int;
4691 select indexrelid::regclass, indisclustered from pg_index
4692 where indrelid = 'alttype_cluster'::regclass
4693 order by indexrelid::regclass::text;
4694 indexrelid | indisclustered
4695 ----------------------+----------------
4696 alttype_cluster_ind | f
4697 alttype_cluster_pkey | t
4700 drop table alttype_cluster;
4702 -- Check that attaching or detaching a partitioned partition correctly leads
4703 -- to its partitions' constraint being updated to reflect the parent's
4704 -- newly added/removed constraint
4705 create table target_parted (a int, b int) partition by list (a);
4706 create table attach_parted (a int, b int) partition by list (b);
4707 create table attach_parted_part1 partition of attach_parted for values in (1);
4708 -- insert a row directly into the leaf partition so that its partition
4709 -- constraint is built and stored in the relcache
4710 insert into attach_parted_part1 values (1, 1);
4711 -- the following better invalidate the partition constraint of the leaf
4713 alter table target_parted attach partition attach_parted for values in (1);
4714 -- ...such that the following insert fails
4715 insert into attach_parted_part1 values (2, 1);
4716 ERROR: new row for relation "attach_parted_part1" violates partition constraint
4717 DETAIL: Failing row contains (2, 1).
4718 -- ...and doesn't when the partition is detached along with its own partition
4719 alter table target_parted detach partition attach_parted;
4720 insert into attach_parted_part1 values (2, 1);
4721 -- Test altering table having publication
4722 create schema alter1;
4723 create schema alter2;
4724 create table alter1.t1 (a int);
4725 set client_min_messages = 'ERROR';
4726 create publication pub1 for table alter1.t1, tables in schema alter2;
4727 reset client_min_messages;
4728 alter table alter1.t1 set schema alter2;
4731 Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
4732 --------+---------+-----------+----------+---------+---------+--------------+-------------
4733 a | integer | | | | plain | |
4737 drop publication pub1;
4738 drop schema alter1 cascade;
4739 drop schema alter2 cascade;
4740 NOTICE: drop cascades to table alter2.t1