pg_partition_ancestors

Adds another introspection feature for partitioning, necessary for
further psql patches.

Reviewed-by: Michaël Paquier
Discussion: https://postgr.es/m/20190226222757.GA31622@alvherre.pgsql
This commit is contained in:
Alvaro Herrera 2019-03-04 16:14:29 -03:00
parent d12fbe2f8e
commit b96f6b1948
6 changed files with 144 additions and 1 deletions

View File

@ -20274,6 +20274,17 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
their partitions, and so on.
</entry>
</row>
<row>
<entry>
<indexterm><primary>pg_partition_ancestors</primary></indexterm>
<literal><function>pg_partition_ancestors(<type>regclass</type>)</function></literal>
</entry>
<entry><type>setof regclass</type></entry>
<entry>
List the ancestor relations of the given partition,
including the partition itself.
</entry>
</row>
<row>
<entry>
<indexterm><primary>pg_partition_root</primary></indexterm>

View File

@ -201,3 +201,52 @@ pg_partition_root(PG_FUNCTION_ARGS)
Assert(OidIsValid(rootrelid));
PG_RETURN_OID(rootrelid);
}
/*
* pg_partition_ancestors
*
* Produces a view with one row per ancestor of the given partition,
* including the input relation itself.
*/
Datum
pg_partition_ancestors(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
FuncCallContext *funcctx;
ListCell **next;
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcxt;
List *ancestors;
funcctx = SRF_FIRSTCALL_INIT();
if (!check_rel_can_be_partition(relid))
SRF_RETURN_DONE(funcctx);
oldcxt = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
ancestors = get_partition_ancestors(relid);
ancestors = lcons_oid(relid, ancestors);
next = (ListCell **) palloc(sizeof(ListCell *));
*next = list_head(ancestors);
funcctx->user_fctx = (void *) next;
MemoryContextSwitchTo(oldcxt);
}
funcctx = SRF_PERCALL_SETUP();
next = (ListCell **) funcctx->user_fctx;
if (*next != NULL)
{
Oid relid = lfirst_oid(*next);
*next = lnext(*next);
SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(relid));
}
SRF_RETURN_DONE(funcctx);
}

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201902161
#define CATALOG_VERSION_NO 201903041
#endif

View File

