diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 041b5e0c87..548b0d8d41 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -349,8 +349,9 @@ exec_command(const char *cmd, status = exec_command_include(scan_state, active_branch, cmd); else if (strcmp(cmd, "if") == 0) status = exec_command_if(scan_state, cstack, query_buf); - else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 || - strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0) + else if (strcmp(cmd, "list") == 0 || strcmp(cmd, "list+") == 0 || + strcmp(cmd, "l") == 0 || strncmp(cmd, "l+", 2) == 0 || + strncmp(cmd, "ls", 2) == 0) status = exec_command_list(scan_state, active_branch, cmd); else if (strncmp(cmd, "lo_", 3) == 0) status = exec_command_lo(scan_state, active_branch, cmd); @@ -702,7 +703,9 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) { char *pattern; bool show_verbose, - show_system; + show_system, + sort_size, + sort_desc; /* We don't do SQLID reduction on the pattern yet */ pattern = psql_scan_slash_option(scan_state, @@ -711,6 +714,9 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) show_verbose = strchr(cmd, '+') ? true : false; show_system = strchr(cmd, 'S') ? true : false; + sort_size = false; + sort_desc = false; + switch (cmd[1]) { case '\0': @@ -720,7 +726,8 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = describeTableDetails(pattern, show_verbose, show_system); else /* standard listing of interesting things */ - success = listTables("tvmsE", NULL, show_verbose, show_system); + success = listTables("tvmsE", NULL, show_verbose, show_system, + false, false); break; case 'A': success = describeAccessMethods(pattern, show_verbose); @@ -789,12 +796,19 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = describeTypes(pattern, show_verbose, show_system); break; case 't': - case 'v': case 'm': case 'i': + if (strlen(cmd) >= 2) + { + sort_size = strchr(&cmd[2], 's') ? true : false; + sort_desc = strchr(&cmd[2], 'd') ? true : false; + } + + case 'v': case 's': case 'E': - success = listTables(&cmd[1], pattern, show_verbose, show_system); + success = listTables(&cmd[1], pattern, show_verbose, show_system, + sort_size, sort_desc); break; case 'r': if (cmd[2] == 'd' && cmd[3] == 's') @@ -1655,13 +1669,17 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd) { char *pattern; bool show_verbose; + bool sort_size; + bool sort_desc; pattern = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); show_verbose = strchr(cmd, '+') ? true : false; + sort_size = strchr(cmd, 's') ? true : false; + sort_desc = strchr(cmd, 'd') ? true : false; - success = listAllDbs(pattern, show_verbose); + success = listAllDbs(pattern, show_verbose, sort_size, sort_desc); if (pattern) free(pattern); diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 638275ca2f..e0acb95166 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -782,7 +782,7 @@ describeOperators(const char *pattern, bool verbose, bool showSystem) * for \l, \list, and -l switch */ bool -listAllDbs(const char *pattern, bool verbose) +listAllDbs(const char *pattern, bool verbose, bool sort_size, bool sort_desc) { PGresult *res; PQExpBufferData buf; @@ -830,7 +830,27 @@ listAllDbs(const char *pattern, bool verbose) processSQLNamePattern(pset.db, &buf, pattern, false, false, NULL, "d.datname", NULL, NULL); - appendPQExpBufferStr(&buf, "ORDER BY 1;"); + if (sort_size) + { + if (pset.sversion < 80200) + { + char sverbuf[32]; + + psql_error("The server (version %s) does not support database size function.\n", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); + return true; + } + + appendPQExpBufferStr(&buf, "ORDER BY pg_catalog.pg_database_size(d.datname)"); + + if (sort_desc) + appendPQExpBuffer(&buf, " DESC"); + + appendPQExpBuffer(&buf, ", 1;"); + } + else + appendPQExpBufferStr(&buf, "ORDER BY 1;"); res = PSQLexec(buf.data); termPQExpBuffer(&buf); if (!res) @@ -3336,7 +3356,8 @@ listDbRoleSettings(const char *pattern, const char *pattern2) * (any order of the above is fine) */ bool -listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem) +listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem, + bool sort_size, bool sort_desc) { bool showTables = strchr(tabtypes, 't') != NULL; bool showIndexes = strchr(tabtypes, 'i') != NULL; @@ -3457,7 +3478,34 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)"); - appendPQExpBufferStr(&buf, "ORDER BY 1,2;"); + if (sort_size) + { + appendPQExpBufferStr(&buf, "ORDER BY "); + + /* + * As of PostgreSQL 9.0, use pg_table_size() to show a more accurate + * size of a table, including FSM, VM and TOAST tables. + */ + if (pset.sversion >= 90000) + appendPQExpBuffer(&buf, "pg_catalog.pg_table_size(c.oid)"); + else if (pset.sversion >= 80100) + appendPQExpBuffer(&buf, "pg_catalog.pg_relation_size(c.oid)"); + else + { + char sverbuf[32]; + + psql_error("The server (version %s) does not support table size function.\n", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); + return true; + } + + if (sort_desc) + appendPQExpBufferStr(&buf, "DESC"); + appendPQExpBufferStr(&buf, " , 1,2;"); + } + else + appendPQExpBufferStr(&buf, "ORDER BY 1,2;"); res = PSQLexec(buf.data); termPQExpBuffer(&buf); diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 14a5667f3e..1941aab181 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -58,10 +58,11 @@ extern bool listTSDictionaries(const char *pattern, bool verbose); extern bool listTSTemplates(const char *pattern, bool verbose); /* \l */ -extern bool listAllDbs(const char *pattern, bool verbose); +extern bool listAllDbs(const char *pattern, bool verbose, bool sort_size, bool sort_desc); /* \dt, \di, \ds, \dS, etc. */ -extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem); +extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem, + bool sort_size, bool sort_desc); /* \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 a926c40b9b..620b8930a5 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -241,10 +241,10 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\dFp[+] [PATTERN] list text search parsers\n")); fprintf(output, _(" \\dFt[+] [PATTERN] list text search templates\n")); fprintf(output, _(" \\dg[S+] [PATTERN] list roles\n")); - fprintf(output, _(" \\di[S+] [PATTERN] list indexes\n")); + fprintf(output, _(" \\di[Ssd+] [PATTERN] list indexes\n")); fprintf(output, _(" \\dl list large objects, same as \\lo_list\n")); fprintf(output, _(" \\dL[S+] [PATTERN] list procedural languages\n")); - fprintf(output, _(" \\dm[S+] [PATTERN] list materialized views\n")); + fprintf(output, _(" \\dm[Ssd+] [PATTERN] list materialized views\n")); fprintf(output, _(" \\dn[S+] [PATTERN] list schemas\n")); fprintf(output, _(" \\do[S] [PATTERN] list operators\n")); fprintf(output, _(" \\dO[S+] [PATTERN] list collations\n")); @@ -253,13 +253,13 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\dRp[+] [PATTERN] list replication publications\n")); fprintf(output, _(" \\dRs[+] [PATTERN] list replication subscriptions\n")); fprintf(output, _(" \\ds[S+] [PATTERN] list sequences\n")); - fprintf(output, _(" \\dt[S+] [PATTERN] list tables\n")); + fprintf(output, _(" \\dt[Ssd+] [PATTERN] list tables\n")); fprintf(output, _(" \\dT[S+] [PATTERN] list data types\n")); fprintf(output, _(" \\du[S+] [PATTERN] list roles\n")); fprintf(output, _(" \\dv[S+] [PATTERN] list views\n")); fprintf(output, _(" \\dx[+] [PATTERN] list extensions\n")); fprintf(output, _(" \\dy [PATTERN] list event triggers\n")); - fprintf(output, _(" \\l[+] [PATTERN] list databases\n")); + fprintf(output, _(" \\l[sd+] [PATTERN] list databases\n")); fprintf(output, _(" \\sf[+] FUNCNAME show a function's definition\n")); fprintf(output, _(" \\sv[+] VIEWNAME show a view's definition\n")); fprintf(output, _(" \\z [PATTERN] same as \\dp\n"));