1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

SQL/MED catalog manipulation facilities

This doesn't do any remote or external things yet, but it gives modules
like plproxy and dblink a standardized and future-proof system for
managing their connection information.

Martin Pihlak and Peter Eisentraut
This commit is contained in:
Peter Eisentraut
2008-12-19 16:25:19 +00:00
parent 1eec10a2de
commit cae565e503
76 changed files with 8452 additions and 125 deletions

View File

@ -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,12 +1535,17 @@ 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)) ||
(pg_strcasecmp(prev4_wd, "DROP") == 0 &&
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 &&
@ -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)