]> granicus.if.org Git - postgresql/commitdiff
Consider only relations part of partition trees in partition functions
authorMichael Paquier <michael@paquier.xyz>
Sat, 2 Mar 2019 09:18:59 +0000 (18:18 +0900)
committerMichael Paquier <michael@paquier.xyz>
Sat, 2 Mar 2019 09:18:59 +0000 (18:18 +0900)
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/20190228193203.GA26151@alvherre.pgsql

src/backend/utils/adt/partitionfuncs.c
src/test/regress/expected/partition_info.out
src/test/regress/sql/partition_info.sql

index 36d9f69cbccd72f76cb37adc7dd6740087112f4a..a2fe4f34b6d5114c3bcc02d5ea7e099f9fd02d34 100644 (file)
@@ -35,17 +35,17 @@ static bool
 check_rel_can_be_partition(Oid relid)
 {
        char            relkind;
+       bool            relispartition;
 
        /* Check if relation exists */
        if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relid)))
                return false;
 
        relkind = get_rel_relkind(relid);
+       relispartition = get_rel_relispartition(relid);
 
        /* Only allow relation types that can appear in partition trees. */
-       if (relkind != RELKIND_RELATION &&
-               relkind != RELKIND_FOREIGN_TABLE &&
-               relkind != RELKIND_INDEX &&
+       if (!relispartition &&
                relkind != RELKIND_PARTITIONED_TABLE &&
                relkind != RELKIND_PARTITIONED_INDEX)
                return false;
@@ -189,13 +189,6 @@ pg_partition_root(PG_FUNCTION_ARGS)
        if (!check_rel_can_be_partition(relid))
                PG_RETURN_NULL();
 
-       /*
-        * If the relation is not a partition (it may be the partition parent),
-        * return itself as a result.
-        */
-       if (!get_rel_relispartition(relid))
-               PG_RETURN_OID(relid);
-
        /* Fetch the top-most parent */
        ancestors = get_partition_ancestors(relid);
        rootrelid = llast_oid(ancestors);
index 73269ffd09d3beb86608b0c11f1e7cd6f1e0e8ec..c1ba53d74d1cb17410d085eda0532f81df824cde 100644 (file)
@@ -32,7 +32,10 @@ CREATE TABLE ptif_test1 PARTITION OF ptif_test
   FOR VALUES FROM (0) TO (100) PARTITION BY list (b);
 CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1);
 CREATE TABLE ptif_test2 PARTITION OF ptif_test
-  FOR VALUES FROM (100) TO (maxvalue);
+  FOR VALUES FROM (100) TO (200);
+-- This partitioned table should remain with no partitions.
+CREATE TABLE ptif_test3 PARTITION OF ptif_test
+  FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b);
 -- Test index partition tree
 CREATE INDEX ptif_test_index ON ONLY ptif_test (a);
 CREATE INDEX ptif_test0_index ON ONLY ptif_test0 (a);
@@ -45,6 +48,8 @@ CREATE INDEX ptif_test11_index ON ptif_test11 (a);
 ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index;
 CREATE INDEX ptif_test2_index ON ptif_test2 (a);
 ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index;
+CREATE INDEX ptif_test3_index ON ptif_test3 (a);
+ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index;
 -- List all tables members of the tree
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree('ptif_test');
@@ -54,9 +59,10 @@ SELECT relid, parentrelid, level, isleaf
  ptif_test0  | ptif_test   |     1 | f
  ptif_test1  | ptif_test   |     1 | f
  ptif_test2  | ptif_test   |     1 | t
+ ptif_test3  | ptif_test   |     1 | f
  ptif_test01 | ptif_test0  |     2 | t
  ptif_test11 | ptif_test1  |     2 | t
-(6 rows)
+(7 rows)
 
 -- List tables from an intermediate level
 SELECT relid, parentrelid, level, isleaf
@@ -77,6 +83,15 @@ SELECT relid, parentrelid, level, isleaf
  ptif_test01 | ptif_test0  |     0 | t
 (1 row)
 
+-- List from partitioned table with no partitions
+SELECT relid, parentrelid, level, isleaf
+  FROM pg_partition_tree('ptif_test3') p
+  JOIN pg_class c ON (p.relid = c.oid);
+   relid    | parentrelid | level | isleaf 
+------------+-------------+-------+--------
+ ptif_test3 | ptif_test   |     0 | f
+(1 row)
+
 -- List all members using pg_partition_root with leaf table reference
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree(pg_partition_root('ptif_test01')) p
@@ -87,9 +102,10 @@ SELECT relid, parentrelid, level, isleaf
  ptif_test0  | ptif_test   |     1 | f
  ptif_test1  | ptif_test   |     1 | f
  ptif_test2  | ptif_test   |     1 | t
+ ptif_test3  | ptif_test   |     1 | f
  ptif_test01 | ptif_test0  |     2 | t
  ptif_test11 | ptif_test1  |     2 | t
-(6 rows)
+(7 rows)
 
 -- List all indexes members of the tree
 SELECT relid, parentrelid, level, isleaf
