Thanks a lot Greg! > Changes look good to me, thanks. Can you make a new patch that applies a single set of changes to HEAD?
Please find attached the diff to Head in a single file. Best Regards, Sadeq Dousti
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index cedccc14129..37b516fc558 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1636,6 +1636,7 @@ SELECT $1 \parse stmt1 <term><literal>\dE[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> <term><literal>\di[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> <term><literal>\dm[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> + <term><literal>\dN[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> <term><literal>\ds[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> <term><literal>\dt[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> <term><literal>\dv[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> @@ -1643,15 +1644,16 @@ SELECT $1 \parse stmt1 <listitem> <para> In this group of commands, the letters <literal>E</literal>, - <literal>i</literal>, <literal>m</literal>, <literal>s</literal>, - <literal>t</literal>, and <literal>v</literal> - stand for foreign table, index, materialized view, + <literal>i</literal>, <literal>m</literal>, <literal>N</literal>, + <literal>s</literal>, <literal>t</literal>, and <literal>v</literal> + stand for foreign table, index, materialized view, no partitions, sequence, table, and view, respectively. You can specify any or all of these letters, in any order, to obtain a listing of objects of these types. For example, <literal>\dti</literal> lists - tables and indexes. + tables and indexes, and <literal>\dNt</literal> lists + tables that are not partitions of any other relation. If <literal>x</literal> is appended to the command name, the results are displayed in expanded mode. If <literal>+</literal> is diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 0f27bf7a91f..cf65df42459 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1163,6 +1163,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 'i': case 's': case 'E': + case 'N': success = listTables(&cmd[1], pattern, show_verbose, show_system); break; case 'r': diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index e6cf468ac9e..d4be468de55 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -4016,6 +4016,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys bool showMatViews = strchr(tabtypes, 'm') != NULL; bool showSeq = strchr(tabtypes, 's') != NULL; bool showForeign = strchr(tabtypes, 'E') != NULL; + bool showNoPartitions = strchr(tabtypes, 'N') != NULL; int ntypes; PQExpBufferData buf; @@ -4024,12 +4025,31 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys int cols_so_far; bool translate_columns[] = {false, false, true, false, false, false, false, false, false}; + /* + * Note: Declarative table partitioning is only supported as of Pg 10.0. + */ + if (showNoPartitions && pset.sversion < 100000) + { + char sverbuf[32]; + + pg_log_error("The server (version %s) does not support declarative table partitioning.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); + return true; + } + /* Count the number of explicitly-requested relation types */ ntypes = showTables + showIndexes + showViews + showMatViews + showSeq + showForeign; - /* If none, we default to \dtvmsE (but see also command.c) */ + if (ntypes == 0) - showTables = showViews = showMatViews = showSeq = showForeign = true; + { + if (showNoPartitions) + showTables = showIndexes = true; + else + /* If none, we default to \dtvmsE (but see also command.c) */ + showTables = showViews = showMatViews = showSeq = showForeign = true; + } initPQExpBuffer(&buf); @@ -4155,6 +4175,9 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys " AND n.nspname !~ '^pg_toast'\n" " AND n.nspname <> 'information_schema'\n"); + if (showNoPartitions) + appendPQExpBufferStr(&buf, " AND NOT c.relispartition\n"); + if (!validateSQLNamePattern(&buf, pattern, true, false, "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)", @@ -4228,8 +4251,11 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys else { myopt.title = + (ntypes != 1 && showNoPartitions) ? _("List of relations (no partitions)") : (ntypes != 1) ? _("List of relations") : + (showTables && showNoPartitions) ? _("List of tables (no partitions)") : (showTables) ? _("List of tables") : + (showIndexes && showNoPartitions) ? _("List of indexes (no partitions)") : (showIndexes) ? _("List of indexes") : (showViews) ? _("List of views") : (showMatViews) ? _("List of materialized views") : diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 714b8619233..09f98da98f2 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -259,6 +259,7 @@ slashUsage(unsigned short int pager) HELP0(" \\dL[Sx+] [PATTERN] list procedural languages\n"); HELP0(" \\dm[Sx+] [PATTERN] list materialized views\n"); HELP0(" \\dn[Sx+] [PATTERN] list schemas\n"); + HELP0(" \\dN[Sx+] [PATTERN] list tables and indexes (no partitions)\n"); HELP0(" \\do[Sx+] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n" " list operators\n"); HELP0(" \\dO[Sx+] [PATTERN] list collations\n"); diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index 8432be641ac..33ac14f10e2 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -683,6 +683,17 @@ static const SchemaQuery Query_for_list_of_tables = { .result = "c.relname", }; +/* All tables EXCEPT those marked as relispartition = true */ +static const SchemaQuery Query_for_list_of_not_relispartition_tables = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relispartition = false AND " + "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "c.relname", +}; + static const SchemaQuery Query_for_list_of_partitioned_tables = { .catname = "pg_catalog.pg_class c", .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")", @@ -787,6 +798,17 @@ static const SchemaQuery Query_for_list_of_indexes = { .result = "c.relname", }; +/* All indexes EXCEPT those marked as relispartition = true */ +static const SchemaQuery Query_for_list_of_not_relispartition_indexes = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relispartition = false AND " + "c.relkind IN (" CppAsString2(RELKIND_INDEX) ", " + CppAsString2(RELKIND_PARTITIONED_INDEX) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "c.relname", +}; + static const SchemaQuery Query_for_list_of_partitioned_indexes = { .catname = "pg_catalog.pg_class c", .selcondition = "c.relkind = " CppAsString2(RELKIND_PARTITIONED_INDEX), @@ -804,6 +826,19 @@ static const SchemaQuery Query_for_list_of_relations = { .result = "c.relname", }; +/* All relations EXCEPT those marked as relispartition = true */ +static const SchemaQuery Query_for_list_of_not_relispartition_relations = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relispartition = false AND " + "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_PARTITIONED_TABLE) ", " + CppAsString2(RELKIND_INDEX) ", " + CppAsString2(RELKIND_PARTITIONED_INDEX) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "c.relname", +}; + /* partitioned relations */ static const SchemaQuery Query_for_list_of_partitioned_relations = { .catname = "pg_catalog.pg_class c", @@ -1881,7 +1916,7 @@ psql_completion(const char *text, int start, int end) "\\db", "\\dc", "\\dconfig", "\\dC", "\\dd", "\\ddp", "\\dD", "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df", "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL", - "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt", + "\\dm", "\\dn", "\\dN", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt", "\\drds", "\\drg", "\\dRs", "\\dRp", "\\ds", "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dX", "\\dy", "\\echo", "\\edit", "\\ef", "\\elif", "\\else", "\\encoding", @@ -5272,6 +5307,8 @@ match_previous_words(int pattern_id, else if (TailMatchesCS("\\dF*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_configurations); + else if (TailMatchesCS("\\diN*") || TailMatchesCS("\\dNi*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_not_relispartition_indexes); else if (TailMatchesCS("\\di*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes); else if (TailMatchesCS("\\dL*")) @@ -5295,6 +5332,8 @@ match_previous_words(int pattern_id, COMPLETE_WITH_VERSIONED_QUERY(Query_for_list_of_subscriptions); else if (TailMatchesCS("\\ds*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences); + else if (TailMatchesCS("\\dtN*") || TailMatchesCS("\\dNt*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_not_relispartition_tables); else if (TailMatchesCS("\\dt*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables); else if (TailMatchesCS("\\dT*")) @@ -5317,6 +5356,8 @@ match_previous_words(int pattern_id, COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); /* must be at end of \d alternatives: */ + else if (TailMatchesCS("\\dN*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_not_relispartition_relations); else if (TailMatchesCS("\\d*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations); diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 6543e90de75..9394a677248 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -5017,6 +5017,47 @@ create index testpart_orange_index on testpart_orange(logdate); testpart | testpart_apple_index | regress_partitioning_role | | testpart_apple (1 row) +-- only non-partition relations should be displayed +\dN + List of relations (no partitions) + Schema | Name | Type | Owner | Table +----------+------------------------+-------------------+---------------------------+------------------ + testpart | testpart_apple | partitioned table | regress_partitioning_role | + testpart | testpart_apple_index | partitioned index | regress_partitioning_role | testpart_apple + testpart | testpart_orange | partitioned table | regress_partitioning_role | + testpart | testpart_orange_index | partitioned index | regress_partitioning_role | testpart_orange + testpart | testtable_apple | table | regress_partitioning_role | + testpart | testtable_apple_index | index | regress_partitioning_role | testtable_apple + testpart | testtable_orange | table | regress_partitioning_role | + testpart | testtable_orange_index | index | regress_partitioning_role | testtable_orange +(8 rows) + +\dN test*apple* + List of relations (no partitions) + Schema | Name | Type | Owner | Table +----------+-----------------------+-------------------+---------------------------+----------------- + testpart | testpart_apple | partitioned table | regress_partitioning_role | + testpart | testpart_apple_index | partitioned index | regress_partitioning_role | testpart_apple + testpart | testtable_apple | table | regress_partitioning_role | + testpart | testtable_apple_index | index | regress_partitioning_role | testtable_apple +(4 rows) + +\dNt test*apple* + List of tables (no partitions) + Schema | Name | Type | Owner +----------+-----------------+-------------------+--------------------------- + testpart | testpart_apple | partitioned table | regress_partitioning_role + testpart | testtable_apple | table | regress_partitioning_role +(2 rows) + +\dNi test*apple* + List of indexes (no partitions) + Schema | Name | Type | Owner | Table +----------+-----------------------+-------------------+---------------------------+----------------- + testpart | testpart_apple_index | partitioned index | regress_partitioning_role | testpart_apple + testpart | testtable_apple_index | index | regress_partitioning_role | testtable_apple +(2 rows) + drop table testtable_apple; drop table testtable_orange; drop table testpart_apple; @@ -5038,6 +5079,7 @@ create table child_30_35 partition of child_30_40 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)); +-- only partition related object should be displayed \dPt List of partitioned tables Schema | Name | Owner @@ -5106,6 +5148,45 @@ insert into parent_tab values (generate_series(30,39)); testpart | child_30_40_id_idx | regress_partitioning_role | partitioned index | parent_index | child_30_40 (4 rows) +-- only non-partition relations should be displayed +\dNt + List of tables (no partitions) + Schema | Name | Type | Owner +----------+------------+-------------------+--------------------------- + testpart | parent_tab | partitioned table | regress_partitioning_role +(1 row) + +\dNi + List of indexes (no partitions) + Schema | Name | Type | Owner | Table +----------+--------------+-------------------+---------------------------+------------ + testpart | parent_index | partitioned index | regress_partitioning_role | parent_tab +(1 row) + +\dNit + List of relations (no partitions) + Schema | Name | Type | Owner | Table +----------+--------------+-------------------+---------------------------+------------ + testpart | parent_index | partitioned index | regress_partitioning_role | parent_tab + testpart | parent_tab | partitioned table | regress_partitioning_role | +(2 rows) + +\dN + List of relations (no partitions) + Schema | Name | Type | Owner | Table +----------+--------------+-------------------+---------------------------+------------ + testpart | parent_index | partitioned index | regress_partitioning_role | parent_tab + testpart | parent_tab | partitioned table | regress_partitioning_role | +(2 rows) + +\dN testpart.* + List of relations (no partitions) + Schema | Name | Type | Owner | Table +----------+--------------+-------------------+---------------------------+------------ + testpart | parent_index | partitioned index | regress_partitioning_role | parent_tab + testpart | parent_tab | partitioned table | regress_partitioning_role | +(2 rows) + drop table parent_tab cascade; drop schema testpart; set search_path to default; diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index 97d1be3aac3..2f0f7bd1dc0 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -1257,6 +1257,12 @@ create index testpart_orange_index on testpart_orange(logdate); \dPt test*apple* \dPi test*apple* +-- only non-partition relations should be displayed +\dN +\dN test*apple* +\dNt test*apple* +\dNi test*apple* + drop table testtable_apple; drop table testtable_orange; drop table testpart_apple; @@ -1280,6 +1286,7 @@ 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)); +-- only partition related object should be displayed \dPt \dPi @@ -1291,6 +1298,14 @@ insert into parent_tab values (generate_series(30,39)); \dPn \dPn testpart.* +-- only non-partition relations should be displayed +\dNt +\dNi +\dNit +\dN + +\dN testpart.* + drop table parent_tab cascade; drop schema testpart;