Hi
pá 30. 11. 2018 v 20:06 odesílatel Pavel Stehule <[email protected]>
napsal:
>
>
> čt 29. 11. 2018 v 7:58 odesílatel Michael Paquier <[email protected]>
> napsal:
>
>> On Thu, Nov 22, 2018 at 03:47:11PM +0100, Pavel Stehule wrote:
>> > I have not feel well when I see in one report numbers 40 and 16, I see
>> much
>> > more comfortable when I see 24 and 16, but for this I need a different
>> > perspective
>> >
>> > What do you think about it?
>>
>> Maybe, my thought is that this would be a separate patch, and that we
>> had better keep it simple for now because that's complicated enough :)
>>
>
> any time, the behave should be consistent.
>
> I agree, so there can be another patch, that reports more about
> partitioned table for \d+
>
>
>> So I would rather have a wrapper on top of pg_partition_tree which is
>> useful for the user with matching patterns, which shows roughly:
>> - the size of the whole partition tree from the root.
>> - its direct parent if any. Potentially in the verbose output. This
>> depends on how much users have multi-level partitions. My bet would be
>> not that much, but more input from others is welcome.
>> - perhaps its level in the hierarchy, if integrated most likely as part
>> of the verbose output.
>>
>> Then with the set of commands, have a mapping close to how \d treats
>> indexes and relations:
>> - \dp shows information about partitioned tables or indexes, if no pattern
>> is defined tables show up. If a partitioned index pattern shows up,
>> then index information is displayed.
>>
>
> ok
>
> - \dpi and \dpt for respectively partitioned indexes and tables.
>>
>
new update of this patch
changes:
1. only root partitioned tables are displayed - you can see quickly total
allocated space. It is not duplicated due nested partitions.
I can imagine new additional flag - line "n" nested - and then we can
display nested partitioned tables with parent table info. Some like
\dPt - show only root partition tables
\dPnt or \dPtn - show root and nested partitioned tables
2. \dP without pattern shows root partitioned tables + total relation size.
When pattern is defined, then shows tables and indexes + table size
postgres=# \dP+
List of partitioned relations
┌────────┬────────────┬───────┬────────┬─────────────┐
│ Schema │ Name │ Owner │ Size │ Description │
╞════════╪════════════╪═══════╪════════╪═════════════╡
│ public │ parent_tab │ pavel │ 120 kB │ │
└────────┴────────────┴───────┴────────┴─────────────┘
(1 row)
postgres=# \dP+ *
List of partitioned relations or indexes
┌────────┬──────────────┬───────┬───────────────────┬────────────┬───────┬─────────────┐
│ Schema │ Name │ Owner │ Type │ Table │ Size │
Description │
╞════════╪══════════════╪═══════╪═══════════════════╪════════════╪═══════╪═════════════╡
│ public │ parent_index │ pavel │ partitioned index │ parent_tab │ 80 kB
│ │
│ public │ parent_tab │ pavel │ partitioned table │ │ 40 kB
│ │
└────────┴──────────────┴───────┴───────────────────┴────────────┴───────┴─────────────┘
(2 rows)
postgres=# \dP+ *index
List of partitioned relations or indexes
┌────────┬──────────────┬───────┬───────────────────┬────────────┬───────┬─────────────┐
│ Schema │ Name │ Owner │ Type │ Table │ Size │
Description │
╞════════╪══════════════╪═══════╪═══════════════════╪════════════╪═══════╪═════════════╡
│ public │ parent_index │ pavel │ partitioned index │ parent_tab │ 80 kB
│ │
└────────┴──────────────┴───────┴───────────────────┴────────────┴───────┴─────────────┘
(1 row)
Regards
Pavel
> --
>> Michael
>>
>
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 6c76cf2f00..626c89d055 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -1645,6 +1645,53 @@ testdb=>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>\dP[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists partitioned relations. If <replaceable
+ class="parameter">pattern</replaceable> is specified, only
+ entries whose relation name or schema name matches
+ the pattern are listed. If the form <literal>\dP+</literal>
+ is used, the sum of size of related partitions (including the
+ table and indexes, if any) and a description
+ are also displayed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dPi[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists partitioned indexes. If <replaceable
+ class="parameter">pattern</replaceable> is specified, only
+ entries whose index name or schema name matches
+ the pattern are listed. If the form <literal>\dPi+</literal>
+ is used, the sum of size of related indexes and a description
+ are also displayed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dPt[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists partitioned tables. If <replaceable
+ class="parameter">pattern</replaceable> is specified, only
+ entries whose table name or schema name matches
+ the pattern are listed. If the form <literal>\dPt+</literal>
+ is used, the sum of size of related tables and a description
+ are also displayed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
<varlistentry>
<term><literal>\drds [ <link linkend="app-psql-patterns"><replaceable class="parameter">role-pattern</replaceable></link> [ <link linkend="app-psql-patterns"><replaceable class="parameter">database-pattern</replaceable></link> ] ]</literal></term>
<listitem>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 55315fe43b..9bdb610e94 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -782,6 +782,31 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'p':
success = permissionsList(pattern);
break;
+ case 'P':
+ switch (cmd[2])
+ {
+ case 'i':
+ /* show indexes only */
+ success = listPartitions(pattern, show_verbose, true, false);
+ break;
+ case 't':
+ /* show tables only */
+ success = listPartitions(pattern, show_verbose, false, true);
+ break;
+ case '+':
+ case '\0':
+ /*
+ * show relations - when there are not pattern, then it shows
+ * tables with total relation size, else where it shows tables
+ * and indexes.
+ */
+ success = listPartitions(pattern, show_verbose, false, false);
+ break;
+ default:
+ status = PSQL_CMD_UNKNOWN;
+ break;
+ }
+ break;
case 'T':
success = describeTypes(pattern, show_verbose, show_system);
break;
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 0a181b01d9..92c57064f6 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3659,6 +3659,209 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
return true;
}
+/*
+ * listPartitions()
+ *
+ * handler for \dP, \dPt and \dPi
+ */
+bool
+listPartitions(const char *pattern, bool verbose, bool show_indexes, bool show_tables)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+ static const bool translate_columns[] = {false, false, true, false, false, false, false};
+ const char *size_function;
+ const char *relkind_str;
+ const char *object_name;
+ const char *objects_name;
+ bool mixed_output = false;
+
+ /*
+ * Note: Declarative table partitions are only supported as of Pg 10.0.
+ */
+ if (pset.sversion < 100000)
+ {
+ char sverbuf[32];
+
+ psql_error("The server (version %s) does not support declarative table partitioning.\n",
+ formatPGVersionNumber(pset.sversion, false,
+ sverbuf, sizeof(sverbuf)));
+ return true;
+ }
+
+ if (show_indexes)
+ {
+ /* \dPi */
+ size_function = "pg_table_size";
+ relkind_str = CppAsString2(RELKIND_PARTITIONED_INDEX);
+ object_name = gettext_noop("index");
+ objects_name = gettext_noop("indexes");
+ }
+ else if (show_tables)
+ {
+ /* \dPt */
+ size_function = "pg_table_size";
+ relkind_str = CppAsString2(RELKIND_PARTITIONED_TABLE);
+ object_name = gettext_noop("table");
+ objects_name = gettext_noop("tables");
+ }
+ else
+ {
+ /* \dP without pattern */
+ if (!pattern)
+ {
+ size_function = "pg_total_relation_size";
+ relkind_str = CppAsString2(RELKIND_PARTITIONED_TABLE);
+ object_name = gettext_noop("relation");
+ objects_name = gettext_noop("relations");
+ }
+ else
+ {
+ size_function = "pg_table_size";
+ relkind_str = CppAsString2(RELKIND_PARTITIONED_TABLE)
+ ", " CppAsString2(RELKIND_PARTITIONED_INDEX);
+ object_name = gettext_noop("relation or index");
+ objects_name = gettext_noop("relations or indexes");
+ mixed_output = true;
+ }
+ }
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT n.nspname as \"%s\",\n"
+ " c.relname as \"%s\",\n"
+ " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
+ gettext_noop("Schema"),
+ gettext_noop("Name"),
+ gettext_noop("Owner"));
+
+ if (mixed_output)
+ appendPQExpBuffer(&buf,
+ ",\n CASE c.relkind"
+ " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
+ " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
+ " END as \"%s\"",
+ gettext_noop("partitioned table"),
+ gettext_noop("partitioned index"),
+ gettext_noop("Type"));
+
+ if (show_indexes || mixed_output)
+ appendPQExpBuffer(&buf,
+ ",\n c2.relname as \"%s\"",
+ gettext_noop("Table"));
+
+ if (verbose)
+ {
+ if (pset.sversion < 120000)
+ {
+ appendPQExpBuffer(&buf,
+ ",\n (WITH RECURSIVE d\n"
+ " AS (SELECT inhrelid AS oid\n"
+ " FROM pg_catalog.pg_inherits\n"
+ " WHERE inhparent = c.oid\n"
+ " UNION ALL\n"
+ " SELECT inhrelid\n"
+ " FROM pg_catalog.pg_inherits i\n"
+ " JOIN d ON i.inhparent = d.oid)\n"
+ " SELECT pg_catalog.pg_size_pretty(sum(pg_catalog.%s("
+ "oid))) FROM d) AS \"%s\""
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ size_function,
+ gettext_noop("Size"),
+ gettext_noop("Description"));
+ }
+ else
+ {
+ /* PostgreSQL 12 has pg_partition_tree function */
+ appendPQExpBuffer(&buf,
+ ",\n (SELECT pg_catalog.pg_size_pretty(sum(pg_catalog.%s("
+ "relid)))\n"
+ " FROM pg_catalog.pg_partition_tree(c.oid)) AS \"%s\""
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ size_function,
+ gettext_noop("Size"),
+ gettext_noop("Description"));
+ }
+ }
+
+ appendPQExpBufferStr(&buf,
+ "\nFROM pg_catalog.pg_class c"
+ "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
+
+ if (show_indexes || mixed_output)
+ appendPQExpBufferStr(&buf,
+ "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid"
+ "\n LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid");
+
+ appendPQExpBuffer(&buf, "\nWHERE c.relkind IN (%s) AND NOT c.relispartition\n",
+ relkind_str);
+
+ if (!pattern)
+ appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
+ " AND n.nspname <> 'information_schema'\n");
+
+ /*
+ * TOAST objects are suppressed unconditionally. Since we don't provide
+ * any way to select RELKIND_TOASTVALUE above, we would never show toast
+ * tables in any case; it seems a bit confusing to allow their indexes to
+ * be shown. Use plain \d if you really need to look at a TOAST
+ * table/index.
+ */
+ appendPQExpBufferStr(&buf, " AND n.nspname !~ '^pg_toast'\n");
+
+ processSQLNamePattern(pset.db, &buf, pattern, true, false,
+ "n.nspname", "c.relname", NULL,
+ "pg_catalog.pg_table_is_visible(c.oid)");
+
+ appendPQExpBufferStr(&buf, "ORDER BY 1,2;");
+
+ res = PSQLexec(buf.data);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ /*
+ * Most functions in this file are content to print an empty table when
+ * there are no matching objects. We intentionally deviate from that
+ * here, but only in !quiet mode, for historical reasons.
+ */
+ if (PQntuples(res) == 0 && !pset.quiet)
+ {
+ if (pattern)
+ /* translator: objects_name is "indexes", "tables" or "relations" */
+ psql_error("Did not find any partitioned %s named \"%s\".\n",
+ objects_name,
+ pattern);
+ else
+ /* translator: object_name is "index", "table" or "relation" */
+ psql_error("Did not find any partitioned %s.\n",
+ object_name);
+ }
+ else
+ {
+ PQExpBufferData title;
+
+ initPQExpBuffer(&title);
+
+ /* translator: objects_name is "indexes", "tables" or "relations" */
+ appendPQExpBuffer(&title, _("List of partitioned %s"), objects_name);
+
+ myopt.nullPrint = NULL;
+ myopt.title = title.data;
+ myopt.translate_header = true;
+ myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
+
+ printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
+
+ termPQExpBuffer(&title);
+ }
+
+ PQclear(res);
+ return true;
+}
/*
* \dL
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index a4cc5efae0..c2138c26b9 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -63,6 +63,9 @@ extern bool listAllDbs(const char *pattern, bool verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+/* \dP, \dPi, \dPt */
+extern bool listPartitions(const char *pattern, bool verbose, bool show_indexes, bool show_tables);
+
/* \dD */
extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 2e9fe760eb..2d3e0404ef 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -168,7 +168,7 @@ slashUsage(unsigned short int pager)
* Use "psql --help=commands | wc" to count correctly. It's okay to count
* the USE_READLINE line even in builds without that.
*/
- output = PageOutput(126, pager ? &(pset.popt.topt) : NULL);
+ output = PageOutput(129, pager ? &(pset.popt.topt) : NULL);
fprintf(output, _("General\n"));
fprintf(output, _(" \\copyright show PostgreSQL usage and distribution terms\n"));
@@ -250,6 +250,9 @@ slashUsage(unsigned short int pager)
fprintf(output, _(" \\do[S] [PATTERN] list operators\n"));
fprintf(output, _(" \\dO[S+] [PATTERN] list collations\n"));
fprintf(output, _(" \\dp [PATTERN] list table, view, and sequence access privileges\n"));
+ fprintf(output, _(" \\dP[+] [PATTERN] list partitioned relations\n"));
+ fprintf(output, _(" \\dPi[+] [PATTERN] list partitioned indexes\n"));
+ fprintf(output, _(" \\dPt[+] [PATTERN] list partitioned tables\n"));
fprintf(output, _(" \\drds [PATRN1 [PATRN2]] list per-database role settings\n"));
fprintf(output, _(" \\dRp[+] [PATTERN] list replication publications\n"));
fprintf(output, _(" \\dRs[+] [PATTERN] list replication subscriptions\n"));
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index fa44b2820b..f447fc9917 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -452,6 +452,15 @@ static const SchemaQuery Query_for_list_of_indexes = {
.result = "pg_catalog.quote_ident(c.relname)",
};
+static const SchemaQuery Query_for_list_of_partitioned_indexes = {
+ .catname = "pg_catalog.pg_class c",
+ .selcondition = "c.relkind = " CppAsString2(RELKIND_PARTITIONED_INDEX),
+ .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
+ .namespace = "c.relnamespace",
+ .result = "pg_catalog.quote_ident(c.relname)",
+};
+
+
/* All relations */
static const SchemaQuery Query_for_list_of_relations = {
.catname = "pg_catalog.pg_class c",
@@ -460,6 +469,15 @@ static const SchemaQuery Query_for_list_of_relations = {
.result = "pg_catalog.quote_ident(c.relname)",
};
+/* partitioned relations */
+static const SchemaQuery Query_for_list_of_partitioned_relations = {
+ .catname = "pg_catalog.pg_class c",
+ .selcondition = "c.relkind = " CppAsString2(RELKIND_PARTITIONED_TABLE),
+ .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
+ .namespace = "c.relnamespace",
+ .result = "pg_catalog.quote_ident(c.relname)",
+};
+
/* Relations supporting INSERT, UPDATE or DELETE */
static const SchemaQuery Query_for_list_of_updatables = {
.catname = "pg_catalog.pg_class c",
@@ -1332,7 +1350,7 @@ psql_completion(const char *text, int start, int end)
"\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
"\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
"\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
- "\\dm", "\\dn", "\\do", "\\dO", "\\dp",
+ "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt",
"\\drds", "\\dRs", "\\dRp", "\\ds", "\\dS",
"\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy",
"\\e", "\\echo", "\\ef", "\\elif", "\\else", "\\encoding",
@@ -3446,6 +3464,10 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL);
+ else if (TailMatchesCS("\\dPi*"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_indexes, NULL);
+ else if (TailMatchesCS("\\dP*"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_relations, NULL);
else if (TailMatchesCS("\\ds*"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
else if (TailMatchesCS("\\dt*"))
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 775b127121..7d71666910 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -4539,3 +4539,83 @@ last error message: division by zero
\echo 'last error code:' :LAST_ERROR_SQLSTATE
last error code: 22012
\unset FETCH_COUNT
+create role testrole_partitioning;
+set role to testrole_partitioning;
+create table testtable_apple(logdate date);
+create table testtable_orange(logdate date);
+create index testtable_apple_index on testtable_apple(logdate);
+create index testtable_orange_index on testtable_orange(logdate);
+create table testpart_apple(logdate date) partition by range(logdate);
+create table testpart_orange(logdate date) partition by range(logdate);
+create index testpart_apple_index on testpart_apple(logdate);
+create index testpart_orange_index on testpart_orange(logdate);
+-- only partition related object should be displayed
+\dP test*apple*
+ List of partitioned relations or indexes
+ Schema | Name | Owner | Type | Table
+--------+----------------------+-----------------------+-------------------+----------------
+ public | testpart_apple | testrole_partitioning | partitioned table |
+ public | testpart_apple_index | testrole_partitioning | partitioned index | testpart_apple
+(2 rows)
+
+\dPt test*apple*
+ List of partitioned tables
+ Schema | Name | Owner
+--------+----------------+-----------------------
+ public | testpart_apple | testrole_partitioning
+(1 row)
+
+\dPi test*apple*
+ List of partitioned indexes
+ Schema | Name | Owner | Table
+--------+----------------------+-----------------------+----------------
+ public | testpart_apple_index | testrole_partitioning | testpart_apple
+(1 row)
+
+drop table testtable_apple;
+drop table testtable_orange;
+drop table testpart_apple;
+drop table testpart_orange;
+create table parent_tab (id int) partition by range (id);
+create index parent_index on parent_tab (id);
+create table child_0_10 partition of parent_tab
+ for values from (0) to (10);
+create table child_10_20 partition of parent_tab
+ for values from (10) to (20);
+create table child_20_30 partition of parent_tab
+ for values from (20) to (30);
+insert into parent_tab values (generate_series(0,29));
+create table child_30_40 partition of parent_tab
+for values from (30) to (40)
+ partition by range(id);
+create table child_30_35 partition of child_30_40
+ for values from (30) to (35);
+create table child_35_40 partition of child_30_40
+ for values from (35) to (40);
+insert into parent_tab values (generate_series(30,39));
+\dPt parent*
+ List of partitioned tables
+ Schema | Name | Owner
+--------+------------+-----------------------
+ public | parent_tab | testrole_partitioning
+(1 row)
+
+\dPi parent*
+ List of partitioned indexes
+ Schema | Name | Owner | Table
+--------+--------------+-----------------------+------------
+ public | parent_index | testrole_partitioning | parent_tab
+(1 row)
+
+-- \dP cannot to test due unwanted partitioned tables from other tests in result
+\dP parent*
+ List of partitioned relations or indexes
+ Schema | Name | Owner | Type | Table
+--------+--------------+-----------------------+-------------------+------------
+ public | parent_index | testrole_partitioning | partitioned index | parent_tab
+ public | parent_tab | testrole_partitioning | partitioned table |
+(2 rows)
+
+drop table parent_tab cascade;
+set role to default;
+drop role testrole_partitioning;
diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql
index 1bb2a6e16d..862e80f61f 100644
--- a/src/test/regress/sql/psql.sql
+++ b/src/test/regress/sql/psql.sql
@@ -1016,3 +1016,56 @@ select 1/(15-unique2) from tenk1 order by unique2 limit 19;
\echo 'last error code:' :LAST_ERROR_SQLSTATE
\unset FETCH_COUNT
+
+create role testrole_partitioning;
+set role to testrole_partitioning;
+
+create table testtable_apple(logdate date);
+create table testtable_orange(logdate date);
+create index testtable_apple_index on testtable_apple(logdate);
+create index testtable_orange_index on testtable_orange(logdate);
+
+create table testpart_apple(logdate date) partition by range(logdate);
+create table testpart_orange(logdate date) partition by range(logdate);
+
+create index testpart_apple_index on testpart_apple(logdate);
+create index testpart_orange_index on testpart_orange(logdate);
+
+-- only partition related object should be displayed
+\dP test*apple*
+\dPt test*apple*
+\dPi test*apple*
+
+drop table testtable_apple;
+drop table testtable_orange;
+drop table testpart_apple;
+drop table testpart_orange;
+
+create table parent_tab (id int) partition by range (id);
+create index parent_index on parent_tab (id);
+create table child_0_10 partition of parent_tab
+ for values from (0) to (10);
+create table child_10_20 partition of parent_tab
+ for values from (10) to (20);
+create table child_20_30 partition of parent_tab
+ for values from (20) to (30);
+insert into parent_tab values (generate_series(0,29));
+create table child_30_40 partition of parent_tab
+for values from (30) to (40)
+ partition by range(id);
+create table child_30_35 partition of child_30_40
+ for values from (30) to (35);
+create table child_35_40 partition of child_30_40
+ for values from (35) to (40);
+insert into parent_tab values (generate_series(30,39));
+
+\dPt parent*
+\dPi parent*
+
+-- \dP cannot to test due unwanted partitioned tables from other tests in result
+\dP parent*
+
+drop table parent_tab cascade;
+
+set role to default;
+drop role testrole_partitioning;