summaryrefslogtreecommitdiff
path: root/src/test/regress/expected/create_table.out
blob: fb2b26ff5e4b29e26a0d7d08ae7a5e41ac6f9a8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
--
-- CREATE_TABLE
--
--
-- CLASS DEFINITIONS
--
CREATE TABLE hobbies_r (
	name		text,
	person 		text
);
CREATE TABLE equipment_r (
	name 		text,
	hobby		text
);
CREATE TABLE onek (
	unique1		int4,
	unique2		int4,
	two			int4,
	four		int4,
	ten			int4,
	twenty		int4,
	hundred		int4,
	thousand	int4,
	twothousand	int4,
	fivethous	int4,
	tenthous	int4,
	odd			int4,
	even		int4,
	stringu1	name,
	stringu2	name,
	string4		name
);
CREATE TABLE tenk1 (
	unique1		int4,
	unique2		int4,
	two			int4,
	four		int4,
	ten			int4,
	twenty		int4,
	hundred		int4,
	thousand	int4,
	twothousand	int4,
	fivethous	int4,
	tenthous	int4,
	odd			int4,
	even		int4,
	stringu1	name,
	stringu2	name,
	string4		name
) WITH OIDS;
CREATE TABLE tenk2 (
	unique1 	int4,
	unique2 	int4,
	two 	 	int4,
	four 		int4,
	ten			int4,
	twenty 		int4,
	hundred 	int4,
	thousand 	int4,
	twothousand int4,
	fivethous 	int4,
	tenthous	int4,
	odd			int4,
	even		int4,
	stringu1	name,
	stringu2	name,
	string4		name
);
CREATE TABLE person (
	name 		text,
	age			int4,
	location 	point
);
CREATE TABLE emp (
	salary 		int4,
	manager 	name
) INHERITS (person) WITH OIDS;
CREATE TABLE student (
	gpa 		float8
) INHERITS (person);
CREATE TABLE stud_emp (
	percent 	int4
) INHERITS (emp, student);
NOTICE:  merging multiple inherited definitions of column "name"
NOTICE:  merging multiple inherited definitions of column "age"
NOTICE:  merging multiple inherited definitions of column "location"
CREATE TABLE city (
	name		name,
	location 	box,
	budget 		city_budget
);
CREATE TABLE dept (
	dname		name,
	mgrname 	text
);
CREATE TABLE slow_emp4000 (
	home_base	 box
);
CREATE TABLE fast_emp4000 (
	home_base	 box
);
CREATE TABLE road (
	name		text,
	thepath 	path
);
CREATE TABLE ihighway () INHERITS (road);
CREATE TABLE shighway (
	surface		text
) INHERITS (road);
CREATE TABLE real_city (
	pop			int4,
	cname		text,
	outline 	path
);
--
-- test the "star" operators a bit more thoroughly -- this time,
-- throw in lots of NULL fields...
--
-- a is the type root
-- b and c inherit from a (one-level single inheritance)
-- d inherits from b and c (two-level multiple inheritance)
-- e inherits from c (two-level single inheritance)
-- f inherits from e (three-level single inheritance)
--
CREATE TABLE a_star (
	class		char,
	a 			int4
);
CREATE TABLE b_star (
	b 			text
) INHERITS (a_star);
CREATE TABLE c_star (
	c 			name
) INHERITS (a_star);
CREATE TABLE d_star (
	d 			float8
) INHERITS (b_star, c_star);
NOTICE:  merging multiple inherited definitions of column "class"
NOTICE:  merging multiple inherited definitions of column "a"
CREATE TABLE e_star (
	e 			int2
) INHERITS (c_star);
CREATE TABLE f_star (
	f 			polygon
) INHERITS (e_star);
CREATE TABLE aggtest (
	a 			int2,
	b			float4
);
CREATE TABLE hash_i4_heap (
	seqno 		int4,
	random 		int4
) DISTRIBUTE BY REPLICATION;
CREATE TABLE hash_name_heap (
	seqno 		int4,
	random 		name
) DISTRIBUTE BY REPLICATION;
CREATE TABLE hash_txt_heap (
	seqno 		int4,
	random 		text
) DISTRIBUTE BY REPLICATION;
CREATE TABLE hash_f8_heap (
	seqno		int4,
	random 		float8
) DISTRIBUTE BY REPLICATION;
-- don't include the hash_ovfl_heap stuff in the distribution
-- the data set is too large for what it's worth
--
-- CREATE TABLE hash_ovfl_heap (
--	x			int4,
--	y			int4
-- );
CREATE TABLE bt_i4_heap (
	seqno 		int4,
	random 		int4
);
CREATE TABLE bt_name_heap (
	seqno 		name,
	random 		int4
);
CREATE TABLE bt_txt_heap (
	seqno 		text,
	random 		int4
);
CREATE TABLE bt_f8_heap (
	seqno 		float8,
	random 		int4
);
CREATE TABLE array_op_test (
	seqno		int4,
	i			int4[],
	t			text[]
);
CREATE TABLE array_index_op_test (
	seqno		int4,
	i			int4[],
	t			text[]
);
CREATE TABLE testjsonb (
       j jsonb
);
CREATE TABLE unknowntab (
	u unknown    -- fail
);
ERROR:  column "u" has pseudo-type unknown
CREATE TYPE unknown_comptype AS (
	u unknown    -- fail
);
ERROR:  column "u" has pseudo-type unknown
CREATE TABLE IF NOT EXISTS test_tsvector(
	t text,
	a tsvector
);
CREATE TABLE IF NOT EXISTS test_tsvector(
	t text
);
NOTICE:  relation "test_tsvector" already exists, skipping
CREATE UNLOGGED TABLE unlogged1 (a int primary key);			-- OK
CREATE TEMPORARY TABLE unlogged2 (a int primary key);			-- OK
SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname;
    relname     | relkind | relpersistence 
