Skip to content

Commit 3422955

Browse files
committed
Consider only relations part of partition trees in partition functions
This changes the partition functions so as tables and indexes which are not part of partition trees are handled the same way as what is done for undefined objects and unsupported relkinds: pg_partition_tree() returns no rows and pg_partition_root() returns a NULL result. Hence, partitioned tables, partitioned indexes and relations whose flag pg_class.relispartition is set are considered as valid objects to process. Previously, tables and indexes not included in a partition tree were processed the same way as a partition or a partitioned table, which caused the functions to return inconsistent results for inherited tables, especially when inheriting from multiple tables. Reported-by: Álvaro Herrera Author: Amit Langote, Michael Paquier Reviewed-by: Tom Lane Discussion: https://postgr.es/m/[email protected]
1 parent 70b9bda commit 3422955

File tree

3 files changed

+55
-23
lines changed

3 files changed

+55
-23
lines changed

src/backend/utils/adt/partitionfuncs.c

+3-10
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,17 @@ static bool
3535
check_rel_can_be_partition(Oid relid)
3636
{
3737
char relkind;
38+
bool relispartition;
3839

3940
/* Check if relation exists */
4041
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relid)))
4142
return false;
4243

4344
relkind = get_rel_relkind(relid);
45+
relispartition = get_rel_relispartition(relid);
4446

4547
/* Only allow relation types that can appear in partition trees. */
46-
if (relkind != RELKIND_RELATION &&
47-
relkind != RELKIND_FOREIGN_TABLE &&
48-
relkind != RELKIND_INDEX &&
48+
if (!relispartition &&
4949
relkind != RELKIND_PARTITIONED_TABLE &&
5050
relkind != RELKIND_PARTITIONED_INDEX)
5151
return false;
@@ -189,13 +189,6 @@ pg_partition_root(PG_FUNCTION_ARGS)
189189
if (!check_rel_can_be_partition(relid))
190190
PG_RETURN_NULL();
191191

192-
/*
193-
* If the relation is not a partition (it may be the partition parent),
194-
* return itself as a result.
195-
*/
196-
if (!get_rel_relispartition(relid))
197-
PG_RETURN_OID(relid);
198-
199192
/* Fetch the top-most parent */
200193
ancestors = get_partition_ancestors(relid);
201194
rootrelid = llast_oid(ancestors);

src/test/regress/expected/partition_info.out

+37-11
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ CREATE TABLE ptif_test1 PARTITION OF ptif_test
3232
FOR VALUES FROM (0) TO (100) PARTITION BY list (b);
3333
CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1);
3434
CREATE TABLE ptif_test2 PARTITION OF ptif_test
35-
FOR VALUES FROM (100) TO (maxvalue);
35+
FOR VALUES FROM (100) TO (200);
36+
-- This partitioned table should remain with no partitions.
37+
CREATE TABLE ptif_test3 PARTITION OF ptif_test
38+
FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b);
3639
-- Test index partition tree
3740
CREATE INDEX ptif_test_index ON ONLY ptif_test (a);
3841
CREATE INDEX ptif_test0_index ON ONLY ptif_test0 (a);
@@ -45,6 +48,8 @@ CREATE INDEX ptif_test11_index ON ptif_test11 (a);
4548
ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index;
4649
CREATE INDEX ptif_test2_index ON ptif_test2 (a);
4750
ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index;
51+
CREATE INDEX ptif_test3_index ON ptif_test3 (a);
52+
ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index;
4853
-- List all tables members of the tree
4954
SELECT relid, parentrelid, level, isleaf
5055
FROM pg_partition_tree('ptif_test');
@@ -54,9 +59,10 @@ SELECT relid, parentrelid, level, isleaf
5459
ptif_test0 | ptif_test | 1 | f
5560
ptif_test1 | ptif_test | 1 | f
5661
ptif_test2 | ptif_test | 1 | t
62+
ptif_test3 | ptif_test | 1 | f
5763
ptif_test01 | ptif_test0 | 2 | t
5864
ptif_test11 | ptif_test1 | 2 | t
59-
(6 rows)
65+
(7 rows)
6066

6167
-- List tables from an intermediate level
6268
SELECT relid, parentrelid, level, isleaf
@@ -77,6 +83,15 @@ SELECT relid, parentrelid, level, isleaf
7783
ptif_test01 | ptif_test0 | 0 | t
7884
(1 row)
7985

86+
-- List from partitioned table with no partitions
87+
SELECT relid, parentrelid, level, isleaf
88+
FROM pg_partition_tree('ptif_test3') p
89+
JOIN pg_class c ON (p.relid = c.oid);
90+
relid | parentrelid | level | isleaf
91+
------------+-------------+-------+--------
92+
ptif_test3 | ptif_test | 0 | f
93+
(1 row)
94+
8095
-- List all members using pg_partition_root with leaf table reference
8196
SELECT relid, parentrelid, level, isleaf
8297
FROM pg_partition_tree(pg_partition_root('ptif_test01')) p
@@ -87,9 +102,10 @@ SELECT relid, parentrelid, level, isleaf
87102
ptif_test0 | ptif_test | 1 | f
88103
ptif_test1 | ptif_test | 1 | f
89104
ptif_test2 | ptif_test | 1 | t
105+
ptif_test3 | ptif_test | 1 | f
90106
ptif_test01 | ptif_test0 | 2 | t
91107
ptif_test11 | ptif_test1 | 2 | t
92-
(6 rows)
108+
(7 rows)
93109

