]> granicus.if.org Git - postgresql/commitdiff
pg_partition_ancestors
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 4 Mar 2019 19:14:29 +0000 (16:14 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 4 Mar 2019 19:14:29 +0000 (16:14 -0300)
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

doc/src/sgml/func.sgml
src/backend/utils/adt/partitionfuncs.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.dat
src/test/regress/expected/partition_info.out
src/test/regress/sql/partition_info.sql

index 86ff4e5c9e2aaf07ab6b3a2a9e640fc488453aa1..6765b0d584c8a76e51664bbe83fcf5bd3c3ba6e7 100644 (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>
index a2fe4f34b6d5114c3bcc02d5ea7e099f9fd02d34..98c8ef77f1711a1bc4118820298d209d1a1e4a1b 100644 (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);
+}
index 4887d322a300206fdf59bd1ae927606c6652c698..0c4c2e11d59627f216b93bac168542cd2189ebec 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201902161
+#define CATALOG_VERSION_NO     201903041
 
 #endif
index a4e173b4846835ececf618f52d3783c8f75f2204..5bb56b2c6391df73f0faf05b095d0b530f211021 100644 (file)
   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',
index 6df7a80a9395c9ebf3b73d6a6266000dcf93a7d1..92aa6abe3f990af76e09e7ee338fb7ef909fe6e9 100644 (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 
 -------------------
index a18c15aef218c43cc0c1bfac78631b54c7b39435..adaca232324745bf740cc6ec29d3786858b48f6a 100644 (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');