----------------+---------+----------------
 unlogged1      | r       | u
 unlogged1_pkey | i       | u
 unlogged2      | r       | t
 unlogged2_pkey | i       | t
(4 rows)

REINDEX INDEX unlogged1_pkey;
REINDEX INDEX unlogged2_pkey;
SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname;
    relname     | relkind | relpersistence 
----------------+---------+----------------
 unlogged1      | r       | u
 unlogged1_pkey | i       | u
 unlogged2      | r       | t
 unlogged2_pkey | i       | t
(4 rows)

DROP TABLE unlogged2;
INSERT INTO unlogged1 VALUES (42);
CREATE UNLOGGED TABLE public.unlogged2 (a int primary key);		-- also OK
CREATE UNLOGGED TABLE pg_temp.unlogged3 (a int primary key);	-- not OK
ERROR:  only temporary relations may be created in temporary schemas
LINE 1: CREATE UNLOGGED TABLE pg_temp.unlogged3 (a int primary key);
                              ^
CREATE TABLE pg_temp.implicitly_temp (a int primary key);		-- OK
CREATE TEMP TABLE explicitly_temp (a int primary key);			-- also OK
CREATE TEMP TABLE pg_temp.doubly_temp (a int primary key);		-- also OK
CREATE TEMP TABLE public.temp_to_perm (a int primary key);		-- not OK
ERROR:  cannot create temporary relation in non-temporary schema
LINE 1: CREATE TEMP TABLE public.temp_to_perm (a int primary key);
                          ^
DROP TABLE unlogged1, public.unlogged2;
CREATE TABLE as_select1 AS SELECT * FROM pg_attribute WHERE attstorage = 'p';
CREATE TABLE as_select1 AS SELECT * FROM pg_attribute WHERE attstorage = 'p';
ERROR:  relation "as_select1" already exists
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_attribute WHERE attstorage = 'p';
NOTICE:  relation "as_select1" already exists, skipping
DROP TABLE as_select1;
-- check that the oid column is added before the primary key is checked
CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
DROP TABLE oid_pk;
--
-- Partitioned tables
--
-- cannot combine INHERITS and PARTITION BY (although grammar allows)
CREATE TABLE partitioned (
	a int
) INHERITS (some_table) PARTITION BY LIST (a);
ERROR:  cannot create partitioned table as inheritance child
-- cannot use more than 1 column as partition key for list partitioned table
CREATE TABLE partitioned (
	a1 int,
	a2 int
) PARTITION BY LIST (a1, a2);	-- fail
ERROR:  cannot use "list" partition strategy with more than one column
-- unsupported constraint type for partitioned tables
CREATE TABLE partitioned (
	a int PRIMARY KEY
) PARTITION BY RANGE (a);
ERROR:  primary key constraints are not supported on partitioned tables
LINE 2:  a int PRIMARY KEY
               ^
CREATE TABLE pkrel (
	a int PRIMARY KEY
);
CREATE TABLE partitioned (
	a int REFERENCES pkrel(a)
) PARTITION BY RANGE (a);
ERROR:  foreign key constraints are not supported on partitioned tables
LINE 2:  a int REFERENCES pkrel(a)
               ^
DROP TABLE pkrel;
CREATE TABLE partitioned (
	a int UNIQUE
) PARTITION BY RANGE (a);
ERROR:  unique constraints are not supported on partitioned tables
LINE 2:  a int UNIQUE
               ^
CREATE TABLE partitioned (
	a int,
	EXCLUDE USING gist (a WITH &&)
) PARTITION BY RANGE (a);
ERROR:  exclusion constraints are not supported on partitioned tables
LINE 3:  EXCLUDE USING gist (a WITH &&)
         ^
-- prevent column from being used twice in the partition key
CREATE TABLE partitioned (
	a int
) PARTITION BY RANGE (a, a);
ERROR:  column "a" appears more than once in partition key
-- prevent using prohibited expressions in the key
CREATE FUNCTION retset (a int) RETURNS SETOF int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE;
CREATE TABLE partitioned (
	a int
) PARTITION BY RANGE (retset(a));
ERROR:  set-returning functions are not allowed in partition key expressions
DROP FUNCTION retset(int);
CREATE TABLE partitioned (
	a int
) PARTITION BY RANGE ((avg(a)));
ERROR:  aggregate functions are not allowed in partition key expression
CREATE TABLE partitioned (
	a int,
	b int
) PARTITION BY RANGE ((avg(a) OVER (PARTITION BY b)));
ERROR:  window functions are not allowed in partition key expression
CREATE TABLE partitioned (
	a int
) PARTITION BY LIST ((a LIKE (SELECT 1)));
ERROR:  cannot use subquery in partition key expression
CREATE TABLE partitioned (
	a int
) PARTITION BY RANGE (('a'));
ERROR:  cannot use constant expression as partition key
CREATE FUNCTION const_func () RETURNS int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE;
CREATE TABLE partitioned (
	a int
) PARTITION BY RANGE (const_func());
ERROR:  cannot use constant expression as partition key
DROP FUNCTION const_func();
-- only accept "list" and "range" as partitioning strategy
CREATE TABLE partitioned (
	a int
) PARTITION BY HASH (a);
ERROR:  unrecognized partitioning strategy "hash"
-- specified column must be present in the table
CREATE TABLE partitioned (
	a int
) PARTITION BY RANGE (b);
ERROR:  column "b" named in partition key does not exist
-- cannot use system columns in partition key
CREATE TABLE partitioned (
	a int
) PARTITION BY RANGE (xmin);
ERROR:  cannot use system column "xmin" in partition key
-- functions in key must be immutable
CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL;
CREATE TABLE partitioned (
	a int
) PARTITION BY RANGE (immut_func(a));
ERROR:  functions in partition key expression must be marked IMMUTABLE
DROP FUNCTION immut_func(int);
-- cannot contain whole-row references
CREATE TABLE partitioned (
	a	int
) PARTITION BY RANGE ((partitioned));
ERROR:  partition key expressions cannot contain whole-row references
-- prevent using columns of unsupported types in key (type must have a btree operator class)
CREATE TABLE partitioned (
	a point
) PARTITION BY LIST (a);
ERROR:  data type point has no default btree operator class
HINT:  You must specify a btree operator class or define a default btree operator class for the data type.
CREATE TABLE partitioned (
	a point
) PARTITION BY LIST (a point_ops);
ERROR:  operator class "point_ops" does not exist for access method "btree"
CREATE TABLE partitioned (
	a point
) PARTITION BY RANGE (a);
ERROR:  data type point has no default btree operator class
HINT:  You must specify a btree operator class or define a default btree operator class for the data type.
CREATE TABLE partitioned (
	a point
) PARTITION BY RANGE (a point_ops);
ERROR:  operator class "point_ops" does not exist for access method "btree"
-- cannot add NO INHERIT constraints to partitioned tables
CREATE TABLE partitioned (
	a int,
	CONSTRAINT check_a CHECK (a > 0) NO INHERIT
) PARTITION BY RANGE (a);
ERROR:  cannot add NO INHERIT constraint to partitioned table "partitioned"
-- some checks after successful creation of a partitioned table
CREATE FUNCTION plusone(a int) RETURNS INT AS $$ SELECT a+1; $$ LANGUAGE SQL;
CREATE TABLE partitioned (
	a int,
	b int,
	c text,
	d text
) PARTITION BY RANGE (a oid_ops, plusone(b), c collate "default", d collate "C");
-- check relkind
SELECT relkind FROM pg_class WHERE relname = 'partitioned';
 relkind 