94110
-- List all indexes members of the tree
95111
SELECT relid, parentrelid, level, isleaf
@@ -100,9 +116,10 @@ SELECT relid, parentrelid, level, isleaf
100116
ptif_test0_index | ptif_test_index | 1 | f
101117
ptif_test1_index | ptif_test_index | 1 | f
102118
ptif_test2_index | ptif_test_index | 1 | t
119+
ptif_test3_index | ptif_test_index | 1 | f
103120
ptif_test01_index | ptif_test0_index | 2 | t
104121
ptif_test11_index | ptif_test1_index | 2 | t
105-
(6 rows)
122+
(7 rows)
106123

107124
-- List indexes from an intermediate level
108125
SELECT relid, parentrelid, level, isleaf
@@ -123,6 +140,15 @@ SELECT relid, parentrelid, level, isleaf
123140
ptif_test01_index | ptif_test0_index | 0 | t
124141
(1 row)
125142

143+
-- List from partitioned index with no partitions
144+
SELECT relid, parentrelid, level, isleaf
145+
FROM pg_partition_tree('ptif_test3_index') p
146+
JOIN pg_class c ON (p.relid = c.oid);
147+
relid | parentrelid | level | isleaf
148+
------------------+-----------------+-------+--------
149+
ptif_test3_index | ptif_test_index | 0 | f
150+
(1 row)
151+
126152
-- List all members using pg_partition_root with leaf index reference
127153
SELECT relid, parentrelid, level, isleaf
128154
FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p
@@ -133,24 +159,24 @@ SELECT relid, parentrelid, level, isleaf
133159
ptif_test0_index | ptif_test_index | 1 | f
134160
ptif_test1_index | ptif_test_index | 1 | f
135161
ptif_test2_index | ptif_test_index | 1 | t
162+
ptif_test3_index | ptif_test_index | 1 | f
136163
ptif_test01_index | ptif_test0_index | 2 | t
137164
ptif_test11_index | ptif_test1_index | 2 | t
138-
(6 rows)
165+
(7 rows)
139166

140167
DROP TABLE ptif_test;
141-
-- Table that is not part of any partition tree is the only member listed.
168+
-- Table that is not part of any partition tree is not listed.
142169
CREATE TABLE ptif_normal_table(a int);
143170
SELECT relid, parentrelid, level, isleaf
144171
FROM pg_partition_tree('ptif_normal_table');
145-
relid | parentrelid | level | isleaf
146-
-------------------+-------------+-------+--------
147-
ptif_normal_table | | 0 | t
148-
(1 row)
172+
relid | parentrelid | level | isleaf
173+
-------+-------------+-------+--------
174+
(0 rows)
149175

150176
SELECT pg_partition_root('ptif_normal_table');
151177
pg_partition_root
152178
-------------------
153-
ptif_normal_table
179+
154180
(1 row)
155181

156182
DROP TABLE ptif_normal_table;

src/test/regress/sql/partition_info.sql

+15-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ CREATE TABLE ptif_test1 PARTITION OF ptif_test
1515
FOR VALUES FROM (0) TO (100) PARTITION BY list (b);
1616
CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1);
1717
CREATE TABLE ptif_test2 PARTITION OF ptif_test
18-
FOR VALUES FROM (100) TO (maxvalue);
18+
FOR VALUES FROM (100) TO (200);
19+
-- This partitioned table should remain with no partitions.
20+
CREATE TABLE ptif_test3 PARTITION OF ptif_test
21+
FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b);
1922

2023
-- Test index partition tree
2124
CREATE INDEX ptif_test_index ON ONLY ptif_test (a);
@@ -29,6 +32,8 @@ CREATE INDEX ptif_test11_index ON ptif_test11 (a);
2932
ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index;
3033
CREATE INDEX ptif_test2_index ON ptif_test2 (a);
3134
ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index;
35+
CREATE INDEX ptif_test3_index ON ptif_test3 (a);
36+
ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index;
3237

3338
-- List all tables members of the tree
3439
SELECT relid, parentrelid, level, isleaf
@@ -41,6 +46,10 @@ SELECT relid, parentrelid, level, isleaf
4146
SELECT relid, parentrelid, level, isleaf
4247
FROM pg_partition_tree('ptif_test01') p
4348
JOIN pg_class c ON (p.relid = c.oid);
49+
-- List from partitioned table with no partitions
50+
SELECT relid, parentrelid, level, isleaf
51+
FROM pg_partition_tree('ptif_test3') p
52+
JOIN pg_class c ON (p.relid = c.oid);
4453
-- List all members using pg_partition_root with leaf table reference
4554
SELECT relid, parentrelid, level, isleaf
4655
FROM pg_partition_tree(pg_partition_root('ptif_test01')) p
@@ -57,14 +66,18 @@ SELECT relid, parentrelid, level, isleaf
5766
SELECT relid, parentrelid, level, isleaf
5867
FROM pg_partition_tree('ptif_test01_index') p
5968
JOIN pg_class c ON (p.relid = c.oid);
69+
-- List from partitioned index with no partitions
70+
SELECT relid, parentrelid, level, isleaf
71+
FROM pg_partition_tree('ptif_test3_index') p
72+
JOIN pg_class c ON (p.relid = c.oid);
6073
-- List all members using pg_partition_root with leaf index reference
6174
SELECT relid, parentrelid, level, isleaf
6275
FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p
6376
JOIN pg_class c ON (p.relid = c.oid);
6477

6578
DROP TABLE ptif_test;
6679

67-
-- Table that is not part of any partition tree is the only member listed.
80+
-- Table that is not part of any partition tree is not listed.
6881
CREATE TABLE ptif_normal_table(a int);
6982
SELECT relid, parentrelid, level, isleaf
7083
FROM pg_partition_tree('ptif_normal_table');

0 commit comments

Comments
 (0)