Commit cc53123b authored by Michael Paquier's avatar Michael Paquier

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
parent 7a28e9aa
......@@ -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())
......
......@@ -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;
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment