aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/psql')
-rw-r--r--src/bin/psql/command.c20
-rw-r--r--src/bin/psql/describe.c155
-rw-r--r--src/bin/psql/describe.h11
-rw-r--r--src/bin/psql/help.c5
-rw-r--r--src/bin/psql/tab-complete.c124
5 files changed, 305 insertions, 10 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 12b2f43abc3..147ee9125a1 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.198 2008/11/21 20:14:27 mha Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.199 2008/12/19 16:25:18 petere Exp $
*/
#include "postgres_fe.h"
#include "command.h"
@@ -416,7 +416,23 @@ exec_command(const char *cmd,
break;
}
break;
-
+ case 'e': /* SQL/MED subsystem */
+ switch(cmd[2])
+ {
+ case 's':
+ success = listForeignServers(pattern, show_verbose);
+ break;
+ case 'u':
+ success = listUserMappings(pattern, show_verbose);
+ break;
+ case 'w':
+ success = listForeignDataWrappers(pattern, show_verbose);
+ break;
+ default:
+ status = PSQL_CMD_UNKNOWN;
+ break;
+ }
+ break;
default:
status = PSQL_CMD_UNKNOWN;
}
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 5eb760513ec..601e478aee5 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -8,7 +8,7 @@
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.189 2008/12/19 14:39:58 alvherre Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.190 2008/12/19 16:25:18 petere Exp $
*/
#include "postgres_fe.h"
@@ -2785,3 +2785,156 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
PQclear(res);
return true;
}
+
+
+/*
+ * \dew
+ *
+ * Describes foreign-data wrappers
+ */
+bool
+listForeignDataWrappers(const char *pattern, bool verbose)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+
+ initPQExpBuffer(&buf);
+ printfPQExpBuffer(&buf,
+ "SELECT fdwname AS \"%s\",\n"
+ " pg_catalog.pg_get_userbyid(fdwowner) AS \"%s\",\n"
+ " fdwlibrary AS \"%s\"\n",
+ gettext_noop("Name"),
+ gettext_noop("Owner"),
+ gettext_noop("Library"));
+
+ if (verbose)
+ appendPQExpBuffer(&buf,
+ ",\n fdwacl AS \"%s\","
+ " fdwoptions AS \"%s\"",
+ gettext_noop("Access privileges"),
+ gettext_noop("Options"));
+
+ appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper WHERE 1=1\n");
+
+ processSQLNamePattern(pset.db, &buf, pattern, true, false,
+ NULL, "fdwname", NULL, NULL);
+
+ appendPQExpBuffer(&buf, "ORDER BY 1;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ myopt.title = _("List of foreign-data wrappers");
+ myopt.translate_header = true;
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
+
+/*
+ * \des
+ *
+ * Describes servers.
+ */
+bool
+listForeignServers(const char *pattern, bool verbose)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+
+ initPQExpBuffer(&buf);
+ printfPQExpBuffer(&buf,
+ "SELECT s.srvname AS \"%s\",\n"
+ " pg_catalog.pg_get_userbyid(s.srvowner) AS \"%s\",\n"
+ " f.fdwname AS \"%s\"\n",
+ gettext_noop("Name"),
+ gettext_noop("Owner"),
+ gettext_noop("Foreign-data wrapper"));
+
+ if (verbose)
+ appendPQExpBuffer(&buf,
+ ",\n s.srvacl AS \"%s\","
+ " s.srvtype AS \"%s\","
+ " s.srvversion AS \"%s\","
+ " s.srvoptions AS \"%s\"",
+ gettext_noop("Access privileges"),
+ gettext_noop("Type"),
+ gettext_noop("Version"),
+ gettext_noop("Options"));
+
+ appendPQExpBuffer(&buf,
+ "\nFROM pg_foreign_server s\n"
+ "JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
+
+ processSQLNamePattern(pset.db, &buf, pattern, true, false,
+ NULL, "s.srvname", NULL, NULL);
+
+ appendPQExpBuffer(&buf, "ORDER BY 1;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ myopt.title = _("List of foreign servers");
+ myopt.translate_header = true;
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
+
+/*
+ * \deu
+ *
+ * Describes user mappings.
+ */
+bool
+listUserMappings(const char *pattern, bool verbose)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+
+ initPQExpBuffer(&buf);
+ printfPQExpBuffer(&buf,
+ "SELECT um.srvname AS \"%s\",\n"
+ " um.usename AS \"%s\"",
+ gettext_noop("Server"),
+ gettext_noop("Username"));
+
+ if (verbose)
+ appendPQExpBuffer(&buf,
+ ",\n um.umoptions AS \"%s\"",
+ gettext_noop("Options"));
+
+ appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_user_mappings um WHERE 1=1\n");
+
+ processSQLNamePattern(pset.db, &buf, pattern, true, false,
+ NULL, "um.srvname", "um.usename", NULL);
+
+ appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ myopt.title = _("List of user mappings");
+ myopt.translate_header = true;
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 76e37d4e7f3..a0959576be7 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.35 2008/01/01 19:45:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.36 2008/12/19 16:25:18 petere Exp $
*/
#ifndef DESCRIBE_H
#define DESCRIBE_H
@@ -66,5 +66,14 @@ extern bool listCasts(const char *pattern);
/* \dn */
extern bool listSchemas(const char *pattern, bool verbose);
+/* \dew */
+extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+
+/* \des */
+extern bool listForeignServers(const char *pattern, bool verbose);
+
+/* \deu */
+extern bool listUserMappings(const char *pattern, bool verbose);
+
#endif /* DESCRIBE_H */
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 49db83c03d4..164d17bba56 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.131 2008/11/06 15:18:36 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.132 2008/12/19 16:25:18 petere Exp $
*/
#include "postgres_fe.h"
@@ -203,6 +203,9 @@ slashUsage(unsigned short int pager)
fprintf(output, _(" \\dC [PATTERN] list casts\n"));
fprintf(output, _(" \\dd [PATTERN] show comment for object\n"));
fprintf(output, _(" \\dD [PATTERN] list domains\n"));
+ fprintf(output, _(" \\des [PATTERN] list foreign servers (add \"+\" for more detail)\n"));
+ fprintf(output, _(" \\deu [PATTERN] list user mappings (add \"+\" for more detail)\n"));
+ fprintf(output, _(" \\dew [PATTERN] list foreign-data wrappers (add \"+\" for more detail)\n"));
fprintf(output, _(" \\df [PATTERN] list functions (add \"+\" for more detail)\n"));
fprintf(output, _(" \\dF [PATTERN] list text search configurations (add \"+\" for more detail)\n"));
fprintf(output, _(" \\dFd [PATTERN] list text search dictionaries (add \"+\" for more detail)\n"));
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 635e0c7fa7b..54363a3e74e 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.177 2008/11/20 14:04:46 petere Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.178 2008/12/19 16:25:18 petere Exp $
*/
/*----------------------------------------------------------------------
@@ -497,6 +497,21 @@ static const SchemaQuery Query_for_list_of_views = {
"SELECT pg_catalog.quote_ident(tmplname) FROM pg_catalog.pg_ts_template "\
" WHERE substring(pg_catalog.quote_ident(tmplname),1,%d)='%s'"
+#define Query_for_list_of_fdws \
+" SELECT pg_catalog.quote_ident(fdwname) "\
+" FROM pg_catalog.pg_foreign_data_wrapper "\
+" WHERE substring(pg_catalog.quote_ident(fdwname),1,%d)='%s'"
+
+#define Query_for_list_of_servers \
+" SELECT pg_catalog.quote_ident(srvname) "\
+" FROM pg_catalog.pg_foreign_server "\
+" WHERE substring(pg_catalog.quote_ident(srvname),1,%d)='%s'"
+
+#define Query_for_list_of_user_mappings \
+" SELECT pg_catalog.quote_ident(usename) "\
+" FROM pg_catalog.pg_user_mappings "\
+" WHERE substring(pg_catalog.quote_ident(usename),1,%d)='%s'"
+
/*
* This is a list of all "things" in Pgsql, which can show up after CREATE or
* DROP; and there is also a query to get a list of them.
@@ -525,6 +540,7 @@ static const pgsql_thing_t words_after_create[] = {
{"DATABASE", Query_for_list_of_databases},
{"DICTIONARY", Query_for_list_of_ts_dictionaries, NULL, true},
{"DOMAIN", NULL, &Query_for_list_of_domains},
+ {"FOREIGN DATA WRAPPER", NULL, NULL},
{"FUNCTION", NULL, &Query_for_list_of_functions},
{"GROUP", Query_for_list_of_roles},
{"LANGUAGE", Query_for_list_of_languages},
@@ -536,6 +552,7 @@ static const pgsql_thing_t words_after_create[] = {
{"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
{"SCHEMA", Query_for_list_of_schemas},
{"SEQUENCE", NULL, &Query_for_list_of_sequences},
+ {"SERVER", Query_for_list_of_servers},
{"TABLE", NULL, &Query_for_list_of_tables},
{"TABLESPACE", Query_for_list_of_tablespaces},
{"TEMP", NULL, NULL}, /* for CREATE TEMP TABLE ... */
@@ -545,6 +562,7 @@ static const pgsql_thing_t words_after_create[] = {
{"TYPE", NULL, &Query_for_list_of_datatypes},
{"UNIQUE", NULL, NULL}, /* for CREATE UNIQUE INDEX ... */
{"USER", Query_for_list_of_roles},
+ {"USER MAPPING FOR", NULL, NULL},
{"VIEW", NULL, &Query_for_list_of_views},
{NULL, NULL, NULL, false} /* end of list */
};
@@ -621,7 +639,7 @@ psql_completion(char *text, int start, int end)
static const char *const backslash_commands[] = {
"\\a", "\\connect", "\\C", "\\cd", "\\copy", "\\copyright",
- "\\d", "\\da", "\\db", "\\dc", "\\dC", "\\dd", "\\dD", "\\df",
+ "\\d", "\\da", "\\db", "\\dc", "\\dC", "\\dd", "\\dD", "\\des", "\\deu", "\\dew", "\\df",
"\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl",
"\\dn", "\\do", "\\dp", "\\ds", "\\dS", "\\dt", "\\dT", "\\dv", "\\du",
"\\e", "\\echo", "\\encoding",
@@ -686,9 +704,9 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev3_wd, "TABLE") != 0)
{
static const char *const list_ALTER[] =
- {"AGGREGATE", "CONVERSION", "DATABASE", "DOMAIN", "FUNCTION",
- "GROUP", "INDEX", "LANGUAGE", "OPERATOR", "ROLE", "SCHEMA", "SEQUENCE", "TABLE",
- "TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE", "USER", "VIEW", NULL};
+ {"AGGREGATE", "CONVERSION", "DATABASE", "DOMAIN", "FOREIGN DATA WRAPPER", "FUNCTION",
+ "GROUP", "INDEX", "LANGUAGE", "OPERATOR", "ROLE", "SCHEMA", "SERVER", "SEQUENCE", "TABLE",
+ "TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE", "USER", "USER MAPPING FOR", "VIEW", NULL};
COMPLETE_WITH_LIST(list_ALTER);
}
@@ -724,6 +742,18 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST(list_ALTERDATABASE);
}
+ /* ALTER FOREIGN DATA WRAPPER <name> */
+ else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev4_wd, "FOREIGN") == 0 &&
+ pg_strcasecmp(prev3_wd, "DATA") == 0 &&
+ pg_strcasecmp(prev2_wd, "WRAPPER") == 0)
+ {
+ static const char *const list_ALTER_FDW[] =
+ {"LIBRARY", "OPTIONS", "OWNER TO", NULL};
+
+ COMPLETE_WITH_LIST(list_ALTER_FDW);
+ }
+
/* ALTER INDEX <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "INDEX") == 0)
@@ -746,6 +776,7 @@ psql_completion(char *text, int start, int end)
/* ALTER USER,ROLE <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+ !(pg_strcasecmp(prev2_wd, "USER") == 0 && pg_strcasecmp(prev_wd, "MAPPING") == 0) &&
(pg_strcasecmp(prev2_wd, "USER") == 0 ||
pg_strcasecmp(prev2_wd, "ROLE") == 0))
{
@@ -814,6 +845,15 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST(list_ALTERSEQUENCE2);
}
+ /* ALTER SERVER <name> */
+ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev2_wd, "SERVER") == 0)
+ {
+ static const char *const list_ALTER_SERVER[] =
+ {"VERSION", "OPTIONS", "OWNER TO", NULL};
+
+ COMPLETE_WITH_LIST(list_ALTER_SERVER);
+ }
/* ALTER VIEW <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "VIEW") == 0)
@@ -1213,6 +1253,18 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev_wd, "TEMPLATE") == 0)
COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
+ /* CREATE FOREIGN DATA WRAPPER */
+ else if (pg_strcasecmp(prev5_wd, "CREATE") == 0 &&
+ pg_strcasecmp(prev4_wd, "FOREIGN") == 0 &&
+ pg_strcasecmp(prev3_wd, "DATA") == 0 &&
+ pg_strcasecmp(prev2_wd, "WRAPPER") == 0)
+ COMPLETE_WITH_CONST("LIBRARY");
+
+ else if (pg_strcasecmp(prev5_wd, "DATA") == 0 &&
+ pg_strcasecmp(prev4_wd, "WRAPPER") == 0 &&
+ pg_strcasecmp(prev2_wd, "LIBRARY") == 0)
+ COMPLETE_WITH_CONST("LANGUAGE C");
+
/* CREATE INDEX */
/* First off we complete CREATE UNIQUE with "INDEX" */
else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 &&
@@ -1289,6 +1341,16 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev_wd, "TO") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
+/* CREATE SERVER <name> */
+ else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
+ pg_strcasecmp(prev2_wd, "SERVER") == 0)
+ {
+ static const char *const list_CREATE_SERVER[] =
+ {"TYPE", "VERSION", "FOREIGN DATA WRAPPER", NULL};
+
+ COMPLETE_WITH_LIST(list_CREATE_SERVER);
+ }
+
/* CREATE TABLE */
/* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 &&
@@ -1357,6 +1419,7 @@ psql_completion(char *text, int start, int end)
/* CREATE ROLE,USER,GROUP */
else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
+ !(pg_strcasecmp(prev2_wd, "USER") == 0 && pg_strcasecmp(prev_wd, "MAPPING") == 0) &&
(pg_strcasecmp(prev2_wd, "ROLE") == 0 ||
pg_strcasecmp(prev2_wd, "GROUP") == 0 || pg_strcasecmp(prev2_wd, "USER") == 0))
{
@@ -1472,6 +1535,7 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev2_wd, "LANGUAGE") == 0 ||
pg_strcasecmp(prev2_wd, "SCHEMA") == 0 ||
pg_strcasecmp(prev2_wd, "SEQUENCE") == 0 ||
+ pg_strcasecmp(prev2_wd, "SERVER") == 0 ||
pg_strcasecmp(prev2_wd, "TABLE") == 0 ||
pg_strcasecmp(prev2_wd, "TYPE") == 0 ||
pg_strcasecmp(prev2_wd, "VIEW") == 0)) ||
@@ -1479,6 +1543,10 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev3_wd, "AGGREGATE") == 0 &&
prev_wd[strlen(prev_wd) - 1] == ')') ||
(pg_strcasecmp(prev5_wd, "DROP") == 0 &&
+ pg_strcasecmp(prev4_wd, "FOREIGN") == 0 &&
+ pg_strcasecmp(prev3_wd, "DATA") == 0 &&
+ pg_strcasecmp(prev2_wd, "WRAPPER") == 0) ||
+ (pg_strcasecmp(prev5_wd, "DROP") == 0 &&
pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
(pg_strcasecmp(prev2_wd, "CONFIGURATION") == 0 ||
@@ -1607,6 +1675,14 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST(list_FROMIN);
}
+/* FOREIGN DATA WRAPPER */
+ /* applies in ALTER/DROP FDW and in CREATE SERVER */
+ else if (pg_strcasecmp(prev4_wd, "CREATE") != 0 &&
+ pg_strcasecmp(prev3_wd, "FOREIGN") == 0 &&
+ pg_strcasecmp(prev2_wd, "DATA") == 0 &&
+ pg_strcasecmp(prev_wd, "WRAPPER") == 0)
+ COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
+
/* GRANT && REVOKE*/
/* Complete GRANT/REVOKE with a list of privileges */
else if (pg_strcasecmp(prev_wd, "GRANT") == 0 ||
@@ -1640,6 +1716,8 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev_wd, "ON") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv,
" UNION SELECT 'DATABASE'"
+ " UNION SELECT 'FOREIGN DATA WRAPPER'"
+ " UNION SELECT 'FOREIGN SERVER'"
" UNION SELECT 'FUNCTION'"
" UNION SELECT 'LANGUAGE'"
" UNION SELECT 'SCHEMA'"
@@ -1759,6 +1837,10 @@ psql_completion(char *text, int start, int end)
else if (pg_strcasecmp(prev_wd, "NOTIFY") == 0)
COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s'");
+/* OPTIONS */
+ else if (pg_strcasecmp(prev_wd, "OPTIONS") == 0)
+ COMPLETE_WITH_CONST("(");
+
/* OWNER TO - complete with available roles */
else if (pg_strcasecmp(prev2_wd, "OWNER") == 0 &&
pg_strcasecmp(prev_wd, "TO") == 0)
@@ -2012,6 +2094,32 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev4_wd, "UPDATE") == 0)
COMPLETE_WITH_CONST("=");
+/* USER MAPPING */
+ else if ((pg_strcasecmp(prev3_wd, "ALTER") == 0 ||
+ pg_strcasecmp(prev3_wd, "CREATE") == 0 ||
+ pg_strcasecmp(prev3_wd, "DROP") == 0) &&
+ pg_strcasecmp(prev2_wd, "USER") == 0 &&
+ pg_strcasecmp(prev_wd, "MAPPING") == 0)
+ COMPLETE_WITH_CONST("FOR");
+ else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 &&
+ pg_strcasecmp(prev3_wd, "USER") == 0 &&
+ pg_strcasecmp(prev2_wd, "MAPPING") == 0 &&
+ pg_strcasecmp(prev_wd, "FOR") == 0)
+ COMPLETE_WITH_QUERY(Query_for_list_of_roles);
+ else if ((pg_strcasecmp(prev4_wd, "ALTER") == 0 ||
+ pg_strcasecmp(prev4_wd, "DROP") == 0) &&
+ pg_strcasecmp(prev3_wd, "USER") == 0 &&
+ pg_strcasecmp(prev2_wd, "MAPPING") == 0 &&
+ pg_strcasecmp(prev_wd, "FOR") == 0)
+ COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
+ else if ((pg_strcasecmp(prev5_wd, "CREATE") == 0 ||
+ pg_strcasecmp(prev5_wd, "ALTER") == 0 ||
+ pg_strcasecmp(prev5_wd, "DROP") == 0) &&
+ pg_strcasecmp(prev4_wd, "USER") == 0 &&
+ pg_strcasecmp(prev3_wd, "MAPPING") == 0 &&
+ pg_strcasecmp(prev2_wd, "FOR") == 0)
+ COMPLETE_WITH_CONST("SERVER");
+
/*
* VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ]
* VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]
@@ -2088,6 +2196,12 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
else if (strcmp(prev_wd, "\\dD") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
+ else if (strcmp(prev_wd, "\\des") == 0 || strcmp(prev_wd, "\\des+") == 0)
+ COMPLETE_WITH_QUERY(Query_for_list_of_servers);
+ else if (strcmp(prev_wd, "\\deu") == 0 || strcmp(prev_wd, "\\deu+") == 0)
+ COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
+ else if (strcmp(prev_wd, "\\dew") == 0 || strcmp(prev_wd, "\\dew+") == 0)
+ COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
else if (strcmp(prev_wd, "\\df") == 0 || strcmp(prev_wd, "\\df+") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
else if (strcmp(prev_wd, "\\dF") == 0 || strcmp(prev_wd, "\\dF+") == 0)