diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 6ae788067edc14eccb4ac7b16d71a3245fecaf2f..075453d6c774a727ddfe37d5f653d0b60e9c8a2c 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.148 2005/07/18 20:57:52 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.149 2005/08/14 18:49:29 tgl Exp $ PostgreSQL documentation --> @@ -963,9 +963,10 @@ testdb=> <term><literal>\dg [ <replaceable class="parameter">pattern</replaceable> ]</literal></term> <listitem> <para> - Lists all database groups. If <replaceable + Lists all database roles. If <replaceable class="parameter">pattern</replaceable> is specified, only - those groups whose names match the pattern are listed. + those roles whose names match the pattern are listed. + (This command is now effectively the same as <literal>\du</>.) </para> </listitem> </varlistentry> @@ -1073,7 +1074,7 @@ testdb=> <term><literal>\du [ <replaceable class="parameter">pattern</replaceable> ]</literal></term> <listitem> <para> - Lists all database users or only those that match <replaceable + Lists all database roles, or only those that match <replaceable class="parameter">pattern</replaceable>. </para> </listitem> diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 824f23210353d67c692047e88dd4bdaacc0da6ec..b46c0f9574aeb4938b435de830e7259bb78b208b 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.151 2005/07/25 17:17:41 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.152 2005/08/14 18:49:30 tgl Exp $ */ #include "postgres_fe.h" #include "command.h" @@ -338,7 +338,8 @@ exec_command(const char *cmd, success = describeFunctions(pattern, show_verbose); break; case 'g': - success = describeGroups(pattern); + /* no longer distinct from \du */ + success = describeRoles(pattern); break; case 'l': success = do_lo_list(); @@ -363,7 +364,7 @@ exec_command(const char *cmd, success = listTables(&cmd[1], pattern, show_verbose); break; case 'u': - success = describeUsers(pattern); + success = describeRoles(pattern); break; default: diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 806c16198768bf73fc137c672b78c9e7632bc820..4859b2ed2bae06b929458defd37e4459a2bd49fa 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.122 2005/07/18 19:09:09 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.123 2005/08/14 18:49:30 tgl Exp $ */ #include "postgres_fe.h" #include "describe.h" @@ -1377,12 +1377,12 @@ add_tablespace_footer(char relkind, Oid tablespace, char **footers, } /* - * \du + * \du or \dg * - * Describes users. Any schema portion of the pattern is ignored. + * Describes roles. Any schema portion of the pattern is ignored. */ bool -describeUsers(const char *pattern) +describeRoles(const char *pattern) { PQExpBufferData buf; PGresult *res; @@ -1391,62 +1391,24 @@ describeUsers(const char *pattern) initPQExpBuffer(&buf); printfPQExpBuffer(&buf, - "SELECT u.usename AS \"%s\",\n" - " u.usesysid AS \"%s\",\n" - " CASE WHEN u.usesuper AND u.usecreatedb THEN CAST('%s' AS pg_catalog.text)\n" - " WHEN u.usesuper THEN CAST('%s' AS pg_catalog.text)\n" - " WHEN u.usecreatedb THEN CAST('%s' AS pg_catalog.text)\n" - " ELSE CAST('' AS pg_catalog.text)\n" - " END AS \"%s\",\n" - " ARRAY(SELECT g.groname FROM pg_catalog.pg_group g WHERE u.usesysid = ANY(g.grolist)) as \"%s\"\n" - "FROM pg_catalog.pg_user u\n", - _("User name"), _("User ID"), - _("superuser, create database"), - _("superuser"), _("create database"), - _("Attributes"), _("Groups")); - - processNamePattern(&buf, pattern, false, false, - NULL, "u.usename", 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 users"); - - printQuery(res, &myopt, pset.queryFout, pset.logfile); - - PQclear(res); - return true; -} - - -/* - * \dg - * - * Describes groups. - */ -bool -describeGroups(const char *pattern) -{ - PQExpBufferData buf; - PGresult *res; - printQueryOpt myopt = pset.popt; - - initPQExpBuffer(&buf); - - printfPQExpBuffer(&buf, - "SELECT g.groname AS \"%s\",\n" - " g.grosysid AS \"%s\"\n" - "FROM pg_catalog.pg_group g\n", - _("Group name"), _("Group ID")); + "SELECT r.rolname AS \"%s\",\n" + " CASE WHEN r.rolsuper THEN '%s' ELSE '%s' END AS \"%s\",\n" + " CASE WHEN r.rolcreaterole THEN '%s' ELSE '%s' END AS \"%s\",\n" + " CASE WHEN r.rolcreatedb THEN '%s' ELSE '%s' END AS \"%s\",\n" + " CASE WHEN r.rolconnlimit < 0 THEN CAST('%s' AS pg_catalog.text)\n" + " ELSE CAST(r.rolconnlimit AS pg_catalog.text)\n" + " END AS \"%s\", \n" + " ARRAY(SELECT b.rolname FROM pg_catalog.pg_auth_members m JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid) WHERE m.member = r.oid) as \"%s\"\n" + "FROM pg_catalog.pg_roles r\n", + _("Role name"), + _("yes"),_("no"),_("Superuser"), + _("yes"),_("no"),_("Create role"), + _("yes"),_("no"),_("Create DB"), + _("no limit"),_("Connections"), + _("Member of")); processNamePattern(&buf, pattern, false, false, - NULL, "g.groname", NULL, NULL); + NULL, "r.rolname", NULL, NULL); appendPQExpBuffer(&buf, "ORDER BY 1;"); @@ -1456,7 +1418,7 @@ describeGroups(const char *pattern) return false; myopt.nullPrint = NULL; - myopt.title = _("List of groups"); + myopt.title = _("List of roles"); printQuery(res, &myopt, pset.queryFout, pset.logfile); diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 170682965dc80cfa727d56bca3b60c0753f4ced8..22528f95a3605c649778981686a5c968b3143dde 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.28 2005/01/01 05:43:08 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.29 2005/08/14 18:49:30 tgl Exp $ */ #ifndef DESCRIBE_H #define DESCRIBE_H @@ -11,52 +11,49 @@ #include "settings.h" /* \da */ -bool describeAggregates(const char *pattern, bool verbose); +extern bool describeAggregates(const char *pattern, bool verbose); /* \db */ -bool describeTablespaces(const char *pattern, bool verbose); +extern bool describeTablespaces(const char *pattern, bool verbose); /* \df */ -bool describeFunctions(const char *pattern, bool verbose); +extern bool describeFunctions(const char *pattern, bool verbose); /* \dT */ -bool describeTypes(const char *pattern, bool verbose); +extern bool describeTypes(const char *pattern, bool verbose); /* \do */ -bool describeOperators(const char *pattern); +extern bool describeOperators(const char *pattern); -/* \du */ -bool describeUsers(const char *pattern); - -/* \dg */ -bool describeGroups(const char *pattern); +/* \du, \dg */ +extern bool describeRoles(const char *pattern); /* \z (or \dp) */ -bool permissionsList(const char *pattern); +extern bool permissionsList(const char *pattern); /* \dd */ -bool objectDescription(const char *pattern); +extern bool objectDescription(const char *pattern); /* \d foo */ -bool describeTableDetails(const char *pattern, bool verbose); +extern bool describeTableDetails(const char *pattern, bool verbose); /* \l */ -bool listAllDbs(bool verbose); +extern bool listAllDbs(bool verbose); /* \dt, \di, \ds, \dS, etc. */ -bool listTables(const char *tabtypes, const char *pattern, bool verbose); +extern bool listTables(const char *tabtypes, const char *pattern, bool verbose); /* \dD */ -bool listDomains(const char *pattern); +extern bool listDomains(const char *pattern); /* \dc */ -bool listConversions(const char *pattern); +extern bool listConversions(const char *pattern); /* \dC */ -bool listCasts(const char *pattern); +extern bool listCasts(const char *pattern); /* \dn */ -bool listSchemas(const char *pattern, bool verbose); +extern bool listSchemas(const char *pattern, bool verbose); #endif /* DESCRIBE_H */ diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 2be131993bb884910c0c643f652a8725a6634507..3a5fe0ab1f6d662220e698d36b0175f524538274 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.136 2005/07/30 15:17:22 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.137 2005/08/14 18:49:30 tgl Exp $ */ /*---------------------------------------------------------------------- @@ -355,6 +355,24 @@ static const SchemaQuery Query_for_list_of_views = { "SELECT pg_catalog.quote_ident(nspname) FROM pg_catalog.pg_namespace "\ " WHERE substring(pg_catalog.quote_ident(nspname),1,%d)='%s'" +#define Query_for_list_of_set_vars \ +"SELECT name FROM "\ +" (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\ +" WHERE context IN ('user', 'superuser') "\ +" UNION ALL SELECT 'constraints' "\ +" UNION ALL SELECT 'transaction' "\ +" UNION ALL SELECT 'session' "\ +" UNION ALL SELECT 'role' "\ +" UNION ALL SELECT 'all') ss "\ +" WHERE substring(name,1,%d)='%s'" + +#define Query_for_list_of_show_vars \ +"SELECT name FROM "\ +" (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\ +" UNION ALL SELECT 'session authorization' "\ +" UNION ALL SELECT 'all') ss "\ +" WHERE substring(name,1,%d)='%s'" + #define Query_for_list_of_system_relations \ "SELECT pg_catalog.quote_ident(relname) "\ " FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n "\ @@ -363,16 +381,16 @@ static const SchemaQuery Query_for_list_of_views = { " AND c.relnamespace = n.oid "\ " AND n.nspname = 'pg_catalog'" -#define Query_for_list_of_users \ -" SELECT pg_catalog.quote_ident(usename) "\ -" FROM pg_catalog.pg_user "\ -" WHERE substring(pg_catalog.quote_ident(usename),1,%d)='%s'" +#define Query_for_list_of_roles \ +" SELECT pg_catalog.quote_ident(rolname) "\ +" FROM pg_catalog.pg_roles "\ +" WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'" -#define Query_for_list_of_grant_users \ -" SELECT pg_catalog.quote_ident(usename) "\ -" FROM pg_catalog.pg_user "\ -" WHERE substring(pg_catalog.quote_ident(usename),1,%d)='%s'"\ -" UNION SELECT 'PUBLIC' UNION SELECT 'GROUP'" +#define Query_for_list_of_grant_roles \ +" SELECT pg_catalog.quote_ident(rolname) "\ +" FROM pg_catalog.pg_roles "\ +" WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\ +" UNION ALL SELECT 'PUBLIC'" /* the silly-looking length condition is just to eat up the current word */ #define Query_for_table_owning_index \ @@ -422,11 +440,12 @@ static const pgsql_thing_t words_after_create[] = { {"DATABASE", Query_for_list_of_databases}, {"DOMAIN", NULL, &Query_for_list_of_domains}, {"FUNCTION", NULL, &Query_for_list_of_functions}, - {"GROUP", "SELECT pg_catalog.quote_ident(groname) FROM pg_catalog.pg_group WHERE substring(pg_catalog.quote_ident(groname),1,%d)='%s'"}, + {"GROUP", Query_for_list_of_roles}, {"LANGUAGE", Query_for_list_of_languages}, {"INDEX", NULL, &Query_for_list_of_indexes}, {"OPERATOR", NULL, NULL}, /* Querying for this is probably not such * a good idea. */ + {"ROLE", Query_for_list_of_roles}, {"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}, @@ -436,7 +455,7 @@ static const pgsql_thing_t words_after_create[] = { {"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s'"}, {"TYPE", NULL, &Query_for_list_of_datatypes}, {"UNIQUE", NULL, NULL}, /* for CREATE UNIQUE INDEX ... */ - {"USER", Query_for_list_of_users}, + {"USER", Query_for_list_of_roles}, {"VIEW", NULL, &Query_for_list_of_views}, {NULL, NULL, NULL} /* end of list */ }; @@ -506,118 +525,6 @@ psql_completion(char *text, int start, int end) "SELECT", "SET", "SHOW", "START", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", NULL }; - static const char *const pgsql_variables[] = { - /* these SET arguments are known in gram.y */ - "CONSTRAINTS", - "NAMES", - "SESSION", - "TRANSACTION", - - /* - * the rest should match USERSET and possibly SUSET entries in - * backend/utils/misc/guc.c. - */ - "add_missing_from", - "australian_timezones", - "client_encoding", - "client_min_messages", - "commit_delay", - "commit_siblings", - "cpu_index_tuple_cost", - "cpu_operator_cost", - "cpu_tuple_cost", - "DateStyle", - "deadlock_timeout", - "debug_pretty_print", - "debug_print_parse", - "debug_print_plan", - "debug_print_rewritten", - "default_statistics_target", - "default_tablespace", - "default_transaction_isolation", - "default_transaction_read_only", - "default_with_oids", - "dynamic_library_path", - "effective_cache_size", - "enable_bitmapscan", - "enable_constraint_exclusion", - "enable_hashagg", - "enable_hashjoin", - "enable_indexscan", - "enable_mergejoin", - "enable_nestloop", - "enable_seqscan", - "enable_sort", - "enable_tidscan", - "explain_pretty_print", - "extra_float_digits", - "from_collapse_limit", - "fsync", - "geqo", - "geqo_effort", - "geqo_generations", - "geqo_pool_size", - "geqo_selection_bias", - "geqo_threshold", - "join_collapse_limit", - "lc_messages", - "lc_monetary", - "lc_numeric", - "lc_time", - "log_destination", - "log_duration", - "log_error_verbosity", - "log_executor_stats", - "log_min_duration_statement", - "log_min_error_statement", - "log_min_messages", - "log_parser_stats", - "log_planner_stats", - "log_statement", - "log_statement_stats", - "maintenance_work_mem", - "max_connections", - "max_files_per_process", - "max_fsm_pages", - "max_fsm_relations", - "max_locks_per_transaction", - "max_stack_depth", - "password_encryption", - "port", - "random_page_cost", - "regex_flavor", - "search_path", - "shared_buffers", - "seed", - "server_encoding", - "sql_inheritance", - "ssl", - "statement_timeout", - "stats_block_level", - "stats_command_string", - "stats_reset_on_server_start", - "stats_row_level", - "stats_start_collector", - "superuser_reserved_connections", - "syslog_facility", - "syslog_ident", - "tcp_keepalives_idle", - "tcp_keepalives_interval", - "tcp_keepalives_count", - "temp_buffers", - "TimeZone", - "trace_notify", - "transform_null_equals", - "unix_socket_directory", - "unix_socket_group", - "unix_socket_permissions", - "wal_buffers", - "wal_debug", - "wal_sync_method", - "work_mem", - NULL - }; - static const char *const backslash_commands[] = { "\\a", "\\connect", "\\C", "\\cd", "\\copy", "\\copyright", "\\d", "\\da", "\\db", "\\dc", "\\dC", "\\dd", "\\dD", "\\df", @@ -681,17 +588,25 @@ psql_completion(char *text, int start, int end) { static const char *const list_ALTER[] = {"AGGREGATE", "CONVERSION", "DATABASE", "DOMAIN", "FUNCTION", - "GROUP", "INDEX", "LANGUAGE", "OPERATOR", "SCHEMA", "SEQUENCE", "TABLE", + "GROUP", "INDEX", "LANGUAGE", "OPERATOR", "ROLE", "SCHEMA", "SEQUENCE", "TABLE", "TABLESPACE", "TRIGGER", "TYPE", "USER", NULL}; COMPLETE_WITH_LIST(list_ALTER); } + /* ALTER AGGREGATE,FUNCTION <name> */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + (pg_strcasecmp(prev2_wd, "AGGREGATE") == 0 || + pg_strcasecmp(prev2_wd, "FUNCTION") == 0)) + { + static const char *const list_ALTERAGG[] = + {"OWNER TO", "RENAME TO","SET SCHEMA", NULL}; - /* ALTER AGGREGATE,CONVERSION,FUNCTION,SCHEMA <name> */ + COMPLETE_WITH_LIST(list_ALTERAGG); + } + + /* ALTER CONVERSION,SCHEMA <name> */ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && - (pg_strcasecmp(prev2_wd, "AGGREGATE") == 0 || - pg_strcasecmp(prev2_wd, "CONVERSION") == 0 || - pg_strcasecmp(prev2_wd, "FUNCTION") == 0 || + (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 || pg_strcasecmp(prev2_wd, "SCHEMA") == 0)) { static const char *const list_ALTERGEN[] = @@ -705,7 +620,7 @@ psql_completion(char *text, int start, int end) pg_strcasecmp(prev2_wd, "DATABASE") == 0) { static const char *const list_ALTERDATABASE[] = - {"RESET", "SET", "OWNER TO", "RENAME TO", NULL}; + {"RESET", "SET", "OWNER TO", "RENAME TO", "CONNECTION LIMIT", NULL}; COMPLETE_WITH_LIST(list_ALTERDATABASE); } @@ -725,17 +640,27 @@ psql_completion(char *text, int start, int end) pg_strcasecmp(prev2_wd, "LANGUAGE") == 0) COMPLETE_WITH_CONST("RENAME TO"); - /* ALTER USER <name> */ + /* ALTER USER,ROLE <name> */ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && - pg_strcasecmp(prev2_wd, "USER") == 0) + (pg_strcasecmp(prev2_wd, "USER") == 0 || + pg_strcasecmp(prev2_wd, "ROLE") == 0)) { static const char *const list_ALTERUSER[] = {"ENCRYPTED", "UNENCRYPTED", "CREATEDB", "NOCREATEDB", "CREATEUSER", - "NOCREATEUSER", "VALID UNTIL", "RENAME TO", "SET", "RESET", NULL}; + "NOCREATEUSER","CREATEROLE","NOCREATEROLE","INHERIT","NOINHERIT", + "LOGIN","NOLOGIN","CONNECTION LIMIT", "VALID UNTIL", "RENAME TO", + "SUPERUSER","NOSUPERUSER", "SET", "RESET", NULL}; COMPLETE_WITH_LIST(list_ALTERUSER); } + /* complete ALTER USER,ROLE <name> ENCRYPTED,UNENCRYPTED with PASSWORD */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0)) + { + COMPLETE_WITH_CONST("PASSWORD"); + } /* ALTER DOMAIN <name> */ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && pg_strcasecmp(prev2_wd, "DOMAIN") == 0) @@ -761,7 +686,7 @@ psql_completion(char *text, int start, int end) pg_strcasecmp(prev_wd, "SET") == 0) { static const char *const list_ALTERDOMAIN3[] = - {"DEFAULT", "NOT NULL", NULL}; + {"DEFAULT", "NOT NULL", "SCHEMA", NULL}; COMPLETE_WITH_LIST(list_ALTERDOMAIN3); } @@ -769,20 +694,21 @@ psql_completion(char *text, int start, int end) else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && pg_strcasecmp(prev2_wd, "SEQUENCE") == 0) { - static const char *const list_ALTERSCHEMA[] = - {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE", NULL}; + static const char *const list_ALTERSEQUENCE[] = + {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE", + "SET SCHEMA", NULL}; - COMPLETE_WITH_LIST(list_ALTERSCHEMA); + COMPLETE_WITH_LIST(list_ALTERSEQUENCE); } /* ALTER SEQUENCE <name> NO */ else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && pg_strcasecmp(prev3_wd, "SEQUENCE") == 0 && pg_strcasecmp(prev_wd, "NO") == 0) { - static const char *const list_ALTERSCHEMA2[] = + static const char *const list_ALTERSEQUENCE2[] = {"MINVALUE", "MAXVALUE", "CYCLE", NULL}; - COMPLETE_WITH_LIST(list_ALTERSCHEMA2); + COMPLETE_WITH_LIST(list_ALTERSEQUENCE2); } /* ALTER TRIGGER <name>, add ON */ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && @@ -871,12 +797,12 @@ psql_completion(char *text, int start, int end) completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_index_of_table); } - /* If we have TABLE <sth> SET, provide WITHOUT or TABLESPACE */ + /* If we have TABLE <sth> SET, provide WITHOUT,TABLESPACE and SCHEMA */ else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && pg_strcasecmp(prev_wd, "SET") == 0) { static const char *const list_TABLESET[] = - {"WITHOUT", "TABLESPACE", NULL}; + {"WITHOUT", "TABLESPACE","SCHEMA", NULL}; COMPLETE_WITH_LIST(list_TABLESET); } @@ -904,10 +830,14 @@ psql_completion(char *text, int start, int end) COMPLETE_WITH_LIST(list_ALTERTSPC); } - /* complete ALTER TYPE <foo> with OWNER TO */ + /* complete ALTER TYPE <foo> with OWNER TO, SET SCHEMA */ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && pg_strcasecmp(prev2_wd, "TYPE") == 0) - COMPLETE_WITH_CONST("OWNER TO"); + { + static const char *const list_ALTERTYPE[] = + {"OWNER TO", "SET SCHEMA", NULL}; + COMPLETE_WITH_LIST(list_ALTERTYPE); + } /* complete ALTER GROUP <foo> */ else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && pg_strcasecmp(prev2_wd, "GROUP") == 0) @@ -928,7 +858,7 @@ psql_completion(char *text, int start, int end) (pg_strcasecmp(prev2_wd, "ADD") == 0 || pg_strcasecmp(prev2_wd, "DROP") == 0) && pg_strcasecmp(prev_wd, "USER") == 0) - COMPLETE_WITH_QUERY(Query_for_list_of_users); + COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* BEGIN, END, ABORT */ else if (pg_strcasecmp(prev_wd, "BEGIN") == 0 || @@ -993,7 +923,7 @@ psql_completion(char *text, int start, int end) static const char *const list_COMMENT[] = {"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA", "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION", - "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", NULL}; + "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN","LARGE OBJECT", NULL}; COMPLETE_WITH_LIST(list_COMMENT); } @@ -1047,14 +977,25 @@ psql_completion(char *text, int start, int end) else if (pg_strcasecmp(prev_wd, "CSV") == 0 && (pg_strcasecmp(prev3_wd, "FROM") == 0 || pg_strcasecmp(prev3_wd, "TO") == 0)) - { + { static const char *const list_CSV[] = {"HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", NULL}; COMPLETE_WITH_LIST(list_CSV); - } + } -/* CREATE INDEX */ + /* CREATE DATABASE */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "DATABASE") == 0) + { + static const char *const list_DATABASE[] = + {"OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", "CONNECTION LIMIT", + NULL}; + + COMPLETE_WITH_LIST(list_DATABASE); + } + + /* CREATE INDEX */ /* First off we complete CREATE UNIQUE with "INDEX" */ else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 && pg_strcasecmp(prev_wd, "UNIQUE") == 0) @@ -1145,10 +1086,58 @@ psql_completion(char *text, int start, int end) } /* CREATE TRIGGER */ - /* is on the agenda . . . */ + /* complete CREATE TRIGGER <name> with BEFORE,AFTER */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "TRIGGER") == 0) + { + static const char *const list_CREATETRIGGER[] = + {"BEFORE", "AFTER", NULL}; + COMPLETE_WITH_LIST(list_CREATETRIGGER); + } + /* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */ + else if (pg_strcasecmp(prev5_wd, "CREATE") == 0 && + pg_strcasecmp(prev4_wd, "TRIGGER") == 0 && + (pg_strcasecmp(prev2_wd, "BEFORE") == 0 || + pg_strcasecmp(prev2_wd, "AFTER") == 0)) + { + static const char *const list_CREATETRIGGER2[] = + {"ON","OR",NULL}; + COMPLETE_WITH_LIST(list_CREATETRIGGER2); + } + +/* CREATE ROLE,USER,GROUP */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + (pg_strcasecmp(prev2_wd, "ROLE") == 0 || + pg_strcasecmp(prev2_wd, "GROUP") == 0 || pg_strcasecmp(prev2_wd, "USER") == 0)) + { + static const char *const list_CREATEROLE[] = + {"ADMIN","CONNECTION LIMIT","CREATEDB","CREATEROLE","CREATEUSER", + "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOINHERIT", "NOLOGIN", "NOCREATEDB", + "NOCREATEROLE", "NOCREATEUSER", "NOSUPERUSER", "ROLE", "SUPERUSER", "SYSID", + "UNENCRYPTED",NULL}; + COMPLETE_WITH_LIST(list_CREATEROLE); + } + /* complete CREATE ROLE,USER,GROUP <name> ENCRYPTED,UNENCRYPTED with PASSWORD */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || + pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0)) + { + COMPLETE_WITH_CONST("PASSWORD"); + } + /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || + pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + pg_strcasecmp(prev_wd, "IN") == 0) + { + static const char *const list_CREATEROLE3[] = + {"GROUP","ROLE",NULL}; + COMPLETE_WITH_LIST(list_CREATEROLE3); + } /* CREATE VIEW */ - /* Complete "CREATE VIEW <name>" with "AS" */ + /* Complete CREATE VIEW <name> with AS */ else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && pg_strcasecmp(prev2_wd, "VIEW") == 0) COMPLETE_WITH_CONST("AS"); @@ -1353,7 +1342,7 @@ psql_completion(char *text, int start, int end) pg_strcasecmp(prev_wd, "TO") == 0) || (pg_strcasecmp(prev5_wd, "REVOKE") == 0 && pg_strcasecmp(prev_wd, "FROM") == 0))) - COMPLETE_WITH_QUERY(Query_for_list_of_grant_users); + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* GROUP BY */ else if (pg_strcasecmp(prev3_wd, "FROM") == 0 && @@ -1438,10 +1427,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'"); -/* OWNER TO - complete with available users*/ +/* OWNER TO - complete with available roles*/ else if (pg_strcasecmp(prev2_wd, "OWNER") == 0 && pg_strcasecmp(prev_wd, "TO") == 0) - COMPLETE_WITH_QUERY(Query_for_list_of_users); + COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* ORDER BY */ else if (pg_strcasecmp(prev3_wd, "FROM") == 0 && @@ -1489,9 +1478,10 @@ psql_completion(char *text, int start, int end) /* Complete with a variable name */ else if ((pg_strcasecmp(prev_wd, "SET") == 0 && pg_strcasecmp(prev3_wd, "UPDATE") != 0) || - pg_strcasecmp(prev_wd, "RESET") == 0 || - pg_strcasecmp(prev_wd, "SHOW") == 0) - COMPLETE_WITH_LIST(pgsql_variables); + pg_strcasecmp(prev_wd, "RESET") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_set_vars); + else if (pg_strcasecmp(prev_wd, "SHOW") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_show_vars); /* Complete "SET TRANSACTION" */ else if ((pg_strcasecmp(prev2_wd, "SET") == 0 && pg_strcasecmp(prev_wd, "TRANSACTION") == 0) @@ -1573,6 +1563,10 @@ psql_completion(char *text, int start, int end) COMPLETE_WITH_LIST(constraint_list); } + /* Complete SET ROLE */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "ROLE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */ else if (pg_strcasecmp(prev2_wd, "SET") == 0 && pg_strcasecmp(prev_wd, "SESSION") == 0) @@ -1586,7 +1580,7 @@ psql_completion(char *text, int start, int end) else if (pg_strcasecmp(prev3_wd, "SET") == 0 && pg_strcasecmp(prev2_wd, "SESSION") == 0 && pg_strcasecmp(prev_wd, "AUTHORIZATION") == 0) - COMPLETE_WITH_QUERY(Query_for_list_of_users); + COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* Complete SET <var> with "TO" */ else if (pg_strcasecmp(prev2_wd, "SET") == 0 && pg_strcasecmp(prev4_wd, "UPDATE") != 0 && @@ -1698,7 +1692,7 @@ psql_completion(char *text, int start, int end) pg_strcasecmp(prev2_wd, "ANALYZE") == 0)) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); -/* ANALZYE */ +/* ANALYZE */ /* If the previous word is ANALYZE, produce list of tables */ else if (pg_strcasecmp(prev_wd, "ANALYZE") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); @@ -1745,7 +1739,7 @@ psql_completion(char *text, int start, int end) else if (strcmp(prev_wd, "\\dT") == 0 || strcmp(prev_wd, "\\dT+") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); else if (strcmp(prev_wd, "\\du") == 0) - COMPLETE_WITH_QUERY(Query_for_list_of_users); + COMPLETE_WITH_QUERY(Query_for_list_of_roles); else if (strcmp(prev_wd, "\\dv") == 0 || strcmp(prev_wd, "\\dv+") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); else if (strcmp(prev_wd, "\\encoding") == 0)