@ -10528,6 +10528,11 @@
proargmodes => '{i,o,o,o,o}',
proargnames => '{rootrelid,relid,parentrelid,isleaf,level}',
prosrc => 'pg_partition_tree' },
{ oid => '3425', descr => 'view ancestors of the partition',
proname => 'pg_partition_ancestors', prorows => '10', proretset => 't',
provolatile => 'v', prorettype => 'regclass', proargtypes => 'regclass',
proallargtypes => '{regclass,regclass}', proargmodes => '{i,o}',
proargnames => '{partitionid,relid}', prosrc => 'pg_partition_ancestors' },
# function to get the top-most partition root parent
{ oid => '3424', descr => 'get top-most partition root parent',

View File

@ -11,6 +11,16 @@ SELECT * FROM pg_partition_tree(0);
-------+-------------+--------+-------
(0 rows)
SELECT * FROM pg_partition_ancestors(NULL);
relid
-------
(0 rows)
SELECT * FROM pg_partition_ancestors(0);
relid
-------
(0 rows)
SELECT pg_partition_root(NULL);
pg_partition_root
-------------------
@ -92,6 +102,21 @@ SELECT relid, parentrelid, level, isleaf
ptif_test3 | ptif_test | 0 | f
(1 row)
-- List all ancestors of root and leaf tables
SELECT * FROM pg_partition_ancestors('ptif_test01');
relid
-------------
ptif_test01
ptif_test0
ptif_test
(3 rows)
SELECT * FROM pg_partition_ancestors('ptif_test');
relid
-----------
ptif_test
(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
@ -164,6 +189,21 @@ SELECT relid, parentrelid, level, isleaf
ptif_test11_index | ptif_test1_index | 2 | t
(7 rows)
-- List all ancestors of root and leaf indexes
SELECT * FROM pg_partition_ancestors('ptif_test01_index');
relid
-------------------
ptif_test01_index
ptif_test0_index
ptif_test_index
(3 rows)
SELECT * FROM pg_partition_ancestors('ptif_test_index');
relid
-----------------
ptif_test_index
(1 row)
DROP TABLE ptif_test;
-- Table that is not part of any partition tree is not listed.
CREATE TABLE ptif_normal_table(a int);
@ -173,6 +213,11 @@ SELECT relid, parentrelid, level, isleaf
-------+-------------+-------+--------
(0 rows)
SELECT * FROM pg_partition_ancestors('ptif_normal_table');
relid
-------
(0 rows)
SELECT pg_partition_root('ptif_normal_table');
pg_partition_root
-------------------
@ -207,6 +252,26 @@ SELECT * FROM pg_partition_tree('ptif_li_child');
-------+-------------+--------+-------
(0 rows)
SELECT * FROM pg_partition_ancestors('ptif_test_view');
relid
-------
(0 rows)
SELECT * FROM pg_partition_ancestors('ptif_test_matview');
relid
-------
(0 rows)
SELECT * FROM pg_partition_ancestors('ptif_li_parent');
relid
-------
(0 rows)
SELECT * FROM pg_partition_ancestors('ptif_li_child');
relid
-------
(0 rows)
SELECT pg_partition_root('ptif_test_view');
pg_partition_root
-------------------

View File

@ -3,6 +3,8 @@
--
SELECT * FROM pg_partition_tree(NULL);
SELECT * FROM pg_partition_tree(0);
SELECT * FROM pg_partition_ancestors(NULL);
SELECT * FROM pg_partition_ancestors(0);
SELECT pg_partition_root(NULL);
SELECT pg_partition_root(0);
@ -50,6 +52,9 @@ SELECT relid, parentrelid, level, isleaf
SELECT relid, parentrelid, level, isleaf
FROM pg_partition_tree('ptif_test3') p
JOIN pg_class c ON (p.relid = c.oid);
-- List all ancestors of root and leaf tables
SELECT * FROM pg_partition_ancestors('ptif_test01');
SELECT * FROM pg_partition_ancestors('ptif_test');
-- 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
@ -74,6 +79,9 @@ SELECT relid, parentrelid, level, isleaf
SELECT relid, parentrelid, level, isleaf
FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p
JOIN pg_class c ON (p.relid = c.oid);
-- List all ancestors of root and leaf indexes
SELECT * FROM pg_partition_ancestors('ptif_test01_index');
SELECT * FROM pg_partition_ancestors('ptif_test_index');
DROP TABLE ptif_test;
@ -81,6 +89,7 @@ DROP TABLE ptif_test;
CREATE TABLE ptif_normal_table(a int);
SELECT relid, parentrelid, level, isleaf
FROM pg_partition_tree('ptif_normal_table');
SELECT * FROM pg_partition_ancestors('ptif_normal_table');
SELECT pg_partition_root('ptif_normal_table');
DROP TABLE ptif_normal_table;
@ -95,6 +104,10 @@ SELECT * FROM pg_partition_tree('ptif_test_view');
SELECT * FROM pg_partition_tree('ptif_test_matview');
SELECT * FROM pg_partition_tree('ptif_li_parent');
SELECT * FROM pg_partition_tree('ptif_li_child');
SELECT * FROM pg_partition_ancestors('ptif_test_view');
SELECT * FROM pg_partition_ancestors('ptif_test_matview');
SELECT * FROM pg_partition_ancestors('ptif_li_parent');
SELECT * FROM pg_partition_ancestors('ptif_li_child');
SELECT pg_partition_root('ptif_test_view');
SELECT pg_partition_root('ptif_test_matview');
SELECT pg_partition_root('ptif_li_parent');