]> granicus.if.org Git - postgresql/commitdiff
Tweak pg_partition_tree for undefined relations and unsupported relkinds
authorMichael Paquier <michael@paquier.xyz>
Wed, 12 Dec 2018 00:49:39 +0000 (09:49 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 12 Dec 2018 00:49:39 +0000 (09:49 +0900)
This fixes a crash which happened when calling the function directly
with a relation OID referring to a non-existing object, and changes the
behavior so as NULL is returned for unsupported relkinds instead of
generating an error.  This puts the new function in line with many other
system functions, and eases actions like full scans of pg_class.

Author: Michael Paquier
Reviewed-by: Amit Langote, Stephen Frost
Discussion: https://postgr.es/m/20181207010406.GO2407@paquier.xyz

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

index 78dd2b542b50f99a49bb10cf9f437d55a112bd75..6fb4f6bc50f9cd40bdbafa23ef8154fef7c6e9db 100644 (file)
@@ -23,6 +23,7 @@
 #include "funcapi.h"
 #include "utils/fmgrprotos.h"
 #include "utils/lsyscache.h"
+#include "utils/syscache.h"
 
 
 /*
@@ -42,16 +43,16 @@ pg_partition_tree(PG_FUNCTION_ARGS)
        FuncCallContext *funcctx;
        ListCell  **next;
 
-       /* Only allow relation types that can appear in partition trees. */
+       if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(rootrelid)))
+               PG_RETURN_NULL();
+
+       /* Return NULL for relation types that cannot appear in partition trees */
        if (relkind != RELKIND_RELATION &&
                relkind != RELKIND_FOREIGN_TABLE &&
                relkind != RELKIND_INDEX &&
                relkind != RELKIND_PARTITIONED_TABLE &&
                relkind != RELKIND_PARTITIONED_INDEX)
-               ereport(ERROR,
-                               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                                errmsg("\"%s\" is not a table, a foreign table, or an index",
-                                               get_rel_name(rootrelid))));
+               PG_RETURN_NULL();
 
        /* stuff done only on the first call of the function */
        if (SRF_IS_FIRSTCALL())
index 6b116125e6db31be983db15faa2ae67b8130e17a..202d8208279a49b235d507b84eb211784dd44718 100644 (file)
@@ -6,6 +6,12 @@ SELECT * FROM pg_partition_tree(NULL);
 -------+-------------+--------+-------
 (0 rows)
 
+SELECT * FROM pg_partition_tree(0);
+ relid | parentrelid | isleaf | level 
+-------+-------------+--------+-------
+       |             |        |      
+(1 row)
+
 -- Test table partition trees
 CREATE TABLE ptif_test (a int, b int) PARTITION BY range (a);
 CREATE TABLE ptif_test0 PARTITION OF ptif_test
@@ -107,8 +113,16 @@ DROP TABLE ptif_normal_table;
 CREATE VIEW ptif_test_view AS SELECT 1;
 CREATE MATERIALIZED VIEW ptif_test_matview AS SELECT 1;
 SELECT * FROM pg_partition_tree('ptif_test_view');
-ERROR:  "ptif_test_view" is not a table, a foreign table, or an index
+ relid | parentrelid | isleaf | level 
+-------+-------------+--------+-------
+       |             |        |      
+(1 row)
+
 SELECT * FROM pg_partition_tree('ptif_test_matview');
-ERROR:  "ptif_test_matview" is not a table, a foreign table, or an index
+ relid | parentrelid | isleaf | level 
+-------+-------------+--------+-------
+       |             |        |      
+(1 row)
+
 DROP VIEW ptif_test_view;
 DROP MATERIALIZED VIEW ptif_test_matview;
index 5a76f22b05ee23c5390e3475fa501ddb0e07d00d..9b55a7fe5cee82a656f044f96bad311abba1a39f 100644 (file)
@@ -2,6 +2,7 @@
 -- Tests for pg_partition_tree
 --
 SELECT * FROM pg_partition_tree(NULL);
+SELECT * FROM pg_partition_tree(0);
 
 -- Test table partition trees
 CREATE TABLE ptif_test (a int, b int) PARTITION BY range (a);