---------
 p
(1 row)

-- prevent a function referenced in partition key from being dropped
DROP FUNCTION plusone(int);
ERROR:  cannot drop function plusone(integer) because other objects depend on it
DETAIL:  table partitioned depends on function plusone(integer)
HINT:  Use DROP ... CASCADE to drop the dependent objects too.
-- partitioned table cannot participate in regular inheritance
CREATE TABLE partitioned2 (
	a int
) PARTITION BY LIST ((a+1));
CREATE TABLE fail () INHERITS (partitioned2);
ERROR:  cannot inherit from partitioned table "partitioned2"
-- Partition key in describe output
\d partitioned
            Table "public.partitioned"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 a      | integer |           |          | 
 b      | integer |           |          | 
 c      | text    |           |          | 
 d      | text    |           |          | 
Partition key: RANGE (a oid_ops, plusone(b), c, d COLLATE "C")

\d partitioned2
            Table "public.partitioned2"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 a      | integer |           |          | 
Partition key: LIST (((a + 1)))

DROP TABLE partitioned, partitioned2;
--
-- Partitions
--
-- check partition bound syntax
CREATE TABLE list_parted (
	a int
) PARTITION BY LIST (a);
-- syntax allows only string literal, numeric literal and null to be
-- specified for a partition bound value
CREATE TABLE part_1 PARTITION OF list_parted FOR VALUES IN ('1');
CREATE TABLE part_2 PARTITION OF list_parted FOR VALUES IN (2);
CREATE TABLE part_null PARTITION OF list_parted FOR VALUES IN (null);
CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN (int '1');
ERROR:  syntax error at or near "int"
LINE 1: ... fail_part PARTITION OF list_parted FOR VALUES IN (int '1');
                                                              ^
CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN ('1'::int);
ERROR:  syntax error at or near "::"
LINE 1: ...fail_part PARTITION OF list_parted FOR VALUES IN ('1'::int);
                                                                ^
-- syntax does not allow empty list of values for list partitions
CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN ();
ERROR:  syntax error at or near ")"
LINE 1: ...E TABLE fail_part PARTITION OF list_parted FOR VALUES IN ();
                                                                     ^
-- trying to specify range for list partitioned table
CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES FROM (1) TO (2);
ERROR:  invalid bound specification for a list partition
LINE 1: ...BLE fail_part PARTITION OF list_parted FOR VALUES FROM (1) T...
                                                             ^
-- specified literal can't be cast to the partition column data type
CREATE TABLE bools (
	a bool
) PARTITION BY LIST (a);
CREATE TABLE bools_true PARTITION OF bools FOR VALUES IN (1);
ERROR:  specified value cannot be cast to type boolean for column "a"
LINE 1: ...REATE TABLE bools_true PARTITION OF bools FOR VALUES IN (1);
                                                                    ^
DROP TABLE bools;
-- specified literal can be cast, but cast isn't immutable
CREATE TABLE moneyp (
	a money
) PARTITION BY LIST (a);
CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10);
ERROR:  specified value cannot be cast to type money for column "a"
LINE 1: ...EATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10);
                                                                   ^
DETAIL:  The cast requires a non-immutable conversion.
HINT:  Try putting the literal value in single quotes.
CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN ('10');
DROP TABLE moneyp;
-- immutable cast should work, though
CREATE TABLE bigintp (
	a bigint
) PARTITION BY LIST (a);
CREATE TABLE bigintp_10 PARTITION OF bigintp FOR VALUES IN (10);
-- fails due to overlap:
CREATE TABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10');
ERROR:  partition "bigintp_10_2" would overlap partition "bigintp_10"
DROP TABLE bigintp;
CREATE TABLE range_parted (
	a date
) PARTITION BY RANGE (a);
-- trying to specify list for range partitioned table
CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES IN ('a');
ERROR:  invalid bound specification for a range partition
LINE 1: ...BLE fail_part PARTITION OF range_parted FOR VALUES IN ('a');
                                                              ^
