⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tab-complete.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 4 页
字号:
	char	   *prev_wd,			   *prev2_wd,			   *prev3_wd,			   *prev4_wd;	static const char * const sql_commands[] = {		"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 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_transaction_isolation",		"default_transaction_read_only",		"dynamic_library_path",		"effective_cache_size",		"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",		"krb_server_keyfile",		"lc_messages",		"lc_monetary",		"lc_numeric",		"lc_time",		"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",		"max_connections",		"max_expr_depth",		"max_files_per_process",		"max_fsm_pages",		"max_fsm_relations",		"max_locks_per_transaction",		"password_encryption",		"port",		"random_page_cost",		"regex_flavor",		"search_path",		"shared_buffers",		"seed",		"server_encoding",		"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",		"TimeZone",		"trace_notify",		"transform_null_equals",		"unix_socket_directory",		"unix_socket_group",		"unix_socket_permissions",		"vacuum_mem",		"wal_buffers",		"wal_debug",		"wal_sync_method",		NULL	};	static const char * const backslash_commands[] = {		"\\a", "\\connect", "\\C", "\\cd", "\\copy", "\\copyright",		"\\d", "\\da", "\\dc", "\\dC", "\\dd", "\\dD", "\\df", "\\di",		"\\dl", "\\dn", "\\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", "\\T",		"\\timing", "\\unset", "\\x", "\\w", "\\z", "\\!", NULL	};	(void) end;					/* not used */#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER	rl_completion_append_character = ' ';#endif	/* Clear a few things. */	completion_charp = NULL;	completion_charpp = NULL;	completion_info_charp = NULL;	/*	 * Scan the input line before our current position for the last four	 * words. According to those we'll make some smart decisions on what	 * the user is probably intending to type. TODO: Use strtokx() to do	 * this.	 */	prev_wd = previous_word(start, 0);	prev2_wd = previous_word(start, 1);	prev3_wd = previous_word(start, 2);	prev4_wd = previous_word(start, 3);	/* If a backslash command was started, continue */	if (text[0] == '\\')		COMPLETE_WITH_LIST(backslash_commands);	/* If no previous word, suggest one of the basic sql commands */	else if (!prev_wd)		COMPLETE_WITH_LIST(sql_commands);/* CREATE or DROP but not ALTER TABLE sth DROP */	/* complete with something you can create or drop */	else if (strcasecmp(prev_wd, "CREATE") == 0 ||			 (strcasecmp(prev_wd, "DROP") == 0 &&			  strcasecmp(prev3_wd, "TABLE") != 0))		matches = completion_matches(text, create_command_generator);/* ALTER */	/*	 * complete with what you can alter (TABLE, GROUP, USER, ...) unless	 * we're in ALTER TABLE sth ALTER	 */	else if (strcasecmp(prev_wd, "ALTER") == 0 &&			 strcasecmp(prev3_wd, "TABLE") != 0)	{		static const char *const 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)	{		static const char *const list_ALTERDATABASE[] =		{"RESET", "SET", "RENAME TO", 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_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	/*	 * If we detect ALTER TABLE <name>, suggest either ADD, DROP, ALTER,	 * RENAME, or OWNER	 */	else if (strcasecmp(prev3_wd, "ALTER") == 0 &&			 strcasecmp(prev2_wd, "TABLE") == 0)	{		static const char *const list_ALTER2[] =		{"ADD", "ALTER", "DROP", "RENAME", "OWNER TO", NULL};		COMPLETE_WITH_LIST(list_ALTER2);	}	/* If we have TABLE <sth> ALTER|RENAME, provide list of columns */	else if (strcasecmp(prev3_wd, "TABLE") == 0 &&			 (strcasecmp(prev_wd, "ALTER") == 0 ||			  strcasecmp(prev_wd, "RENAME") == 0))		COMPLETE_WITH_ATTR(prev2_wd);	/* If we have TABLE <sth> DROP, provide COLUMN or CONSTRAINT */	else if (strcasecmp(prev3_wd, "TABLE") == 0 &&			 strcasecmp(prev_wd, "DROP") == 0)	{		static const char *const list_TABLEDROP[] =		{"COLUMN", "CONSTRAINT", NULL};		COMPLETE_WITH_LIST(list_TABLEDROP);	}	/* If we have TABLE <sth> DROP COLUMN, provide list of columns */	else if (strcasecmp(prev4_wd, "TABLE") == 0 &&			 strcasecmp(prev2_wd, "DROP") == 0 &&			 strcasecmp(prev_wd, "COLUMN") == 0)		COMPLETE_WITH_ATTR(prev3_wd);	/* complete ALTER GROUP <foo> with ADD or DROP */	else if (strcasecmp(prev3_wd, "ALTER") == 0 &&			 strcasecmp(prev2_wd, "GROUP") == 0)	{		static const char *const list_ALTERGROUP[] =		{"ADD", "DROP", NULL};		COMPLETE_WITH_LIST(list_ALTERGROUP);	}	/* complete ALTER GROUP <foo> ADD|DROP with USER */	else if (strcasecmp(prev4_wd, "ALTER") == 0 &&			 strcasecmp(prev3_wd, "GROUP") == 0 &&			 (strcasecmp(prev_wd, "ADD") == 0 ||			  strcasecmp(prev_wd, "DROP") == 0))		COMPLETE_WITH_CONST("USER");	/* complete {ALTER} GROUP <foo> ADD|DROP USER with a user name */	else if (strcasecmp(prev4_wd, "GROUP") == 0 &&			 (strcasecmp(prev2_wd, "ADD") == 0 ||			  strcasecmp(prev2_wd, "DROP") == 0) &&			 strcasecmp(prev_wd, "USER") == 0)		COMPLETE_WITH_QUERY(Query_for_list_of_users);/* ANALYZE */	/* If the previous word is ANALYZE, produce list of tables. */	else if (strcasecmp(prev_wd, "ANALYZE") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	/* If we have ANALYZE <table>, complete with semicolon. */	else if (strcasecmp(prev2_wd, "ANALYZE") == 0)		COMPLETE_WITH_CONST(";");/* CLUSTER */	/* If the previous word is CLUSTER, produce list of indexes. */	else if (strcasecmp(prev_wd, "CLUSTER") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);	/* If we have CLUSTER <sth>, then add "ON" */	else if (strcasecmp(prev2_wd, "CLUSTER") == 0)		COMPLETE_WITH_CONST("ON");	/*	 * If we have CLUSTER <sth> ON, then add the correct tablename as	 * well.	 */	else if (strcasecmp(prev3_wd, "CLUSTER") == 0 &&			 strcasecmp(prev_wd, "ON") == 0)	{		completion_info_charp = prev2_wd;		COMPLETE_WITH_QUERY(Query_for_table_owning_index);	}/* COMMENT */	else if (strcasecmp(prev_wd, "COMMENT") == 0)		COMPLETE_WITH_CONST("ON");	else if (strcasecmp(prev2_wd, "COMMENT") == 0 &&			 strcasecmp(prev_wd, "ON") == 0)	{		static const char *const list_COMMENT[] =		{"DATABASE", "INDEX", "RULE", "SCHEMA", "SEQUENCE", "TABLE",		 "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION", "OPERATOR",		 "TRIGGER", "CONSTRAINT", "DOMAIN", NULL};		COMPLETE_WITH_LIST(list_COMMENT);	}	else if (strcasecmp(prev4_wd, "COMMENT") == 0 &&			 strcasecmp(prev3_wd, "ON") == 0)		COMPLETE_WITH_CONST("IS");/* COPY */	/*	 * If we have COPY [BINARY] (which you'd have to type yourself), offer	 * list of tables (Also cover the analogous backslash command)	 */	else if (strcasecmp(prev_wd, "COPY") == 0 ||			 strcasecmp(prev_wd, "\\copy") == 0 ||			 (strcasecmp(prev2_wd, "COPY") == 0 &&			  strcasecmp(prev_wd, "BINARY") == 0))		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	/* If we have COPY|BINARY <sth>, complete it with "TO" or "FROM" */	else if (strcasecmp(prev2_wd, "COPY") == 0 ||			 strcasecmp(prev2_wd, "\\copy") == 0 ||			 strcasecmp(prev2_wd, "BINARY") == 0)	{		static const char *const list_FROMTO[] =		{"FROM", "TO", NULL};		COMPLETE_WITH_LIST(list_FROMTO);	}/* CREATE INDEX */	/* First off we complete CREATE UNIQUE with "INDEX" */	else if (strcasecmp(prev2_wd, "CREATE") == 0 &&			 strcasecmp(prev_wd, "UNIQUE") == 0)		COMPLETE_WITH_CONST("INDEX");	/* If we have CREATE|UNIQUE INDEX <sth>, then add "ON" */	else if (strcasecmp(prev2_wd, "INDEX") == 0 &&			 (strcasecmp(prev3_wd, "CREATE") == 0 ||			  strcasecmp(prev3_wd, "UNIQUE") == 0))		COMPLETE_WITH_CONST("ON");	/* Complete ... INDEX <name> ON with a list of tables  */	else if (strcasecmp(prev3_wd, "INDEX") == 0 &&			 strcasecmp(prev_wd, "ON") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	/*	 * Complete INDEX <name> ON <table> with a list of table columns	 * (which should really be in parens)	 */	else if (strcasecmp(prev4_wd, "INDEX") == 0 &&			 strcasecmp(prev2_wd, "ON") == 0)		COMPLETE_WITH_ATTR(prev_wd);	/* same if you put in USING */	else if (strcasecmp(prev4_wd, "ON") == 0 &&			 strcasecmp(prev2_wd, "USING") == 0)		COMPLETE_WITH_ATTR(prev3_wd);	/* Complete USING with an index method */	else if (strcasecmp(prev_wd, "USING") == 0)	{		static const char *const index_mth[] =		{"BTREE", "RTREE", "HASH", "GIST", NULL};		COMPLETE_WITH_LIST(index_mth);	}/* CREATE RULE */	/* Complete "CREATE RULE <sth>" with "AS" */	else if (strcasecmp(prev3_wd, "CREATE") == 0 &&			 strcasecmp(prev2_wd, "RULE") == 0)		COMPLETE_WITH_CONST("AS");	/* Complete "CREATE RULE <sth> AS with "ON" */	else if (strcasecmp(prev4_wd, "CREATE") == 0 &&			 strcasecmp(prev3_wd, "RULE") == 0 &&			 strcasecmp(prev_wd, "AS") == 0)		COMPLETE_WITH_CONST("ON");	/* Complete "RULE * AS ON" with SELECT|UPDATE|DELETE|INSERT */	else if (strcasecmp(prev4_wd, "RULE") == 0 &&			 strcasecmp(prev2_wd, "AS") == 0 &&			 strcasecmp(prev_wd, "ON") == 0)	{		static const char *const rule_events[] =		{"SELECT", "UPDATE", "INSERT", "DELETE", NULL};		COMPLETE_WITH_LIST(rule_events);	}	/* Complete "AS ON <sth with a 'T' :)>" with a "TO" */	else if (strcasecmp(prev3_wd, "AS") == 0 &&			 strcasecmp(prev2_wd, "ON") == 0 &&			 (toupper((unsigned char) prev_wd[4]) == 'T' ||			  toupper((unsigned char) prev_wd[5]) == 'T'))		COMPLETE_WITH_CONST("TO");	/* Complete "AS ON <sth> TO" with a table name */	else if (strcasecmp(prev4_wd, "AS") == 0 &&			 strcasecmp(prev3_wd, "ON") == 0 &&			 strcasecmp(prev_wd, "TO") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);/* CREATE TABLE */	/* Complete CREATE TEMP with "TABLE" */	else if (strcasecmp(prev2_wd, "CREATE") == 0 &&			 strcasecmp(prev_wd, "TEMP") == 0)		COMPLETE_WITH_CONST("TABLE");/* CREATE TRIGGER */	/* is on the agenda . . . *//* CREATE VIEW */	/* Complete "CREATE VIEW <name>" with "AS" */	else if (strcasecmp(prev3_wd, "CREATE") == 0 &&			 strcasecmp(prev2_wd, "VIEW") == 0)		COMPLETE_WITH_CONST("AS");	/* Complete "CREATE VIEW <sth> AS with "SELECT" */	else if (strcasecmp(prev4_wd, "CREATE") == 0 &&			 strcasecmp(prev3_wd, "VIEW") == 0 &&			 strcasecmp(prev_wd, "AS") == 0)		COMPLETE_WITH_CONST("SELECT");/* DELETE */	/*	 * Complete DELETE with FROM (only if the word before that is not "ON"	 * (cf. rules) or "BEFORE" or "AFTER" (cf. triggers) or GRANT)	 */	else if (strcasecmp(prev_wd, "DELETE") == 0 &&			 !(strcasecmp(prev2_wd, "ON") == 0 ||			   strcasecmp(prev2_wd, "GRANT") == 0 ||			   strcasecmp(prev2_wd, "BEFORE") == 0 ||			   strcasecmp(prev2_wd, "AFTER") == 0))		COMPLETE_WITH_CONST("FROM");	/* Complete DELETE FROM with a list of tables */	else if (strcasecmp(prev2_wd, "DELETE") == 0 &&			 strcasecmp(prev_wd, "FROM") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	/* Complete DELETE FROM <table> with "WHERE" (perhaps a safe idea?) */	else if (strcasecmp(prev3_wd, "DELETE") == 0 &&			 strcasecmp(prev2_wd, "FROM") == 0)		COMPLETE_WITH_CONST("WHERE");/* EXPLAIN */	/*	 * Complete EXPLAIN [VERBOSE] (which you'd have to type yourself) with	 * the list of SQL commands	 */	else if (strcasecmp(prev_wd, "EXPLAIN") == 0 ||			 (strcasecmp(prev2_wd, "EXPLAIN") == 0 &&			  strcasecmp(prev_wd, "VERBOSE") == 0))		COMPLETE_WITH_LIST(sql_commands);/* FETCH && MOVE */	/* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */	else if (strcasecmp(prev_wd, "FETCH") == 0 ||			 strcasecmp(prev_wd, "MOVE") == 0)	{		static const char * const list_FETCH1[] =		{"FORWARD", "BACKWARD", "RELATIVE", NULL};		COMPLETE_WITH_LIST(list_FETCH1);	}	/* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */	else if (strcasecmp(prev2_wd, "FETCH") == 0 ||			 strcasecmp(prev2_wd, "MOVE") == 0)	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -