On Thu, Feb 28, 2019 at 11:50:16PM -0500, Tom Lane wrote:
> FWIW, I don't agree with Michael's suggestion above.  A plain table is
> significantly different from a partitioned table with no children:
> you can store rows in the former but not the latter, and you can add
> partitions to the latter but not the former.  So conflating the two
> doesn't seem likely to lead to any good outcome.

Okay, so the opinion moves into this direction.  What would be needed
is just something like the attached patch then based on Amit's
suggestion?  The routine names and comments looked fine to me so I
have not touched the surroundings, and comments are welcome.

> But, having said that, we've learned that it's generally bad for
> catalog-query functions to fail outright just because they're pointed
> at the wrong kind of catalog object.  So I think that what we want here
> is for pg_partition_tree to return NULL or an empty set or some such
> for a plain table, while its output for a childless partitioned table
> should be visibly different from that.  I'm not wedded to details
> beyond that idea.

Yep, that's the intention since cc53123.  I won't come back to return
an ERROR in any case.  Here is what the patch gives for childless
partitions FWIW:
=# CREATE TABLE ptif_test (a int, b int) PARTITION BY range (a);
CREATE TABLE
=# SELECT * FROM pg_partition_tree('ptif_test');
   relid   | parentrelid | isleaf | level
-----------+-------------+--------+-------
 ptif_test | null        | f      |     0
(1 row)    
--
Michael
diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c
index 36d9f69cbc..a2fe4f34b6 100644
--- a/src/backend/utils/adt/partitionfuncs.c
+++ b/src/backend/utils/adt/partitionfuncs.c
@@ -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);
diff --git a/src/test/regress/expected/partition_info.out b/src/test/regress/expected/partition_info.out
index 73269ffd09..24e3fe60f3 100644
--- a/src/test/regress/expected/partition_info.out
+++ b/src/test/regress/expected/partition_info.out
@@ -138,19 +138,18 @@ SELECT relid, parentrelid, level, isleaf
 (6 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;
diff --git a/src/test/regress/sql/partition_info.sql b/src/test/regress/sql/partition_info.sql
index 119b90afe4..d9dfa5d5d7 100644
--- a/src/test/regress/sql/partition_info.sql
+++ b/src/test/regress/sql/partition_info.sql
@@ -64,7 +64,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');

Attachment: signature.asc
Description: PGP signature

Reply via email to