-- each of start and end bounds must have same number of values as the
-- length of the partition key
CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('z');
ERROR:  FROM must specify exactly one value per partitioning column
CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a') TO ('z', 1);
ERROR:  TO must specify exactly one value per partitioning column
-- cannot specify null values in range bounds
CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (maxvalue);
ERROR:  cannot specify NULL in range bound
-- check if compatible with the specified parent
-- cannot create as partition of a non-partitioned table
CREATE TABLE unparted (
	a int
);
CREATE TABLE fail_part PARTITION OF unparted FOR VALUES IN ('a');
ERROR:  "unparted" is not partitioned
DROP TABLE unparted;
-- cannot create a permanent rel as partition of a temp rel
CREATE TEMP TABLE temp_parted (
	a int
) PARTITION BY LIST (a);
CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a');
ERROR:  cannot create a permanent relation as partition of temporary relation "temp_parted"
DROP TABLE temp_parted;
-- cannot create a table with oids as partition of table without oids
CREATE TABLE no_oids_parted (
	a int
) PARTITION BY RANGE (a) WITHOUT OIDS;
CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10) WITH OIDS;
ERROR:  cannot create table with OIDs as partition of table without OIDs
DROP TABLE no_oids_parted;
-- If the partitioned table has oids, then the partition must have them.
-- If the WITHOUT OIDS option is specified for partition, it is overridden.
CREATE TABLE oids_parted (
	a int
) PARTITION BY RANGE (a) WITH OIDS;
CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS;
\d+ part_forced_oids
                             Table "public.part_forced_oids"
 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description 
--------+---------+-----------+----------+---------+---------+--------------+-------------
 a      | integer |           |          |         | plain   |              | 
Partition of: oids_parted FOR VALUES FROM (1) TO (10)
Partition constraint: ((a IS NOT NULL) AND (a >= 1) AND (a < 10))
Has OIDs: yes
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

DROP TABLE oids_parted, part_forced_oids;
-- check for partition bound overlap and other invalid specifications
CREATE TABLE list_parted2 (
	a varchar
) PARTITION BY LIST (a);
CREATE TABLE part_null_z PARTITION OF list_parted2 FOR VALUES IN (null, 'z');
CREATE TABLE part_ab PARTITION OF list_parted2 FOR VALUES IN ('a', 'b');
CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN (null);
ERROR:  partition "fail_part" would overlap partition "part_null_z"
CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('b', 'c');
ERROR:  partition "fail_part" would overlap partition "part_ab"
CREATE TABLE range_parted2 (
	a int
) PARTITION BY RANGE (a);
-- trying to create range partition with empty range
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0);
ERROR:  empty range bound specified for partition "fail_part"
DETAIL:  Specified lower bound (1) is greater than or equal to upper bound (0).
-- note that the range '[1, 1)' has no elements
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1);
ERROR:  empty range bound specified for partition "fail_part"
DETAIL:  Specified lower bound (1) is greater than or equal to upper bound (1).
CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1);
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2);
ERROR:  partition "fail_part" would overlap partition "part0"
CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10);
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue);
ERROR:  partition "fail_part" would overlap partition "part1"
CREATE TABLE part2 PARTITION OF range_parted2 FOR VALUES FROM (20) TO (30);
CREATE TABLE part3 PARTITION OF range_parted2 FOR VALUES FROM (30) TO (40);
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (30);
ERROR:  partition "fail_part" would overlap partition "part2"
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (50);
ERROR:  partition "fail_part" would overlap partition "part2"
-- now check for multi-column range partition key
CREATE TABLE range_parted3 (
	a int,
	b int
) PARTITION BY RANGE (a, (b+1));
CREATE TABLE part00 PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, maxvalue);
CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, 1);
ERROR:  partition "fail_part" would overlap partition "part00"
CREATE TABLE part10 PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, 1);
CREATE TABLE part11 PARTITION OF range_parted3 FOR VALUES FROM (1, 1) TO (1, 10);
CREATE TABLE part12 PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, maxvalue);
CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, 20);
ERROR:  partition "fail_part" would overlap partition "part12"
-- cannot create a partition that says column b is allowed to range
-- from -infinity to +infinity, while there exist partitions that have
-- more specific ranges
CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, maxvalue);
ERROR:  partition "fail_part" would overlap partition "part10"
-- check schema propagation from parent
CREATE TABLE parted (
	a text,
	b int NOT NULL DEFAULT 0,
	CONSTRAINT check_a CHECK (length(a) > 0)
) PARTITION BY LIST (a);
CREATE TABLE part_a PARTITION OF parted FOR VALUES IN ('a');
-- only inherited attributes (never local ones)
SELECT attname, attislocal, attinhcount FROM pg_attribute
  WHERE attrelid = 'part_a'::regclass and attnum > 0
  ORDER BY attnum;
 attname | attislocal | attinhcount 