@@ -100,9 +116,10 @@ SELECT relid, parentrelid, level, isleaf
  ptif_test0_index  | ptif_test_index  |     1 | f
  ptif_test1_index  | ptif_test_index  |     1 | f
  ptif_test2_index  | ptif_test_index  |     1 | t
+ ptif_test3_index  | ptif_test_index  |     1 | f
  ptif_test01_index | ptif_test0_index |     2 | t
  ptif_test11_index | ptif_test1_index |     2 | t
-(6 rows)
+(7 rows)
 
 -- List indexes from an intermediate level
 SELECT relid, parentrelid, level, isleaf
@@ -123,6 +140,15 @@ SELECT relid, parentrelid, level, isleaf
  ptif_test01_index | ptif_test0_index |     0 | t
 (1 row)
 
+-- List from partitioned index with no partitions
+SELECT relid, parentrelid, level, isleaf
+  FROM pg_partition_tree('ptif_test3_index') p
+  JOIN pg_class c ON (p.relid = c.oid);
+      relid       |   parentrelid   | level | isleaf 
+------------------+-----------------+-------+--------
+ ptif_test3_index | ptif_test_index |     0 | f
+(1 row)
+
 -- List all members using pg_partition_root with leaf index reference
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p
@@ -133,24 +159,24 @@ SELECT relid, parentrelid, level, isleaf
  ptif_test0_index  | ptif_test_index  |     1 | f
  ptif_test1_index  | ptif_test_index  |     1 | f
  ptif_test2_index  | ptif_test_index  |     1 | t
+ ptif_test3_index  | ptif_test_index  |     1 | f
  ptif_test01_index | ptif_test0_index |     2 | t
  ptif_test11_index | ptif_test1_index |     2 | t
-(6 rows)
+(7 rows)
 
 DROP TABLE ptif_test;
--- Table that is not part of any partition tree is the only member listed.
+-- Table that is not part of any partition tree is not listed.
 CREATE TABLE ptif_normal_table(a int);
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree('ptif_normal_table');
-       relid       | parentrelid | level | isleaf 
--------------------+-------------+-------+--------
- ptif_normal_table |             |     0 | t
-(1 row)
+ relid | parentrelid | level | isleaf 
+-------+-------------+-------+--------
+(0 rows)
 
 SELECT pg_partition_root('ptif_normal_table');
  pg_partition_root 
 -------------------
- ptif_normal_table
 (1 row)
 
 DROP TABLE ptif_normal_table;
index 119b90afe456e34fb0d1697c9169c166e11fdb21..44a0abe7e2136f9cb35c018b3afb15b71b136462 100644 (file)
@@ -15,7 +15,10 @@ CREATE TABLE ptif_test1 PARTITION OF ptif_test
   FOR VALUES FROM (0) TO (100) PARTITION BY list (b);
 CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1);
 CREATE TABLE ptif_test2 PARTITION OF ptif_test
-  FOR VALUES FROM (100) TO (maxvalue);
+  FOR VALUES FROM (100) TO (200);
+-- This partitioned table should remain with no partitions.
+CREATE TABLE ptif_test3 PARTITION OF ptif_test
+  FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b);
 
 -- Test index partition tree
 CREATE INDEX ptif_test_index ON ONLY ptif_test (a);
@@ -29,6 +32,8 @@ CREATE INDEX ptif_test11_index ON ptif_test11 (a);
 ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index;
 CREATE INDEX ptif_test2_index ON ptif_test2 (a);
 ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index;
+CREATE INDEX ptif_test3_index ON ptif_test3 (a);
+ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index;
 
 -- List all tables members of the tree
 SELECT relid, parentrelid, level, isleaf
@@ -41,6 +46,10 @@ SELECT relid, parentrelid, level, isleaf
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree('ptif_test01') p
   JOIN pg_class c ON (p.relid = c.oid);
+-- List from partitioned table with no partitions
+SELECT relid, parentrelid, level, isleaf
+  FROM pg_partition_tree('ptif_test3') p
+  JOIN pg_class c ON (p.relid = c.oid);
 -- List all members using pg_partition_root with leaf table reference
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree(pg_partition_root('ptif_test01')) p
@@ -57,6 +66,10 @@ SELECT relid, parentrelid, level, isleaf
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree('ptif_test01_index') p
   JOIN pg_class c ON (p.relid = c.oid);
+-- List from partitioned index with no partitions
+SELECT relid, parentrelid, level, isleaf
+  FROM pg_partition_tree('ptif_test3_index') p
+  JOIN pg_class c ON (p.relid = c.oid);
 -- List all members using pg_partition_root with leaf index reference
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p
@@ -64,7 +77,7 @@ SELECT relid, parentrelid, level, isleaf
 
 DROP TABLE ptif_test;
 
--- Table that is not part of any partition tree is the only member listed.
+-- Table that is not part of any partition tree is not listed.
 CREATE TABLE ptif_normal_table(a int);
 SELECT relid, parentrelid, level, isleaf
   FROM pg_partition_tree('ptif_normal_table');