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

📄 tab-complete.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 4 页
字号:
		static const char * const list_FETCH2[] =		{"ALL", "NEXT", "PRIOR", NULL};		COMPLETE_WITH_LIST(list_FETCH2);	}	/*	 * Complete FETCH <sth1> <sth2> with "FROM" or "TO". (Is there a	 * difference? If not, remove one.)	 */	else if (strcasecmp(prev3_wd, "FETCH") == 0 ||			 strcasecmp(prev3_wd, "MOVE") == 0)	{		static const char * const list_FROMTO[] =		{"FROM", "TO", NULL};		COMPLETE_WITH_LIST(list_FROMTO);	}/* GRANT && REVOKE*/	/* Complete GRANT/REVOKE with a list of privileges */	else if (strcasecmp(prev_wd, "GRANT") == 0 ||			 strcasecmp(prev_wd, "REVOKE") == 0)	{		static const char * const list_privileg[] =		{"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES",		 "TRIGGER", "CREATE", "TEMPORARY", "EXECUTE", "USAGE", "ALL", NULL};		COMPLETE_WITH_LIST(list_privileg);	}	/* Complete GRANT/REVOKE <sth> with "ON" */	else if (strcasecmp(prev2_wd, "GRANT") == 0 ||			 strcasecmp(prev2_wd, "REVOKE") == 0)		COMPLETE_WITH_CONST("ON");	/*	 * Complete GRANT/REVOKE <sth> ON with a list of tables, views,	 * sequences, and indexes	 *	 * keywords DATABASE, FUNCTION, LANGUAGE, SCHEMA added to query result	 * via UNION; seems to work intuitively	 *	 * Note: GRANT/REVOKE can get quite complex; tab-completion as	 * implemented here will only work if the privilege list contains	 * exactly one privilege	 */	else if ((strcasecmp(prev3_wd, "GRANT") == 0 ||			  strcasecmp(prev3_wd, "REVOKE") == 0) &&			 strcasecmp(prev_wd, "ON") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv,								   " UNION SELECT 'DATABASE'"								   " UNION SELECT 'FUNCTION'"								   " UNION SELECT 'LANGUAGE'"								   " UNION SELECT 'SCHEMA'");	/* Complete "GRANT/REVOKE * ON * " with "TO" */	else if ((strcasecmp(prev4_wd, "GRANT") == 0 ||			  strcasecmp(prev4_wd, "REVOKE") == 0) &&			 strcasecmp(prev2_wd, "ON") == 0)	{		if (strcasecmp(prev_wd, "DATABASE") == 0)			COMPLETE_WITH_QUERY(Query_for_list_of_databases);		else if (strcasecmp(prev_wd, "FUNCTION") == 0)			COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);		else if (strcasecmp(prev_wd, "LANGUAGE") == 0)			COMPLETE_WITH_QUERY(Query_for_list_of_languages);		else if (strcasecmp(prev_wd, "SCHEMA") == 0)			COMPLETE_WITH_QUERY(Query_for_list_of_schemas);		else			COMPLETE_WITH_CONST("TO");	}	/*	 * TODO: to complete with user name we need prev5_wd -- wait for a	 * more general solution there same for GRANT <sth> ON { DATABASE |	 * FUNCTION | LANGUAGE | SCHEMA } xxx TO	 *//* INSERT */	/* Complete INSERT with "INTO" */	else if (strcasecmp(prev_wd, "INSERT") == 0)		COMPLETE_WITH_CONST("INTO");	/* Complete INSERT INTO with table names */	else if (strcasecmp(prev2_wd, "INSERT") == 0 &&			 strcasecmp(prev_wd, "INTO") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	/* Complete "INSERT INTO <table> (" with attribute names */	else if (rl_line_buffer[start - 1] == '(' &&			 strcasecmp(prev3_wd, "INSERT") == 0 &&			 strcasecmp(prev2_wd, "INTO") == 0)		COMPLETE_WITH_ATTR(prev_wd);	/*	 * Complete INSERT INTO <table> with "VALUES" or "SELECT" or "DEFAULT	 * VALUES"	 */	else if (strcasecmp(prev3_wd, "INSERT") == 0 &&			 strcasecmp(prev2_wd, "INTO") == 0)	{		static const char * const list_INSERT[] =		{"DEFAULT VALUES", "SELECT", "VALUES", NULL};		COMPLETE_WITH_LIST(list_INSERT);	}	/* Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" */	else if (strcasecmp(prev4_wd, "INSERT") == 0 &&			 strcasecmp(prev3_wd, "INTO") == 0 &&			 prev_wd[strlen(prev_wd) - 1] == ')')	{		static const char * const list_INSERT[] =		{"SELECT", "VALUES", NULL};		COMPLETE_WITH_LIST(list_INSERT);	}	/* Insert an open parenthesis after "VALUES" */	else if (strcasecmp(prev_wd, "VALUES") == 0 &&			 strcasecmp(prev2_wd, "DEFAULT") != 0)		COMPLETE_WITH_CONST("(");/* LOCK */	/* Complete LOCK [TABLE] with a list of tables */	else if (strcasecmp(prev_wd, "LOCK") == 0 ||			 (strcasecmp(prev_wd, "TABLE") == 0 &&			  strcasecmp(prev2_wd, "LOCK") == 0))		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	/* For the following, handle the case of a single table only for now */	/* Complete LOCK [TABLE] <table> with "IN" */	else if ((strcasecmp(prev2_wd, "LOCK") == 0 &&			  strcasecmp(prev_wd, "TABLE")) ||			 (strcasecmp(prev2_wd, "TABLE") == 0 &&			  strcasecmp(prev3_wd, "LOCK") == 0))		COMPLETE_WITH_CONST("IN");	/* Complete LOCK [TABLE] <table> IN with a lock mode */	else if (strcasecmp(prev_wd, "IN") == 0 &&			 (strcasecmp(prev3_wd, "LOCK") == 0 ||			  (strcasecmp(prev3_wd, "TABLE") == 0 &&			   strcasecmp(prev4_wd, "LOCK") == 0)))	{		static const char * const lock_modes[] =		{"ACCESS SHARE MODE",		 "ROW SHARE MODE", "ROW EXCLUSIVE MODE",		 "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",		 "SHARE ROW EXCLUSIVE MODE",		 "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE", NULL};		COMPLETE_WITH_LIST(lock_modes);	}/* NOTIFY */	else if (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'");/* REINDEX */	else if (strcasecmp(prev_wd, "REINDEX") == 0)	{		static const char * const list_REINDEX[] =		{"TABLE", "DATABASE", "INDEX", NULL};		COMPLETE_WITH_LIST(list_REINDEX);	}	else if (strcasecmp(prev2_wd, "REINDEX") == 0)	{		if (strcasecmp(prev_wd, "TABLE") == 0)			COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);		else if (strcasecmp(prev_wd, "DATABASE") == 0)			COMPLETE_WITH_QUERY(Query_for_list_of_databases);		else if (strcasecmp(prev_wd, "INDEX") == 0)			COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);	}/* SELECT */	/* naah . . . *//* SET, RESET, SHOW */	/* Complete with a variable name */	else if ((strcasecmp(prev_wd, "SET") == 0 &&			  strcasecmp(prev3_wd, "UPDATE") != 0) ||			 strcasecmp(prev_wd, "RESET") == 0 ||			 strcasecmp(prev_wd, "SHOW") == 0)		COMPLETE_WITH_LIST(pgsql_variables);	/* Complete "SET TRANSACTION" */	else if ((strcasecmp(prev2_wd, "SET") == 0 &&			  strcasecmp(prev_wd, "TRANSACTION") == 0) ||			 (strcasecmp(prev4_wd, "SESSION") == 0 &&			  strcasecmp(prev3_wd, "CHARACTERISTICS") == 0 &&			  strcasecmp(prev2_wd, "AS") == 0 &&			  strcasecmp(prev_wd, "TRANSACTION") == 0))	{		static const char * const my_list[] =		{"ISOLATION", "READ", NULL};		COMPLETE_WITH_LIST(my_list);	}	else if (strcasecmp(prev3_wd, "SET") == 0 &&			 strcasecmp(prev2_wd, "TRANSACTION") == 0 &&			 strcasecmp(prev_wd, "ISOLATION") == 0)		COMPLETE_WITH_CONST("LEVEL");	else if ((strcasecmp(prev4_wd, "SET") == 0 ||			  strcasecmp(prev4_wd, "AS") == 0) &&			 strcasecmp(prev3_wd, "TRANSACTION") == 0 &&			 strcasecmp(prev2_wd, "ISOLATION") == 0 &&			 strcasecmp(prev_wd, "LEVEL") == 0)	{		static const char * const my_list[] =		{"READ", "SERIALIZABLE", NULL};		COMPLETE_WITH_LIST(my_list);	}	else if (strcasecmp(prev4_wd, "TRANSACTION") == 0 &&			 strcasecmp(prev3_wd, "ISOLATION") == 0 &&			 strcasecmp(prev2_wd, "LEVEL") == 0 &&			 strcasecmp(prev_wd, "READ") == 0)		COMPLETE_WITH_CONST("COMMITTED");	else if ((strcasecmp(prev3_wd, "SET") == 0 ||			  strcasecmp(prev3_wd, "AS") == 0) &&			 strcasecmp(prev2_wd, "TRANSACTION") == 0 &&			 strcasecmp(prev_wd, "READ") == 0)	{		static const char * const my_list[] =		{"ONLY", "WRITE", NULL};		COMPLETE_WITH_LIST(my_list);	}	/* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */	else if (strcasecmp(prev3_wd, "SET") == 0 &&			 strcasecmp(prev2_wd, "CONSTRAINTS") == 0)	{		static const char * const constraint_list[] =		{"DEFERRED", "IMMEDIATE", NULL};		COMPLETE_WITH_LIST(constraint_list);	}	/* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */	else if (strcasecmp(prev2_wd, "SET") == 0 &&			 strcasecmp(prev_wd, "SESSION") == 0)	{		static const char * const my_list[] =		{"AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION", NULL};		COMPLETE_WITH_LIST(my_list);	}	/* Complete SET SESSION AUTHORIZATION with username */	else if (strcasecmp(prev3_wd, "SET") == 0			 && strcasecmp(prev2_wd, "SESSION") == 0			 && strcasecmp(prev_wd, "AUTHORIZATION") == 0)		COMPLETE_WITH_QUERY(Query_for_list_of_users);	/* Complete SET <var> with "TO" */	else if (strcasecmp(prev2_wd, "SET") == 0 &&			 strcasecmp(prev4_wd, "UPDATE") != 0)		COMPLETE_WITH_CONST("TO");	/* Suggest possible variable values */	else if (strcasecmp(prev3_wd, "SET") == 0 &&		   (strcasecmp(prev_wd, "TO") == 0 || strcmp(prev_wd, "=") == 0))	{		if (strcasecmp(prev2_wd, "DateStyle") == 0)		{			static const char * const my_list[] =			{"ISO", "SQL", "Postgres", "German",			 "YMD", "DMY", "MDY",			 "US", "European", "NonEuropean",			 "DEFAULT", NULL};			COMPLETE_WITH_LIST(my_list);		}		else if (strcasecmp(prev2_wd, "GEQO") == 0)		{			static const char * const my_list[] =			{"ON", "OFF", "DEFAULT", NULL};			COMPLETE_WITH_LIST(my_list);		}		else		{			static const char * const my_list[] =			{"DEFAULT", NULL};			COMPLETE_WITH_LIST(my_list);		}	}/* TRUNCATE */	else if (strcasecmp(prev_wd, "TRUNCATE") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);/* UNLISTEN */	else if (strcasecmp(prev_wd, "UNLISTEN") == 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' UNION SELECT '*'");/* UPDATE */	/* If prev. word is UPDATE suggest a list of tables */	else if (strcasecmp(prev_wd, "UPDATE") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	/* Complete UPDATE <table> with "SET" */	else if (strcasecmp(prev2_wd, "UPDATE") == 0)		COMPLETE_WITH_CONST("SET");	/*	 * If the previous word is SET (and it wasn't caught above as the	 * _first_ word) the word before it was (hopefully) a table name and	 * we'll now make a list of attributes.	 */	else if (strcasecmp(prev_wd, "SET") == 0)		COMPLETE_WITH_ATTR(prev2_wd);/* VACUUM */	else if (strcasecmp(prev_wd, "VACUUM") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,								   " UNION SELECT 'FULL'"								   " UNION SELECT 'ANALYZE'"								   " UNION SELECT 'VERBOSE'");	else if (strcasecmp(prev2_wd, "VACUUM") == 0 &&			 (strcasecmp(prev_wd, "FULL") == 0 ||			  strcasecmp(prev_wd, "ANALYZE") == 0 ||			  strcasecmp(prev_wd, "VERBOSE") == 0))		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);/* WHERE */	/* Simple case of the word before the where being the table name */	else if (strcasecmp(prev_wd, "WHERE") == 0)		COMPLETE_WITH_ATTR(prev2_wd);/* ... FROM ... *//* TODO: also include SRF ? */	else if (strcasecmp(prev_wd, "FROM") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL);/* Backslash commands *//* TODO:  \dc \dd \dl */	else if (strcmp(prev_wd, "\\connect") == 0 || strcmp(prev_wd, "\\c") == 0)		COMPLETE_WITH_QUERY(Query_for_list_of_databases);	else if (strcmp(prev_wd, "\\d") == 0 || strcmp(prev_wd, "\\d+") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tisv, NULL);	else if (strcmp(prev_wd, "\\da") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);	else if (strcmp(prev_wd, "\\dD") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);	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, "\\di") == 0 || strcmp(prev_wd, "\\di+") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);	else if (strcmp(prev_wd, "\\dn") == 0)		COMPLETE_WITH_QUERY(Query_for_list_of_schemas);	else if (strcmp(prev_wd, "\\dp") == 0 || strcmp(prev_wd, "\\z") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL);	else if (strcmp(prev_wd, "\\ds") == 0 || strcmp(prev_wd, "\\ds+") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);	else if (strcmp(prev_wd, "\\dS") == 0 || strcmp(prev_wd, "\\dS+") == 0)		COMPLETE_WITH_QUERY(Query_for_list_of_system_relations);	else if (strcmp(prev_wd, "\\dt") == 0 || strcmp(prev_wd, "\\dt+") == 0)		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);	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);	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)		COMPLETE_WITH_QUERY(Query_for_list_of_encodings);	else if (strcmp(prev_wd, "\\h") == 0 || strcmp(prev_wd, "\\help") == 0)		COMPLETE_WITH_LIST(sql_commands);	else if (strcmp(prev_wd, "\\pset") == 0)	{		static const char * const my_list[] =		{"format", "border", "expanded",		 "null", "fieldsep", "tuples_only", "title", "tableattr", "pager",		 "recordsep", NULL};		COMPLETE_WITH_LIST(my_list);	}	else if (strcmp(prev_wd, "\\cd") == 0 ||		 strcmp(prev_wd, "\\e") == 0 || strcmp(prev_wd, "\\edit") == 0 ||			 strcmp(prev_wd, "\\g") == 0 ||			 strcmp(prev_wd, "\\i") == 0 || strcmp(prev_wd, "\\include") == 0 ||		  strcmp(prev_wd, "\\o") == 0 || strcmp(prev_wd, "\\out") == 0 ||			 strcmp(prev_wd, "\\s") == 0 ||		   strcmp(prev_wd, "\\w") == 0 || strcmp(prev_wd, "\\write") == 0		)		matches = completion_matches(text, filename_completion_function);	/*	 * Finally, we look through the list of "things", such as TABLE, INDEX	 * and check if that was the previous word. If so, execute the query	 * to get a list of them.	 */	else	{		int			i;		for (i = 0; words_after_create[i].name; i++)		{			if (strcasecmp(prev_wd, words_after_create[i].name) == 0)			{				if (words_after_create[i].query)					COMPLETE_WITH_QUERY(words_after_create[i].query);				else if (words_after_create[i].squery)					COMPLETE_WITH_SCHEMA_QUERY(*words_after_create[i].squery,											   NULL);				break;			}		}	}	/*	 * If we still don't have anything to match we have to fabricate some	 * sort of default list. If we were to just return NULL, readline	 * automatically attempts filename completion, and that's usually no	 * good.	 */	if (matches == NULL)	{		COMPLETE_WITH_CONST("");#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER		rl_completion_append_character = '\0';#endif	}	/* free storage */	free(prev_wd);	free(prev2_wd);	free(prev3_wd);	free(prev4_wd);	/* Return our Grand List O' Matches */	return matches;}/* GENERATOR FUNCTIONS   These functions do all the actual work of completing the input. They get   passed the text so far and the count how many times they have been called so   far with the same text.   If you read the above carefully, you'll see that these don't get called   directly but through the readline interface.   The return value is expected to be the full completion of the text, going   through a list each time, or NULL if there are no more matches. The string   will be free()'d be readline, so you must run it through strdup() or   something of that sort.*//* This one gives you one from a list of things you can put after CREATE or DROP   as defined above.*/static char *create_command_generator(const char *text, int state){	static int	list_index,				string_length;	const char *name;

⌨️ 快捷键说明

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