út 18. 12. 2018 v 8:49 odesílatel Amit Langote < langote_amit...@lab.ntt.co.jp> napsal:
> Hi, > > Thank you for updating the patch. > > On 2018/12/17 17:48, Pavel Stehule wrote: > > new update of this patch > > Documentation portion of this patch still contains some typos that I > mentioned before here: > > > https://www.postgresql.org/message-id/1c83bb5c-47cd-d796-226c-e95795b05551%40lab.ntt.co.jp > > + .. 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. > > + ... If the form <literal>\dPi+</literal> > + is used, the sum of size of related indexes and a description > + are also displayed. > > + ... If the form <literal>\dPt+</literal> > + is used, the sum of size of related tables and a description > + are also displayed. > > In all of the three hunks: > > the sum of size of -> the sum of "sizes" of > > and a description -> and associated description > fixed > > > changes: > > > > 1. only root partitioned tables are displayed - you can see quickly total > > allocated space. It is not duplicated due nested partitions. > > +1 > > If one wants to see a non-root partitioned table's details, they can use > \dP+ <pattern>. > > > 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 > > Too much complication maybe? > I wrote it - the setup query is more complex, but not too much. I fixed the size calculation, when nested partitions tables are visible - it calculate partitions only from level1 group. Then the displayed size is same as total size postgres=# \dP+ List of partitioned relations ┌────────┬────────────┬───────┬────────┬─────────────┐ │ Schema │ Name │ Owner │ Size │ Description │ ╞════════╪════════════╪═══════╪════════╪═════════════╡ │ public │ parent_tab │ pavel │ 120 kB │ │ └────────┴────────────┴───────┴────────┴─────────────┘ (1 row) postgres=# \dPn+ List of partitioned relations ┌────────┬─────────────┬───────┬─────────────┬───────┬─────────────┐ │ Schema │ Name │ Owner │ Parent name │ Size │ Description │ ╞════════╪═════════════╪═══════╪═════════════╪═══════╪═════════════╡ │ public │ child_30_40 │ pavel │ parent_tab │ 48 kB │ │ │ public │ parent_tab │ pavel │ │ 72 kB │ │ └────────┴─────────────┴───────┴─────────────┴───────┴─────────────┘ (2 rows) postgres=# \dPn+ * List of partitioned relations or indexes ┌────────┬────────────────────┬───────┬───────────────────┬──────────────┬─────────────┬───────┬─────────────┐ │ Schema │ Name │ Owner │ Type │ Parent name │ On table │ Size │ Description │ ╞════════╪════════════════════╪═══════╪═══════════════════╪══════════════╪═════════════╪═══════╪═════════════╡ │ public │ child_30_40 │ pavel │ partitioned table │ parent_tab │ │ 16 kB │ │ │ public │ child_30_40_id_idx │ pavel │ partitioned index │ parent_index │ child_30_40 │ 32 kB │ │ │ public │ parent_index │ pavel │ partitioned index │ │ parent_tab │ 48 kB │ │ │ public │ parent_tab │ pavel │ partitioned table │ │ │ 24 kB │ │ └────────┴────────────────────┴───────┴───────────────────┴──────────────┴─────────────┴───────┴─────────────┘ (4 rows) > > 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) > > Looking at the patch: > > + 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); > > It seems that objects_name and object_name need to be swapped between the > if and else blocks, and so do /* translator: ... */ comments. > > if (pattern) > /* translator: object_name is "index", "table" or "relation" */ > psql_error(..., object_name); > else > /* translator: objects_name is "indexes", "tables" or "relations" */ > psql_error(..., objects_name); > > That is, it should say, "Did not find any partitioned index/table/relation > named "foo" and "Did not find any partitioned indexes/tables/relations". > fixed I am sending updated patch Regards Pavel > > Thanks, > Amit > >
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 6c76cf2f00..1639c3f979 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1645,6 +1645,71 @@ testdb=> </listitem> </varlistentry> + + <varlistentry> + <term><literal>\dP[n+] [ <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 sizes of related partitions (including the + table and indexes, if any) and associated description + are also displayed. + </para> + + <para> + If modifier <literal>n</literal> is used, then nested partition + tables are displayed too. The size is calculated just for directly + assigned partitions (not for nested partitions). + </para> + </listitem> + </varlistentry> + + + <varlistentry> + <term><literal>\dPi[n+] [ <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 sizes of related indexes and associated + description are also displayed. + </para> + + <para> + If modifier <literal>n</literal> is used, then nested partition + tables are displayed too. The size is calculated just for directly + assigned partitions (not for nested partitions). + </para> + </listitem> + </varlistentry> + + + <varlistentry> + <term><literal>\dPt[n+] [ <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 sizes of related tables and associated + description are also displayed. + </para> + + <para> + If modifier <literal>n</literal> is used, then nested partition + tables are displayed too. The size is calculated just for directly + assigned partitions (not for nested partitions). + </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..c70c422ee0 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -782,6 +782,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 'p': success = permissionsList(pattern); break; + case 'P': + { + bool show_nested_partitions = strchr(cmd, 'n') ? true : false; + + switch (cmd[2]) + { + case 'i': + /* show indexes only */ + success = listPartitions(pattern, show_verbose, true, false, show_nested_partitions); + break; + case 't': + /* show tables only */ + success = listPartitions(pattern, show_verbose, false, true, show_nested_partitions); + break; + case '+': + case '\0': + case 'n': + /* + * 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, show_nested_partitions); + 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..2b62cb40e5 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3659,6 +3659,241 @@ 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, bool show_nested_partitions) +{ + PQExpBufferData buf; + PGresult *res; + printQueryOpt myopt = pset.popt; + static bool translate_columns[] = {false, false, false, false, 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")); + + translate_columns[4] = true; + } + + if (show_nested_partitions) + appendPQExpBuffer(&buf, + ",\n c3.relname as \"%s\"", + gettext_noop("Parent name")); + + if (show_indexes || mixed_output) + appendPQExpBuffer(&buf, + ",\n c2.relname as \"%s\"", + gettext_noop("On table")); + + if (verbose) + { + if (pset.sversion < 120000) + { + appendPQExpBuffer(&buf, + ",\n (WITH RECURSIVE d\n" + " AS (SELECT inhrelid AS oid, 1 AS level\n" + " FROM pg_catalog.pg_inherits\n" + " WHERE inhparent = c.oid\n" + " UNION ALL\n" + " SELECT inhrelid, level + 1\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)))\n" + " FROM d", + size_function); + + if (show_nested_partitions) + appendPQExpBuffer(&buf, "\n WHERE d.level = 1"); + + appendPQExpBuffer(&buf, + ") AS \"%s\"" + ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"", + 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(" + "ppt.relid)))\n" + " FROM pg_catalog.pg_partition_tree(c.oid) ppt", + size_function); + + /* + * Assign size just for directly assigned tables, when nested + * partitions are visible + */ + if (show_nested_partitions) + appendPQExpBuffer(&buf, "\n WHERE ppt.isleaf AND ppt.level = 1"); + + appendPQExpBuffer(&buf, + ") AS \"%s\"" + ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"", + 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"); + + if (show_nested_partitions) + appendPQExpBufferStr(&buf, + "\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid" + "\n LEFT JOIN pg_catalog.pg_class c3 ON c3.oid = inh.inhparent"); + + appendPQExpBuffer(&buf, "\nWHERE c.relkind IN (%s)", relkind_str); + appendPQExpBufferStr(&buf, !show_nested_partitions ? " AND NOT c.relispartition\n" : "\n"); + + 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: object_name is "index", "table" or "relation" */ + psql_error("Did not find any partitioned %s.\n", + object_name); + else + /* translator: objects_name is "indexes", "tables" or "relations" */ + psql_error("Did not find any partitioned %s named \"%s\".\n", + objects_name, + pattern); + } + 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..1cf3a13598 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[n], \dPi[n], \dPt[n] */ +extern bool listPartitions(const char *pattern, bool verbose, bool show_indexes, bool show_tables, bool show_nested_partitions); + /* \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..bf747b883e 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[n+] [PATTERN] list partitioned relations\n")); + fprintf(output, _(" \\dPi[n+] [PATTERN] list partitioned indexes\n")); + fprintf(output, _(" \\dPt[n+] [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..52bcb3f918 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -4539,3 +4539,129 @@ last error message: division by zero \echo 'last error code:' :LAST_ERROR_SQLSTATE last error code: 22012 \unset FETCH_COUNT +create schema testpart; +create role testrole_partitioning; +alter schema testpart owner to testrole_partitioning; +set role to testrole_partitioning; +-- run test inside own schema and hide other partitions +set search_path to testpart; +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 | On table +----------+----------------------+-----------------------+-------------------+---------------- + testpart | testpart_apple | testrole_partitioning | partitioned table | + testpart | testpart_apple_index | testrole_partitioning | partitioned index | testpart_apple +(2 rows) + +\dPt test*apple* + List of partitioned tables + Schema | Name | Owner +----------+----------------+----------------------- + testpart | testpart_apple | testrole_partitioning +(1 row) + +\dPi test*apple* + List of partitioned indexes + Schema | Name | Owner | On table +----------+----------------------+-----------------------+---------------- + testpart | 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 + List of partitioned tables + Schema | Name | Owner +----------+------------+----------------------- + testpart | parent_tab | testrole_partitioning +(1 row) + +\dPi + List of partitioned indexes + Schema | Name | Owner | On table +----------+--------------+-----------------------+------------ + testpart | parent_index | testrole_partitioning | parent_tab +(1 row) + +\dP testpart.* + List of partitioned relations or indexes + Schema | Name | Owner | Type | On table +----------+--------------+-----------------------+-------------------+------------ + testpart | parent_index | testrole_partitioning | partitioned index | parent_tab + testpart | parent_tab | testrole_partitioning | partitioned table | +(2 rows) + +\dP + List of partitioned relations + Schema | Name | Owner +----------+------------+----------------------- + testpart | parent_tab | testrole_partitioning +(1 row) + +\dPtn + List of partitioned tables + Schema | Name | Owner | Parent name +----------+-------------+-----------------------+------------- + testpart | child_30_40 | testrole_partitioning | parent_tab + testpart | parent_tab | testrole_partitioning | +(2 rows) + +\dPin + List of partitioned indexes + Schema | Name | Owner | Parent name | On table +----------+--------------------+-----------------------+--------------+------------- + testpart | child_30_40_id_idx | testrole_partitioning | parent_index | child_30_40 + testpart | parent_index | testrole_partitioning | | parent_tab +(2 rows) + +\dPn + List of partitioned relations + Schema | Name | Owner | Parent name +----------+-------------+-----------------------+------------- + testpart | child_30_40 | testrole_partitioning | parent_tab + testpart | parent_tab | testrole_partitioning | +(2 rows) + +\dPn testpart.* + List of partitioned relations or indexes + Schema | Name | Owner | Type | Parent name | On table +----------+--------------------+-----------------------+-------------------+--------------+------------- + testpart | child_30_40 | testrole_partitioning | partitioned table | parent_tab | + testpart | child_30_40_id_idx | testrole_partitioning | partitioned index | parent_index | child_30_40 + testpart | parent_index | testrole_partitioning | partitioned index | | parent_tab + testpart | parent_tab | testrole_partitioning | partitioned table | | +(4 rows) + +drop table parent_tab cascade; +drop schema testpart; +set search_path to default; +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..540a416a7b 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -1016,3 +1016,72 @@ select 1/(15-unique2) from tenk1 order by unique2 limit 19; \echo 'last error code:' :LAST_ERROR_SQLSTATE \unset FETCH_COUNT + +create schema testpart; +create role testrole_partitioning; + +alter schema testpart owner to testrole_partitioning; + +set role to testrole_partitioning; + +-- run test inside own schema and hide other partitions +set search_path to testpart; + +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 +\dPi + +\dP testpart.* +\dP + +\dPtn +\dPin +\dPn +\dPn testpart.* + +drop table parent_tab cascade; + +drop schema testpart; + +set search_path to default; + +set role to default; +drop role testrole_partitioning;