Clean up psql:
Add simple ALTER DATABASE, ALTER TRIGGER, CHECK POINT, CREATE CONVERSION, CREATE DOMAIN, CREATE LANGUAGE, DEALLOCATE, DROP CONVERSION, DROP DOMAIN, DROP LANGUAGE, EXECUTE, PREPARE Complete CAST in CREATE CAST and DROP CAST but doesn't suggest what should follow. Add many more SET / SHOW variables to the list. Taken from SHOW ALL output. Complete a case sensitive search to allow \dD, \dd, \dS, \ds, \h, \H to complete properly. But there are no matches, then try a case insensitive search to allow case conversion. Add all missing help options. \Q<tab> -> \q \dD<tab> -> \dD \dd<tab> -> \dd \D<tab><tab><tab> -> \d (with listing of \d? commands) sel<tab> -> SELECT Rod Taylor
This commit is contained in:
parent
728fa75edc
commit
5b7eb4dd45
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright 2000-2002 by PostgreSQL Global Development Group
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.67 2002/11/15 00:47:22 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.68 2002/11/15 03:07:52 momjian Exp $
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
@ -141,9 +141,13 @@ typedef struct
|
||||
|
||||
pgsql_thing_t words_after_create[] = {
|
||||
{"AGGREGATE", "SELECT DISTINCT proname FROM pg_catalog.pg_proc WHERE proisagg AND substr(proname,1,%d)='%s'"},
|
||||
{"CAST", NULL}, /* Casts have complex structures for namees, so skip it */
|
||||
{"CONVERSION", "SELECT conname FROM pg_catalog.pg_conversion WHERE substr(conname,1,%d)='%s'"},
|
||||
{"DATABASE", Query_for_list_of_databases},
|
||||
{"DOMAIN", "SELECT typname FROM pg_catalog.pg_type WHERE typtype = 'd' AND substr(typname,1,%d)='%s'"},
|
||||
{"FUNCTION", "SELECT DISTINCT proname FROM pg_catalog.pg_proc WHERE substr(proname,1,%d)='%s'"},
|
||||
{"GROUP", "SELECT groname FROM pg_catalog.pg_group WHERE substr(groname,1,%d)='%s'"},
|
||||
{"LANGUAGE", "SELECT lanname FROM pg_catalog.pg_language WHERE substr(lanname,1,%d)='%s'"},
|
||||
{"INDEX", Query_for_list_of_indexes},
|
||||
{"OPERATOR", NULL}, /* Querying for this is probably not such
|
||||
* a good idea. */
|
||||
@ -196,11 +200,11 @@ psql_completion(char *text, int start, int end)
|
||||
*prev4_wd;
|
||||
|
||||
static char *sql_commands[] = {
|
||||
"ABORT", "ALTER", "ANALYZE", "BEGIN", "CLOSE", "CLUSTER", "COMMENT", "COMMIT", "COPY",
|
||||
"CREATE", "DECLARE", "DELETE", "DROP", "EXPLAIN", "FETCH", "GRANT",
|
||||
"INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "REINDEX", "RESET",
|
||||
"REVOKE", "ROLLBACK", "SELECT", "SET", "SHOW", "TRUNCATE", "UNLISTEN", "UPDATE",
|
||||
"VACUUM", NULL
|
||||
"ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER", "COMMENT",
|
||||
"COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE", "DROP", "EXECUTE",
|
||||
"EXPLAIN", "FETCH", "GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY",
|
||||
"PREPARE", "REINDEX", "RESET", "REVOKE", "ROLLBACK", "SELECT", "SET", "SHOW",
|
||||
"TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", NULL
|
||||
};
|
||||
|
||||
static char *pgsql_variables[] = {
|
||||
@ -220,70 +224,111 @@ psql_completion(char *text, int start, int end)
|
||||
* the rest should match USERSET entries in
|
||||
* backend/utils/misc/guc.c
|
||||
*/
|
||||
"enable_seqscan",
|
||||
"enable_indexscan",
|
||||
"enable_tidscan",
|
||||
"enable_sort",
|
||||
"enable_nestloop",
|
||||
"enable_mergejoin",
|
||||
"enable_hashjoin",
|
||||
"geqo",
|
||||
"fsync",
|
||||
"log_min_messages",
|
||||
"client_min_messages",
|
||||
"debug_assertions",
|
||||
"log_statement",
|
||||
"log_duration",
|
||||
"debug_print_parse",
|
||||
"debug_print_rewritten",
|
||||
"debug_print_plan",
|
||||
"debug_pretty_print",
|
||||
"log_parser_stats",
|
||||
"log_planner_stats",
|
||||
"log_executor_stats",
|
||||
"log_statement_stats",
|
||||
"trace_notify",
|
||||
"explain_pretty_print",
|
||||
"sql_inheritance",
|
||||
"australian_timezones",
|
||||
"password_encryption",
|
||||
"transform_null_equals",
|
||||
"authentication_timeout",
|
||||
"autocommit",
|
||||
|
||||
"default_statistics_target",
|
||||
"geqo_threshold",
|
||||
"geqo_pool_size",
|
||||
"geqo_effort",
|
||||
"geqo_generations",
|
||||
"geqo_random_seed",
|
||||
"sort_mem",
|
||||
"vacuum_mem",
|
||||
"max_expr_depth",
|
||||
"checkpoint_segments",
|
||||
"checkpoint_timeout",
|
||||
"client_min_messages",
|
||||
"commit_delay",
|
||||
"commit_siblings",
|
||||
"extra_float_digits",
|
||||
|
||||
"effective_cache_size",
|
||||
"random_page_cost",
|
||||
"cpu_tuple_cost",
|
||||
"cpu_index_tuple_cost",
|
||||
"cpu_operator_cost",
|
||||
"geqo_selection_bias",
|
||||
|
||||
"cpu_tuple_cost",
|
||||
"db_user_namespace",
|
||||
"deadlock_timeout",
|
||||
"debug_pretty_print",
|
||||
"debug_print_parse",
|
||||
"debug_print_plan",
|
||||
"debug_print_rewritten",
|
||||
"default_statistics_target",
|
||||
"default_transaction_isolation",
|
||||
"search_path",
|
||||
"statement_timeout",
|
||||
"dynamic_library_path",
|
||||
"effective_cache_size",
|
||||
"enable_hashjoin",
|
||||
"enable_indexscan",
|
||||
"enable_mergejoin",
|
||||
"enable_nestloop",
|
||||
"enable_seqscan",
|
||||
"enable_sort",
|
||||
"enable_tidscan",
|
||||
"explain_pretty_print",
|
||||
"extra_float_digits",
|
||||
"fixbtree",
|
||||
"fsync",
|
||||
"geqo",
|
||||
"geqo_effort",
|
||||
"geqo_generations",
|
||||
"geqo_pool_size",
|
||||
"geqo_random_seed",
|
||||
"geqo_selection_bias",
|
||||
"geqo_threshold",
|
||||
"log_hostname",
|
||||
"krb_server_keyfile",
|
||||
"lc_messages",
|
||||
"lc_monetary",
|
||||
"lc_numeric",
|
||||
"lc_timeC",
|
||||
"log_connections",
|
||||
"log_duration",
|
||||
"log_min_error_statement",
|
||||
"log_pid",
|
||||
"log_statement",
|
||||
"log_timestamp",
|
||||
"max_connections",
|
||||
"max_expr_depth",
|
||||
"max_files_per_process",
|
||||
"max_fsm_pages",
|
||||
"max_fsm_relations",
|
||||
"max_locks_per_transaction",
|
||||
"password_encryption",
|
||||
"port",
|
||||
"pre_auth_delay",
|
||||
"random_page_cost",
|
||||
"search_path",
|
||||
"log_min_messages",
|
||||
"shared_buffers",
|
||||
"log_executor_stats",
|
||||
"log_parser_stats",
|
||||
"log_planner_stats",
|
||||
"log_source_port",
|
||||
"log_statement_stats",
|
||||
"silent_mode",
|
||||
"sort_mem",
|
||||
"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",
|
||||
"syslog_facility",
|
||||
"syslog_ident",
|
||||
"tcpip_socket",
|
||||
"trace_notify",
|
||||
"transform_null_equals",
|
||||
"unix_socket_directory",
|
||||
"unix_socket_group",
|
||||
"unix_socket_permissions",
|
||||
"vacuum_mem",
|
||||
"virtual_hostt",
|
||||
"wal_buffers",
|
||||
"wal_debug",
|
||||
"wal_sync_method",
|
||||
NULL
|
||||
};
|
||||
|
||||
static char *backslash_commands[] = {
|
||||
"\\connect", "\\copy", "\\d", "\\da", "\\dd", "\\df", "\\di",
|
||||
"\\dl", "\\do", "\\dp", "\\ds", "\\dS", "\\dt", "\\dT", "\\dv",
|
||||
"\\e", "\\echo",
|
||||
"\\encoding", "\\g", "\\h", "\\i", "\\l",
|
||||
"\\a", "\\connect", "\\C", "\\cd", "\\copy", "\\copyright",
|
||||
"\\d", "\\da", "\\dd", "\\dD", "\\df", "\\di", "\\dl", "\\do",
|
||||
"\\dp", "\\ds", "\\dS", "\\dt", "\\dT", "\\dv","\\du",
|
||||
"\\e", "\\echo", "\\encoding",
|
||||
"\\f", "\\g", "\\h", "\\help", "\\H", "\\i", "\\l",
|
||||
"\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
|
||||
"\\o", "\\p", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t",
|
||||
"\\o", "\\p", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\T",
|
||||
"\\timing", "\\unset", "\\x", "\\w", "\\z", "\\!", NULL
|
||||
};
|
||||
|
||||
@ -323,14 +368,32 @@ psql_completion(char *text, int start, int end)
|
||||
matches = completion_matches(text, create_command_generator);
|
||||
|
||||
/* ALTER */
|
||||
/* complete with what you can alter (TABLE, GROUP, USER) */
|
||||
/* complete with what you can alter (TABLE, GROUP, USER, ...) */
|
||||
else if (strcasecmp(prev_wd, "ALTER") == 0)
|
||||
{
|
||||
char *list_ALTER[] = {"GROUP", "SCHEMA", "TABLE", "USER", NULL};
|
||||
char *list_ALTER[] = {"DATABASE", "GROUP", "SCHEMA", "TABLE", "TRIGGER", "USER", NULL};
|
||||
|
||||
COMPLETE_WITH_LIST(list_ALTER);
|
||||
}
|
||||
|
||||
/* ALTER DATABASE <name> */
|
||||
else if (strcasecmp(prev3_wd, "ALTER") == 0 && strcasecmp(prev2_wd, "DATABASE") == 0)
|
||||
{
|
||||
char *list_ALTERDATABASE[] = {"RESET", "SET", NULL};
|
||||
|
||||
COMPLETE_WITH_LIST(list_ALTERDATABASE);
|
||||
}
|
||||
/* ALTER TRIGGER <name>, add ON */
|
||||
else if (strcasecmp(prev3_wd, "ALTER") == 0 && strcasecmp(prev2_wd, "TRIGGER") == 0)
|
||||
COMPLETE_WITH_CONST("ON");
|
||||
|
||||
/*
|
||||
* If we have ALTER TRIGGER <sth> ON, then add the correct tablename
|
||||
*/
|
||||
else if (strcasecmp(prev4_wd, "ALTER") == 0 && strcasecmp(prev3_wd, "TRIGGER") == 0
|
||||
&& strcasecmp(prev_wd, "ON") == 0)
|
||||
COMPLETE_WITH_QUERY(Query_for_list_of_tables);
|
||||
|
||||
/*
|
||||
* If we detect ALTER TABLE <name>, suggest either ADD, ALTER, or
|
||||
* RENAME
|
||||
@ -970,7 +1033,9 @@ static char *
|
||||
complete_from_list(char *text, int state)
|
||||
{
|
||||
static int string_length,
|
||||
list_index;
|
||||
list_index,
|
||||
matches;
|
||||
static bool casesensitive;
|
||||
char *item;
|
||||
|
||||
/* need to have a list */
|
||||
@ -983,11 +1048,35 @@ complete_from_list(char *text, int state)
|
||||
{
|
||||
list_index = 0;
|
||||
string_length = strlen(text);
|
||||
casesensitive = true;
|
||||
matches = 0;
|
||||
}
|
||||
|
||||
while ((item = completion_charpp[list_index++]))
|
||||
if (strncasecmp(text, item, string_length) == 0)
|
||||
{
|
||||
/* First pass is case sensitive */
|
||||
if (casesensitive && strncmp(text, item, string_length) == 0)
|
||||
{
|
||||
matches++;
|
||||
return xstrdup(item);
|
||||
}
|
||||
|
||||
/* Second pass is case insensitive, don't bother counting matches */
|
||||
if (!casesensitive && strncasecmp(text, item, string_length) == 0)
|
||||
return xstrdup(item);
|
||||
}
|
||||
|
||||
/*
|
||||
* No matches found. If we're not case insensitive already, lets switch
|
||||
* to being case insensitive and try again
|
||||
*/
|
||||
if (casesensitive && matches == 0)
|
||||
{
|
||||
casesensitive = false;
|
||||
list_index = 0;
|
||||
state++;
|
||||
return (complete_from_list(text, state));
|
||||
}
|
||||
|
||||
/* If no more matches, return null. */
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user