33 *
44 * Copyright 2000-2002 by PostgreSQL Global Development Group
55 *
6- * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.67 2002/11/1500:47:22 momjian Exp $
6+ * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.68 2002/11/1503:07:52 momjian Exp $
77 */
88
99/*----------------------------------------------------------------------
@@ -141,9 +141,13 @@ typedef struct
141141
142142pgsql_thing_t words_after_create []= {
143143{"AGGREGATE" ,"SELECT DISTINCT proname FROM pg_catalog.pg_proc WHERE proisagg AND substr(proname,1,%d)='%s'" },
144+ {"CAST" ,NULL },/* Casts have complex structures for namees, so skip it */
145+ {"CONVERSION" ,"SELECT conname FROM pg_catalog.pg_conversion WHERE substr(conname,1,%d)='%s'" },
144146{"DATABASE" ,Query_for_list_of_databases },
147+ {"DOMAIN" ,"SELECT typname FROM pg_catalog.pg_type WHERE typtype = 'd' AND substr(typname,1,%d)='%s'" },
145148{"FUNCTION" ,"SELECT DISTINCT proname FROM pg_catalog.pg_proc WHERE substr(proname,1,%d)='%s'" },
146149{"GROUP" ,"SELECT groname FROM pg_catalog.pg_group WHERE substr(groname,1,%d)='%s'" },
150+ {"LANGUAGE" ,"SELECT lanname FROM pg_catalog.pg_language WHERE substr(lanname,1,%d)='%s'" },
147151{"INDEX" ,Query_for_list_of_indexes },
148152{"OPERATOR" ,NULL },/* Querying for this is probably not such
149153 * a good idea. */
@@ -196,11 +200,11 @@ psql_completion(char *text, int start, int end)
196200* prev4_wd ;
197201
198202static char * sql_commands []= {
199- "ABORT" ,"ALTER" ,"ANALYZE" ,"BEGIN" ,"CLOSE " ,"CLUSTER " ,"COMMENT " ,"COMMIT" , "COPY " ,
200- "CREATE " ,"DECLARE " ,"DELETE " ,"DROP " ,"EXPLAIN " ,"FETCH " ,"GRANT " ,
201- "INSERT " ,"LISTEN " ,"LOAD " ,"LOCK " ,"MOVE " ,"NOTIFY " ,"REINDEX " ,"RESET " ,
202- "REVOKE " ,"ROLLBACK " ,"SELECT " ,"SET " ,"SHOW " ,"TRUNCATE " ,"UNLISTEN " ,"UPDATE " ,
203- "VACUUM" ,NULL
203+ "ABORT" ,"ALTER" ,"ANALYZE" ,"BEGIN" ,"CHECKPOINT " ,"CLOSE " ,"CLUSTER " ,"COMMENT " ,
204+ "COMMIT " ,"COPY " ,"CREATE " ,"DEALLOCATE " ,"DECLARE " ,"DELETE " ,"DROP" , "EXECUTE " ,
205+ "EXPLAIN " ,"FETCH " ,"GRANT " ,"INSERT " ,"LISTEN " ,"LOAD " ,"LOCK " ,"MOVE" , "NOTIFY " ,
206+ "PREPARE " ,"REINDEX " ,"RESET " ,"REVOKE " ,"ROLLBACK " ,"SELECT " ,"SET " ,"SHOW " ,
207+ "TRUNCATE" , "UNLISTEN" , "UPDATE" , " VACUUM" ,NULL
204208};
205209
206210static char * pgsql_variables []= {
@@ -220,70 +224,111 @@ psql_completion(char *text, int start, int end)
220224 * the rest should match USERSET entries in
221225 * backend/utils/misc/guc.c
222226 */
223- "enable_seqscan" ,
224- "enable_indexscan" ,
225- "enable_tidscan" ,
226- "enable_sort" ,
227- "enable_nestloop" ,
228- "enable_mergejoin" ,
229- "enable_hashjoin" ,
230- "geqo" ,
231- "fsync" ,
232- "log_min_messages" ,
227+ "australian_timezones" ,
228+ "authentication_timeout" ,
229+ "autocommit" ,
230+ "checkpoint_segments" ,
231+ "checkpoint_timeout" ,
233232"client_min_messages" ,
234- "debug_assertions" ,
235- "log_statement" ,
236- "log_duration" ,
233+ "commit_delay" ,
234+ "commit_siblings" ,
235+ "cpu_index_tuple_cost" ,
236+ "cpu_operator_cost" ,
237+ "cpu_tuple_cost" ,
238+ "db_user_namespace" ,
239+ "deadlock_timeout" ,
240+ "debug_pretty_print" ,
237241"debug_print_parse" ,
238- "debug_print_rewritten" ,
239242"debug_print_plan" ,
240- "debug_pretty_print" ,
241- "log_parser_stats" ,
242- "log_planner_stats" ,
243- "log_executor_stats" ,
244- "log_statement_stats" ,
245- "trace_notify" ,
246- "explain_pretty_print" ,
247- "sql_inheritance" ,
248- "australian_timezones" ,
249- "password_encryption" ,
250- "transform_null_equals" ,
251- "autocommit" ,
252-
243+ "debug_print_rewritten" ,
253244"default_statistics_target" ,
254- "geqo_threshold" ,
255- "geqo_pool_size" ,
245+ "default_transaction_isolation" ,
246+ "dynamic_library_path" ,
247+ "effective_cache_size" ,
248+ "enable_hashjoin" ,
249+ "enable_indexscan" ,
250+ "enable_mergejoin" ,
251+ "enable_nestloop" ,
252+ "enable_seqscan" ,
253+ "enable_sort" ,
254+ "enable_tidscan" ,
255+ "explain_pretty_print" ,
256+ "extra_float_digits" ,
257+ "fixbtree" ,
258+ "fsync" ,
259+ "geqo" ,
256260"geqo_effort" ,
257261"geqo_generations" ,
262+ "geqo_pool_size" ,
258263"geqo_random_seed" ,
259- "sort_mem" ,
260- "vacuum_mem" ,
264+ "geqo_selection_bias" ,
265+ "geqo_threshold" ,
266+ "log_hostname" ,
267+ "krb_server_keyfile" ,
268+ "lc_messages" ,
269+ "lc_monetary" ,
270+ "lc_numeric" ,
271+ "lc_timeC" ,
272+ "log_connections" ,
273+ "log_duration" ,
274+ "log_min_error_statement" ,
275+ "log_pid" ,
276+ "log_statement" ,
277+ "log_timestamp" ,
278+ "max_connections" ,
261279"max_expr_depth" ,
262- "commit_delay" ,
263- "commit_siblings" ,
264- "extra_float_digits" ,
265-
266- "effective_cache_size" ,
280+ "max_files_per_process" ,
281+ "max_fsm_pages" ,
282+ "max_fsm_relations" ,
283+ "max_locks_per_transaction" ,
284+ "password_encryption" ,
285+ "port" ,
286+ "pre_auth_delay" ,
267287"random_page_cost" ,
268- "cpu_tuple_cost" ,
269- "cpu_index_tuple_cost" ,
270- "cpu_operator_cost" ,
271- "geqo_selection_bias" ,
272-
273- "default_transaction_isolation" ,
274288"search_path" ,
289+ "log_min_messages" ,
290+ "shared_buffers" ,
291+ "log_executor_stats" ,
292+ "log_parser_stats" ,
293+ "log_planner_stats" ,
294+ "log_source_port" ,
295+ "log_statement_stats" ,
296+ "silent_mode" ,
297+ "sort_mem" ,
298+ "sql_inheritance" ,
299+ "ssl" ,
275300"statement_timeout" ,
276- "log_min_error_statement" ,
301+ "stats_block_level" ,
302+ "stats_command_string" ,
303+ "stats_reset_on_server_start" ,
304+ "stats_row_level" ,
305+ "stats_start_collector" ,
306+ "superuser_reserved_connections" ,
307+ "syslog" ,
308+ "syslog_facility" ,
309+ "syslog_ident" ,
310+ "tcpip_socket" ,
311+ "trace_notify" ,
312+ "transform_null_equals" ,
313+ "unix_socket_directory" ,
314+ "unix_socket_group" ,
315+ "unix_socket_permissions" ,
316+ "vacuum_mem" ,
317+ "virtual_hostt" ,
318+ "wal_buffers" ,
319+ "wal_debug" ,
320+ "wal_sync_method" ,
277321NULL
278322};
279323
280324static char * backslash_commands []= {
281- "\\connect" ,"\\copy" ,"\\d" ,"\\da" ,"\\dd" ,"\\df" ,"\\di" ,
282- "\\dl" ,"\\do" ,"\\dp" ,"\\ds" ,"\\dS" ,"\\dt" ,"\\dT" ,"\\dv" ,
283- "\\e" ,"\\echo" ,
284- "\\encoding" ,"\\g" ,"\\h" ,"\\i" ,"\\l" ,
325+ "\\a" ,"\\connect" ,"\\C" ,"\\cd" ,"\\copy" ,"\\copyright" ,
326+ "\\d" ,"\\da" ,"\\dd" ,"\\dD" ,"\\df" ,"\\di" ,"\\dl" ,"\\do" ,
327+ "\\dp" ,"\\ds" ,"\\dS" ,"\\dt" ,"\\dT" ,"\\dv" ,"\\du" ,
328+ "\\e" ,"\\echo" ,"\\encoding" ,
329+ "\\f" ,"\\g" ,"\\h" ,"\\help" ,"\\H" ,"\\i" ,"\\l" ,
285330"\\lo_import" ,"\\lo_export" ,"\\lo_list" ,"\\lo_unlink" ,
286- "\\o" ,"\\p" ,"\\pset" ,"\\q" ,"\\qecho" ,"\\r" ,"\\set" ,"\\t" ,
331+ "\\o" ,"\\p" ,"\\pset" ,"\\q" ,"\\qecho" ,"\\r" ,"\\set" ,"\\t" ,"\\T" ,
287332"\\timing" ,"\\unset" ,"\\x" ,"\\w" ,"\\z" ,"\\!" ,NULL
288333};
289334
@@ -323,14 +368,32 @@ psql_completion(char *text, int start, int end)
323368matches = completion_matches (text ,create_command_generator );
324369
325370/* ALTER */
326- /* complete with what you can alter (TABLE, GROUP, USER) */
371+ /* complete with what you can alter (TABLE, GROUP, USER, ... ) */
327372else if (strcasecmp (prev_wd ,"ALTER" )== 0 )
328373{
329- char * list_ALTER []= {"GROUP" ,"SCHEMA" ,"TABLE" ,"USER" ,NULL };
374+ char * list_ALTER []= {"DATABASE" , " GROUP" ,"SCHEMA" ,"TABLE" , "TRIGGER " ,"USER" ,NULL };
330375
331376COMPLETE_WITH_LIST (list_ALTER );
332377}
333378
379+ /* ALTER DATABASE <name> */
380+ else if (strcasecmp (prev3_wd ,"ALTER" )== 0 && strcasecmp (prev2_wd ,"DATABASE" )== 0 )
381+ {
382+ char * list_ALTERDATABASE []= {"RESET" ,"SET" ,NULL };
383+
384+ COMPLETE_WITH_LIST (list_ALTERDATABASE );
385+ }
386+ /* ALTER TRIGGER <name>, add ON */
387+ else if (strcasecmp (prev3_wd ,"ALTER" )== 0 && strcasecmp (prev2_wd ,"TRIGGER" )== 0 )
388+ COMPLETE_WITH_CONST ("ON" );
389+
390+ /*
391+ * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
392+ */
393+ else if (strcasecmp (prev4_wd ,"ALTER" )== 0 && strcasecmp (prev3_wd ,"TRIGGER" )== 0
394+ && strcasecmp (prev_wd ,"ON" )== 0 )
395+ COMPLETE_WITH_QUERY (Query_for_list_of_tables );
396+
334397/*
335398 * If we detect ALTER TABLE <name>, suggest either ADD, ALTER, or
336399 * RENAME
@@ -970,7 +1033,9 @@ static char *
9701033complete_from_list (char * text ,int state )
9711034{
9721035static int string_length ,
973- list_index ;
1036+ list_index ,
1037+ matches ;
1038+ static bool casesensitive ;
9741039char * item ;
9751040
9761041/* need to have a list */
@@ -983,11 +1048,35 @@ complete_from_list(char *text, int state)
9831048{
9841049list_index = 0 ;
9851050string_length = strlen (text );
1051+ casesensitive = true;
1052+ matches = 0 ;
9861053}
9871054
9881055while ((item = completion_charpp [list_index ++ ]))
989- if (strncasecmp (text ,item ,string_length )== 0 )
1056+ {
1057+ /* First pass is case sensitive */
1058+ if (casesensitive && strncmp (text ,item ,string_length )== 0 )
1059+ {
1060+ matches ++ ;
1061+ return xstrdup (item );
1062+ }
1063+
1064+ /* Second pass is case insensitive, don't bother counting matches */
1065+ if (!casesensitive && strncasecmp (text ,item ,string_length )== 0 )
9901066return xstrdup (item );
1067+ }
1068+
1069+ /*
1070+ * No matches found. If we're not case insensitive already, lets switch
1071+ * to being case insensitive and try again
1072+ */
1073+ if (casesensitive && matches == 0 )
1074+ {
1075+ casesensitive = false;
1076+ list_index = 0 ;
1077+ state ++ ;
1078+ return (complete_from_list (text ,state ));
1079+ }
9911080
9921081/* If no more matches, return null. */
9931082return NULL ;