---------+------------+-------------
 a       | f          |           1
 b       | f          |           1
(2 rows)

-- able to specify column default, column constraint, and table constraint
-- first check the "column specified more than once" error
CREATE TABLE part_b PARTITION OF parted (
	b NOT NULL,
	b DEFAULT 1,
	b CHECK (b >= 0),
	CONSTRAINT check_a CHECK (length(a) > 0)
) FOR VALUES IN ('b');
ERROR:  column "b" specified more than once
CREATE TABLE part_b PARTITION OF parted (
	b NOT NULL DEFAULT 1 CHECK (b >= 0),
	CONSTRAINT check_a CHECK (length(a) > 0)
) FOR VALUES IN ('b');
NOTICE:  merging constraint "check_a" with inherited definition
-- conislocal should be false for any merged constraints
SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass AND conname = 'check_a';
 conislocal | coninhcount 
------------+-------------
 f          |           1
(1 row)

-- specify PARTITION BY for a partition
CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c);
ERROR:  column "c" named in partition key does not exist
CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b));
-- create a level-2 partition
CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
-- Partition bound in describe output
\d+ part_b
                                   Table "public.part_b"
 Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+---------+-----------+----------+---------+----------+--------------+-------------
 a      | text    |           |          |         | extended |              | 
 b      | integer |           | not null | 1       | plain    |              | 
Partition of: parted FOR VALUES IN ('b')
Partition constraint: ((a IS NOT NULL) AND (a = ANY (ARRAY['b'::text])))
Check constraints:
    "check_a" CHECK (length(a) > 0)
    "part_b_b_check" CHECK (b >= 0)
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

-- Both partition bound and partition key in describe output
\d+ part_c
                                   Table "public.part_c"
 Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+---------+-----------+----------+---------+----------+--------------+-------------
 a      | text    |           |          |         | extended |              | 
 b      | integer |           | not null | 0       | plain    |              | 
Partition of: parted FOR VALUES IN ('c')
Partition constraint: ((a IS NOT NULL) AND (a = ANY (ARRAY['c'::text])))
Partition key: RANGE (b)
Check constraints:
    "check_a" CHECK (length(a) > 0)
Partitions: part_c_1_10 FOR VALUES FROM (1) TO (10)
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

-- a level-2 partition's constraint will include the parent's expressions
\d+ part_c_1_10
                                Table "public.part_c_1_10"
 Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+---------+-----------+----------+---------+----------+--------------+-------------
 a      | text    |           |          |         | extended |              | 
 b      | integer |           | not null | 0       | plain    |              | 
Partition of: part_c FOR VALUES FROM (1) TO (10)
Partition constraint: ((a IS NOT NULL) AND (a = ANY (ARRAY['c'::text])) AND (b IS NOT NULL) AND (b >= 1) AND (b < 10))
Check constraints:
    "check_a" CHECK (length(a) > 0)
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

-- Show partition count in the parent's describe output
-- Tempted to include \d+ output listing partitions with bound info but
-- output could vary depending on the order in which partition oids are
-- returned.
\d parted
               Table "public.parted"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 a      | text    |           |          | 
 b      | integer |           | not null | 0
Partition key: LIST (a)
Check constraints:
    "check_a" CHECK (length(a) > 0)
Number of partitions: 3 (Use \d+ to list them.)

-- check that we get the expected partition constraints
CREATE TABLE range_parted4 (a int, b int, c int) PARTITION BY RANGE (abs(a), abs(b), c);
CREATE TABLE unbounded_range_part PARTITION OF range_parted4 FOR VALUES FROM (MINVALUE, 0, 0) TO (MAXVALUE, 0, 0);
\d+ unbounded_range_part
                           Table "public.unbounded_range_part"
 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description 
