From cc53123bcc9d8786acae2885c3a0897b7be34a02 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 12 Dec 2018 09:49:39 +0900 Subject: [PATCH] Tweak pg_partition_tree for undefined relations and unsupported relkinds 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 | 11 ++++++----- src/test/regress/expected/partition_info.out | 18 ++++++++++++++++-- src/test/regress/sql/partition_info.sql | 1 + 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c index 78dd2b542b..6fb4f6bc50 100644 --- a/src/backend/utils/adt/partitionfuncs.c +++ b/src/backend/utils/adt/partitionfuncs.c @@ -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()) diff --git a/src/test/regress/expected/partition_info.out b/src/test/regress/expected/partition_info.out index 6b116125e6..202d820827 100644 --- a/src/test/regress/expected/partition_info.out +++ b/src/test/regress/expected/partition_info.out @@ -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; diff --git a/src/test/regress/sql/partition_info.sql b/src/test/regress/sql/partition_info.sql index 5a76f22b05..9b55a7fe5c 100644 --- a/src/test/regress/sql/partition_info.sql +++ b/src/test/regress/sql/partition_info.sql @@ -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); -- 2.40.0