Skip to content

Commit 889da53

Browse files
msdoustiCommitfest Bot
authored andcommitted
psql acommand for non-partitioned tables & indexes
This patch introduces the new letter N for the \d (describe) metacommand of psql. Using this command, one can list all the tables and indexes that are not partitioned. Using \dtN and \diN, one can further limit the disabled objects to non-partitioned tables, respectively, non-partitioned indexes.
1 parent 0a8a4be commit 889da53

File tree

7 files changed

+170
-7
lines changed

7 files changed

+170
-7
lines changed

doc/src/sgml/ref/psql-ref.sgml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,22 +1645,24 @@ SELECT $1 \parse stmt1
16451645
<term><literal>\dE[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
16461646
<term><literal>\di[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
16471647
<term><literal>\dm[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
1648+
<term><literal>\dN[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
16481649
<term><literal>\ds[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
16491650
<term><literal>\dt[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
16501651
<term><literal>\dv[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
16511652

16521653
<listitem>
16531654
<para>
16541655
In this group of commands, the letters <literal>E</literal>,
1655-
<literal>i</literal>, <literal>m</literal>, <literal>s</literal>,
1656-
<literal>t</literal>, and <literal>v</literal>
1657-
stand for foreign table, index, materialized view,
1656+
<literal>i</literal>, <literal>m</literal>, <literal>N</literal>,
1657+
<literal>s</literal>, <literal>t</literal>, and <literal>v</literal>
1658+
stand for foreign table, index, materialized view, no partitions,
16581659
sequence, table, and view,
16591660
respectively.
16601661
You can specify any or all of
16611662
these letters, in any order, to obtain a listing of objects
16621663
of these types. For example, <literal>\dti</literal> lists
1663-
tables and indexes.
1664+
tables and indexes, and <literal>\dNt</literal> lists
1665+
tables that are not partitions of any other relation.
16641666
If <literal>x</literal> is appended to the command name, the results
16651667
are displayed in expanded mode.
16661668
If <literal>+</literal> is

src/bin/psql/command.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
11901190
case 'i':
11911191
case 's':
11921192
case 'E':
1193+
case 'N':
11931194
success = listTables(&cmd[1], pattern, show_verbose, show_system);
11941195
break;
11951196
case 'r':

src/bin/psql/describe.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4031,6 +4031,7 @@ describeRoleGrants(const char *pattern, bool showSystem)
40314031
* tabtypes is an array of characters, specifying what info is desired:
40324032
* t - tables
40334033
* i - indexes
4034+
* N - no partitions (only applies to tables and indexes)
40344035
* v - views
40354036
* m - materialized views
40364037
* s - sequences
@@ -4046,6 +4047,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
40464047
bool showMatViews = strchr(tabtypes, 'm') != NULL;
40474048
bool showSeq = strchr(tabtypes, 's') != NULL;
40484049
bool showForeign = strchr(tabtypes, 'E') != NULL;
4050+
bool showNoPartitions = strchr(tabtypes, 'N') != NULL;
40494051

40504052
int ntypes;
40514053
PQExpBufferData buf;
@@ -4054,12 +4056,26 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
40544056
int cols_so_far;
40554057
bool translate_columns[] = {false, false, true, false, false, false, false, false, false};
40564058

4059+
/*
4060+
* Note: Declarative table partitioning is only supported as of Pg 10.0.
4061+
*/
4062+
if (showNoPartitions && pset.sversion < 100000)
4063+
{
4064+
showNoPartitions = false;
4065+
}
4066+
40574067
/* Count the number of explicitly-requested relation types */
40584068
ntypes = showTables + showIndexes + showViews + showMatViews +
40594069
showSeq + showForeign;
4060-
/* If none, we default to \dtvmsE (but see also command.c) */
4070+
40614071
if (ntypes == 0)
4062-
showTables = showViews = showMatViews = showSeq = showForeign = true;
4072+
{
4073+
if (showNoPartitions)
4074+
showTables = showIndexes = true;
4075+
else
4076+
/* If none, we default to \dtvmsE (but see also command.c) */
4077+
showTables = showViews = showMatViews = showSeq = showForeign = true;
4078+
}
40634079

40644080
initPQExpBuffer(&buf);
40654081

@@ -4185,6 +4201,9 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
41854201
" AND n.nspname !~ '^pg_toast'\n"
41864202
" AND n.nspname <> 'information_schema'\n");
41874203

4204+
if (showNoPartitions)
4205+
appendPQExpBufferStr(&buf, " AND NOT c.relispartition\n");
4206+
41884207
if (!validateSQLNamePattern(&buf, pattern, true, false,
41894208
"n.nspname", "c.relname", NULL,
41904209
"pg_catalog.pg_table_is_visible(c.oid)",
@@ -4258,8 +4277,11 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
42584277
else
42594278
{
42604279
myopt.title =
4280+
(ntypes != 1 && showNoPartitions) ? _("List of relations (no partitions)") :
42614281
(ntypes != 1) ? _("List of relations") :
4282+
(showTables && showNoPartitions) ? _("List of tables (no partitions)") :
42624283
(showTables) ? _("List of tables") :
4284+
(showIndexes && showNoPartitions) ? _("List of indexes (no partitions)") :
42634285
(showIndexes) ? _("List of indexes") :
42644286
(showViews) ? _("List of views") :
42654287
(showMatViews) ? _("List of materialized views") :

src/bin/psql/help.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ slashUsage(unsigned short int pager)
251251
HELP0(" \\dL[Sx+] [PATTERN] list procedural languages\n");
252252
HELP0(" \\dm[Sx+] [PATTERN] list materialized views\n");
253253
HELP0(" \\dn[Sx+] [PATTERN] list schemas\n");
254+
HELP0(" \\dN[Sx+] [PATTERN] list tables and indexes (no partitions)\n");
254255
HELP0(" \\do[Sx+] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n"
255256
" list operators\n");
256257
HELP0(" \\dO[Sx+] [PATTERN] list collations\n");

src/bin/psql/tab-complete.in.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,17 @@ static const SchemaQuery Query_for_list_of_tables = {
693693
.result = "c.relname",
694694
};
695695

696+
/* All tables EXCEPT those marked as relispartition = true */
697+
static const SchemaQuery Query_for_list_of_not_relispartition_tables = {
698+
.catname = "pg_catalog.pg_class c",
699+
.selcondition = "c.relispartition = false AND "
700+
"c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
701+
CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
702+
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
703+
.namespace = "c.relnamespace",
704+
.result = "c.relname",
705+
};
706+
696707
static const SchemaQuery Query_for_list_of_partitioned_tables = {
697708
.catname = "pg_catalog.pg_class c",
698709
.selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
@@ -797,6 +808,17 @@ static const SchemaQuery Query_for_list_of_indexes = {
797808
.result = "c.relname",
798809
};
799810

811+
/* All indexes EXCEPT those marked as relispartition = true */
812+
static const SchemaQuery Query_for_list_of_not_relispartition_indexes = {
813+
.catname = "pg_catalog.pg_class c",
814+
.selcondition = "c.relispartition = false AND "
815+
"c.relkind IN (" CppAsString2(RELKIND_INDEX) ", "
816+
CppAsString2(RELKIND_PARTITIONED_INDEX) ")",
817+
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
818+
.namespace = "c.relnamespace",
819+
.result = "c.relname",
820+
};
821+
800822
static const SchemaQuery Query_for_list_of_partitioned_indexes = {
801823
.catname = "pg_catalog.pg_class c",
802824
.selcondition = "c.relkind = " CppAsString2(RELKIND_PARTITIONED_INDEX),
@@ -814,6 +836,19 @@ static const SchemaQuery Query_for_list_of_relations = {
814836
.result = "c.relname",
815837
};
816838

839+
/* All relations EXCEPT those marked as relispartition = true */
840+
static const SchemaQuery Query_for_list_of_not_relispartition_relations = {
841+
.catname = "pg_catalog.pg_class c",
842+
.selcondition = "c.relispartition = false AND "
843+
"c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
844+
CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
845+
CppAsString2(RELKIND_INDEX) ", "
846+
CppAsString2(RELKIND_PARTITIONED_INDEX) ")",
847+
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
848+
.namespace = "c.relnamespace",
849+
.result = "c.relname",
850+
};
851+
817852
/* partitioned relations */
818853
static const SchemaQuery Query_for_list_of_partitioned_relations = {
819854
.catname = "pg_catalog.pg_class c",
@@ -1916,7 +1951,7 @@ psql_completion(const char *text, int start, int end)
19161951
"\\db", "\\dc", "\\dconfig", "\\dC", "\\dd", "\\ddp", "\\dD",
19171952
"\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
19181953
"\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
1919-
"\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt",
1954+
"\\dm", "\\dn", "\\dN", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt",
19201955
"\\drds", "\\drg", "\\dRs", "\\dRp", "\\ds",
19211956
"\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dX", "\\dy",
19221957
"\\echo", "\\edit", "\\ef", "\\elif", "\\else", "\\encoding",
@@ -5376,6 +5411,8 @@ match_previous_words(int pattern_id,
53765411
else if (TailMatchesCS("\\dF*"))
53775412
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_configurations);
53785413

5414+
else if (TailMatchesCS("\\diN*") || TailMatchesCS("\\dNi*"))
5415+
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_not_relispartition_indexes);
53795416
else if (TailMatchesCS("\\di*"))
53805417
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
53815418
else if (TailMatchesCS("\\dL*"))
@@ -5399,6 +5436,8 @@ match_previous_words(int pattern_id,
53995436
COMPLETE_WITH_VERSIONED_QUERY(Query_for_list_of_subscriptions);
54005437
else if (TailMatchesCS("\\ds*"))
54015438
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences);
5439+
else if (TailMatchesCS("\\dtN*") || TailMatchesCS("\\dNt*"))
5440+
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_not_relispartition_tables);
54025441
else if (TailMatchesCS("\\dt*"))
54035442
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
54045443
else if (TailMatchesCS("\\dT*"))
@@ -5421,6 +5460,8 @@ match_previous_words(int pattern_id,
54215460
COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
54225461

54235462
/* must be at end of \d alternatives: */
5463+
else if (TailMatchesCS("\\dN*"))
5464+
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_not_relispartition_relations);
54245465
else if (TailMatchesCS("\\d*"))
54255466
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations);
54265467

src/test/regress/expected/psql.out

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5020,6 +5020,47 @@ create index testpart_orange_index on testpart_orange(logdate);
50205020
testpart | testpart_apple_index | regress_partitioning_role | | testpart_apple
50215021
(1 row)
50225022

5023+
-- only non-partition relations should be displayed
5024+
\dN
5025+
List of relations (no partitions)
5026+
Schema | Name | Type | Owner | Table
5027+
----------+------------------------+-------------------+---------------------------+------------------
5028+
testpart | testpart_apple | partitioned table | regress_partitioning_role |
5029+
testpart | testpart_apple_index | partitioned index | regress_partitioning_role | testpart_apple
5030+
testpart | testpart_orange | partitioned table | regress_partitioning_role |
5031+
testpart | testpart_orange_index | partitioned index | regress_partitioning_role | testpart_orange
5032+
testpart | testtable_apple | table | regress_partitioning_role |
5033+
testpart | testtable_apple_index | index | regress_partitioning_role | testtable_apple
5034+
testpart | testtable_orange | table | regress_partitioning_role |
5035+
testpart | testtable_orange_index | index | regress_partitioning_role | testtable_orange
5036+
(8 rows)
5037+
5038+
\dN test*apple*
5039+
List of relations (no partitions)
5040+
Schema | Name | Type | Owner | Table
5041+
----------+-----------------------+-------------------+---------------------------+-----------------
5042+
testpart | testpart_apple | partitioned table | regress_partitioning_role |
5043+
testpart | testpart_apple_index | partitioned index | regress_partitioning_role | testpart_apple
5044+
testpart | testtable_apple | table | regress_partitioning_role |
5045+
testpart | testtable_apple_index | index | regress_partitioning_role | testtable_apple
5046+
(4 rows)
5047+
5048+
\dNt test*apple*
5049+
List of tables (no partitions)
5050+
Schema | Name | Type | Owner
5051+
----------+-----------------+-------------------+---------------------------
5052+
testpart | testpart_apple | partitioned table | regress_partitioning_role
5053+
testpart | testtable_apple | table | regress_partitioning_role
5054+
(2 rows)
5055+
5056+
\dNi test*apple*
5057+
List of indexes (no partitions)
5058+
Schema | Name | Type | Owner | Table
5059+
----------+-----------------------+-------------------+---------------------------+-----------------
5060+
testpart | testpart_apple_index | partitioned index | regress_partitioning_role | testpart_apple
5061+
testpart | testtable_apple_index | index | regress_partitioning_role | testtable_apple
5062+
(2 rows)
5063+
50235064
drop table testtable_apple;
50245065
drop table testtable_orange;
50255066
drop table testpart_apple;
@@ -5041,6 +5082,7 @@ create table child_30_35 partition of child_30_40
50415082
create table child_35_40 partition of child_30_40
50425083
for values from (35) to (40);
50435084
insert into parent_tab values (generate_series(30,39));
5085+
-- only partition related object should be displayed
50445086
\dPt
50455087
List of partitioned tables
50465088
Schema | Name | Owner
@@ -5109,6 +5151,45 @@ insert into parent_tab values (generate_series(30,39));
51095151
testpart | child_30_40_id_idx | regress_partitioning_role | partitioned index | parent_index | child_30_40
51105152
(4 rows)
51115153

5154+
-- only non-partition relations should be displayed
5155+
\dNt
5156+
List of tables (no partitions)
5157+
Schema | Name | Type | Owner
5158+
----------+------------+-------------------+---------------------------
5159+
testpart | parent_tab | partitioned table | regress_partitioning_role
5160+
(1 row)
5161+
5162+
\dNi
5163+
List of indexes (no partitions)
5164+
Schema | Name | Type | Owner | Table
5165+
----------+--------------+-------------------+---------------------------+------------
5166+
testpart | parent_index | partitioned index | regress_partitioning_role | parent_tab
5167+
(1 row)
5168+
5169+
\dNit
5170+
List of relations (no partitions)
5171+
Schema | Name | Type | Owner | Table
5172+
----------+--------------+-------------------+---------------------------+------------
5173+
testpart | parent_index | partitioned index | regress_partitioning_role | parent_tab
5174+
testpart | parent_tab | partitioned table | regress_partitioning_role |
5175+
(2 rows)
5176+
5177+
\dN
5178+
List of relations (no partitions)
5179+
Schema | Name | Type | Owner | Table
5180+
----------+--------------+-------------------+---------------------------+------------
5181+
testpart | parent_index | partitioned index | regress_partitioning_role | parent_tab
5182+
testpart | parent_tab | partitioned table | regress_partitioning_role |
5183+
(2 rows)
5184+
5185+
\dN testpart.*
5186+
List of relations (no partitions)
5187+
Schema | Name | Type | Owner | Table
5188+
----------+--------------+-------------------+---------------------------+------------
5189+
testpart | parent_index | partitioned index | regress_partitioning_role | parent_tab
5190+
testpart | parent_tab | partitioned table | regress_partitioning_role |
5191+
(2 rows)
5192+
51125193
drop table parent_tab cascade;
51135194
drop schema testpart;
51145195
set search_path to default;

src/test/regress/sql/psql.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,12 @@ create index testpart_orange_index on testpart_orange(logdate);
12601260
\dPt test*apple*
12611261
\dPi test*apple*
12621262

1263+
-- only non-partition relations should be displayed
1264+
\dN
1265+
\dN test*apple*
1266+
\dNt test*apple*
1267+
\dNi test*apple*
1268+
12631269
drop table testtable_apple;
12641270
drop table testtable_orange;
12651271
drop table testpart_apple;
@@ -1283,6 +1289,7 @@ create table child_35_40 partition of child_30_40
12831289
for values from (35) to (40);
12841290
insert into parent_tab values (generate_series(30,39));
12851291

1292+
-- only partition related object should be displayed
12861293
\dPt
12871294
\dPi
12881295

@@ -1294,6 +1301,14 @@ insert into parent_tab values (generate_series(30,39));
12941301
\dPn
12951302
\dPn testpart.*
12961303

1304+
-- only non-partition relations should be displayed
1305+
\dNt
1306+
\dNi
1307+
\dNit
1308+
\dN
1309+
1310+
\dN testpart.*
1311+
12971312
drop table parent_tab cascade;
12981313

12991314
drop schema testpart;

0 commit comments

Comments
 (0)