--------+---------+-----------+----------+---------+---------+--------------+-------------
 a      | integer |           |          |         | plain   |              | 
 b      | integer |           |          |         | plain   |              | 
 c      | integer |           |          |         | plain   |              | 
Partition of: range_parted4 FOR VALUES FROM (MINVALUE, 0, 0) TO (MAXVALUE, 0, 0)
Partition constraint: ((abs(a) IS NOT NULL) AND (abs(b) IS NOT NULL) AND (c IS NOT NULL))
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

DROP TABLE unbounded_range_part;
CREATE TABLE range_parted4_1 PARTITION OF range_parted4 FOR VALUES FROM (MINVALUE, 0, 0) TO (1, MAXVALUE, 0);
\d+ range_parted4_1
                              Table "public.range_parted4_1"
 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description 
--------+---------+-----------+----------+---------+---------+--------------+-------------
 a      | integer |           |          |         | plain   |              | 
 b      | integer |           |          |         | plain   |              | 
 c      | integer |           |          |         | plain   |              | 
Partition of: range_parted4 FOR VALUES FROM (MINVALUE, 0, 0) TO (1, MAXVALUE, 0)
Partition constraint: ((abs(a) IS NOT NULL) AND (abs(b) IS NOT NULL) AND (c IS NOT NULL) AND (abs(a) <= 1))
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

CREATE TABLE range_parted4_2 PARTITION OF range_parted4 FOR VALUES FROM (3, 4, 5) TO (6, 7, MAXVALUE);
\d+ range_parted4_2
                              Table "public.range_parted4_2"
 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description 
--------+---------+-----------+----------+---------+---------+--------------+-------------
 a      | integer |           |          |         | plain   |              | 
 b      | integer |           |          |         | plain   |              | 
 c      | integer |           |          |         | plain   |              | 
Partition of: range_parted4 FOR VALUES FROM (3, 4, 5) TO (6, 7, MAXVALUE)
Partition constraint: ((abs(a) IS NOT NULL) AND (abs(b) IS NOT NULL) AND (c IS NOT NULL) AND ((abs(a) > 3) OR ((abs(a) = 3) AND (abs(b) > 4)) OR ((abs(a) = 3) AND (abs(b) = 4) AND (c >= 5))) AND ((abs(a) < 6) OR ((abs(a) = 6) AND (abs(b) <= 7))))
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

CREATE TABLE range_parted4_3 PARTITION OF range_parted4 FOR VALUES FROM (6, 8, MINVALUE) TO (9, MAXVALUE, 0);
\d+ range_parted4_3
                              Table "public.range_parted4_3"
 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description 
--------+---------+-----------+----------+---------+---------+--------------+-------------
 a      | integer |           |          |         | plain   |              | 
 b      | integer |           |          |         | plain   |              | 
 c      | integer |           |          |         | plain   |              | 
Partition of: range_parted4 FOR VALUES FROM (6, 8, MINVALUE) TO (9, MAXVALUE, 0)
Partition constraint: ((abs(a) IS NOT NULL) AND (abs(b) IS NOT NULL) AND (c IS NOT NULL) AND ((abs(a) > 6) OR ((abs(a) = 6) AND (abs(b) >= 8))) AND (abs(a) <= 9))
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

DROP TABLE range_parted4;
-- cleanup
DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3;
-- comments on partitioned tables columns
CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a);
COMMENT ON TABLE parted_col_comment IS 'Am partitioned table';
COMMENT ON COLUMN parted_col_comment.a IS 'Partition key';
SELECT obj_description('parted_col_comment'::regclass);
   obj_description    
----------------------
 Am partitioned table
(1 row)

\d+ parted_col_comment
                              Table "public.parted_col_comment"
 Column |  Type   | Collation | Nullable | Default | Storage  | Stats target |  Description  
--------+---------+-----------+----------+---------+----------+--------------+---------------
 a      | integer |           |          |         | plain    |              | Partition key
 b      | text    |           |          |         | extended |              | 
Partition key: LIST (a)
Distribute By: HASH(a)
Location Nodes: ALL DATANODES

DROP TABLE parted_col_comment;