mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	psql: Improve tab-completion for MERGE.
Commit 7103ebb7aa added the tab-completion for MERGE accidentally
in the middle of that for LOCK TABLE. This commit fixes this issue.
This also adds some tab-completion for MERGE.
Back-patch to v15 where MERGE was introduced.
Author: Kotaro Kawamoto, Fujii Masao
Reviewed-by: Shinya Kato, Álvaro Herrera
Discussion: https://postgr.es/m/9f1ad2a87a58cd5e7d64f3993130958d@oss.nttdata.com
			
			
This commit is contained in:
		@@ -1669,7 +1669,7 @@ psql_completion(const char *text, int start, int end)
 | 
				
			|||||||
		"COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
 | 
							"COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
 | 
				
			||||||
		"DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN",
 | 
							"DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN",
 | 
				
			||||||
		"FETCH", "GRANT", "IMPORT FOREIGN SCHEMA", "INSERT INTO", "LISTEN", "LOAD", "LOCK",
 | 
							"FETCH", "GRANT", "IMPORT FOREIGN SCHEMA", "INSERT INTO", "LISTEN", "LOAD", "LOCK",
 | 
				
			||||||
		"MERGE", "MOVE", "NOTIFY", "PREPARE",
 | 
							"MERGE INTO", "MOVE", "NOTIFY", "PREPARE",
 | 
				
			||||||
		"REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE",
 | 
							"REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE",
 | 
				
			||||||
		"RESET", "REVOKE", "ROLLBACK",
 | 
							"RESET", "REVOKE", "ROLLBACK",
 | 
				
			||||||
		"SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START",
 | 
							"SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START",
 | 
				
			||||||
@@ -3641,7 +3641,7 @@ psql_completion(const char *text, int start, int end)
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
	else if (Matches("EXPLAIN"))
 | 
						else if (Matches("EXPLAIN"))
 | 
				
			||||||
		COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 | 
							COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 | 
				
			||||||
					  "MERGE", "EXECUTE", "ANALYZE", "VERBOSE");
 | 
										  "MERGE INTO", "EXECUTE", "ANALYZE", "VERBOSE");
 | 
				
			||||||
	else if (HeadMatches("EXPLAIN", "(*") &&
 | 
						else if (HeadMatches("EXPLAIN", "(*") &&
 | 
				
			||||||
			 !HeadMatches("EXPLAIN", "(*)"))
 | 
								 !HeadMatches("EXPLAIN", "(*)"))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -3660,12 +3660,12 @@ psql_completion(const char *text, int start, int end)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else if (Matches("EXPLAIN", "ANALYZE"))
 | 
						else if (Matches("EXPLAIN", "ANALYZE"))
 | 
				
			||||||
		COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 | 
							COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 | 
				
			||||||
					  "MERGE", "EXECUTE", "VERBOSE");
 | 
										  "MERGE INTO", "EXECUTE", "VERBOSE");
 | 
				
			||||||
	else if (Matches("EXPLAIN", "(*)") ||
 | 
						else if (Matches("EXPLAIN", "(*)") ||
 | 
				
			||||||
			 Matches("EXPLAIN", "VERBOSE") ||
 | 
								 Matches("EXPLAIN", "VERBOSE") ||
 | 
				
			||||||
			 Matches("EXPLAIN", "ANALYZE", "VERBOSE"))
 | 
								 Matches("EXPLAIN", "ANALYZE", "VERBOSE"))
 | 
				
			||||||
		COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 | 
							COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 | 
				
			||||||
					  "MERGE", "EXECUTE");
 | 
										  "MERGE INTO", "EXECUTE");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* FETCH && MOVE */
 | 
					/* FETCH && MOVE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -4065,58 +4065,90 @@ psql_completion(const char *text, int start, int end)
 | 
				
			|||||||
	else if (HeadMatches("LOCK") && TailMatches("IN", "SHARE"))
 | 
						else if (HeadMatches("LOCK") && TailMatches("IN", "SHARE"))
 | 
				
			||||||
		COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE",
 | 
							COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE",
 | 
				
			||||||
					  "UPDATE EXCLUSIVE MODE");
 | 
										  "UPDATE EXCLUSIVE MODE");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Complete LOCK [TABLE] [ONLY] <table> [IN lockmode MODE] with "NOWAIT" */
 | 
				
			||||||
 | 
						else if (HeadMatches("LOCK") && TailMatches("MODE"))
 | 
				
			||||||
 | 
							COMPLETE_WITH("NOWAIT");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* MERGE --- can be inside EXPLAIN */
 | 
					/* MERGE --- can be inside EXPLAIN */
 | 
				
			||||||
	else if (TailMatches("MERGE"))
 | 
						else if (TailMatches("MERGE"))
 | 
				
			||||||
		COMPLETE_WITH("INTO");
 | 
							COMPLETE_WITH("INTO");
 | 
				
			||||||
	else if (TailMatches("MERGE", "INTO"))
 | 
						else if (TailMatches("MERGE", "INTO"))
 | 
				
			||||||
		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_mergetargets);
 | 
							COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_mergetargets);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Complete MERGE INTO <table> [[AS] <alias>] with USING */
 | 
				
			||||||
	else if (TailMatches("MERGE", "INTO", MatchAny))
 | 
						else if (TailMatches("MERGE", "INTO", MatchAny))
 | 
				
			||||||
		COMPLETE_WITH("USING", "AS");
 | 
							COMPLETE_WITH("USING", "AS");
 | 
				
			||||||
	else if (TailMatches("MERGE", "INTO", MatchAny, "USING"))
 | 
						else if (TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny) ||
 | 
				
			||||||
		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
 | 
								 TailMatches("MERGE", "INTO", MatchAny, MatchAnyExcept("USING|AS")))
 | 
				
			||||||
	/* with [AS] alias */
 | 
					 | 
				
			||||||
	else if (TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny))
 | 
					 | 
				
			||||||
		COMPLETE_WITH("USING");
 | 
							COMPLETE_WITH("USING");
 | 
				
			||||||
	else if (TailMatches("MERGE", "INTO", MatchAny, MatchAny))
 | 
					
 | 
				
			||||||
		COMPLETE_WITH("USING");
 | 
						/*
 | 
				
			||||||
	else if (TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING"))
 | 
						 * Complete MERGE INTO ... USING with a list of relations supporting
 | 
				
			||||||
		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
 | 
						 * SELECT
 | 
				
			||||||
	else if (TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING"))
 | 
						 */
 | 
				
			||||||
		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
 | 
						else if (TailMatches("MERGE", "INTO", MatchAny, "USING") ||
 | 
				
			||||||
	/* ON */
 | 
								 TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING") ||
 | 
				
			||||||
	else if (TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny))
 | 
								 TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING"))
 | 
				
			||||||
 | 
							COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Complete MERGE INTO <table> [[AS] <alias>] USING <relations> [[AS]
 | 
				
			||||||
 | 
						 * alias] with ON
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						else if (TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny) ||
 | 
				
			||||||
 | 
								 TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny) ||
 | 
				
			||||||
 | 
								 TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING", MatchAny))
 | 
				
			||||||
 | 
							COMPLETE_WITH("AS", "ON");
 | 
				
			||||||
 | 
						else if (TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny, "AS", MatchAny) ||
 | 
				
			||||||
 | 
								 TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny) ||
 | 
				
			||||||
 | 
								 TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING", MatchAny, "AS", MatchAny) ||
 | 
				
			||||||
 | 
								 TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")) ||
 | 
				
			||||||
 | 
								 TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")) ||
 | 
				
			||||||
 | 
								 TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")))
 | 
				
			||||||
		COMPLETE_WITH("ON");
 | 
							COMPLETE_WITH("ON");
 | 
				
			||||||
	else if (TailMatches("INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny))
 | 
					
 | 
				
			||||||
		COMPLETE_WITH("ON");
 | 
						/* Complete MERGE INTO ... ON with target table attributes */
 | 
				
			||||||
	else if (TailMatches("INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAny))
 | 
					 | 
				
			||||||
		COMPLETE_WITH("ON");
 | 
					 | 
				
			||||||
	/* ON condition */
 | 
					 | 
				
			||||||
	else if (TailMatches("INTO", MatchAny, "USING", MatchAny, "ON"))
 | 
						else if (TailMatches("INTO", MatchAny, "USING", MatchAny, "ON"))
 | 
				
			||||||
		COMPLETE_WITH_ATTR(prev4_wd);
 | 
							COMPLETE_WITH_ATTR(prev4_wd);
 | 
				
			||||||
	else if (TailMatches("INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny, "ON"))
 | 
						else if (TailMatches("INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny, "ON"))
 | 
				
			||||||
		COMPLETE_WITH_ATTR(prev8_wd);
 | 
							COMPLETE_WITH_ATTR(prev8_wd);
 | 
				
			||||||
	else if (TailMatches("INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAny, "ON"))
 | 
						else if (TailMatches("INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAny, "ON"))
 | 
				
			||||||
		COMPLETE_WITH_ATTR(prev6_wd);
 | 
							COMPLETE_WITH_ATTR(prev6_wd);
 | 
				
			||||||
	/* WHEN [NOT] MATCHED */
 | 
					
 | 
				
			||||||
	else if (TailMatches("USING", MatchAny, "ON", MatchAny))
 | 
						/*
 | 
				
			||||||
 | 
						 * Complete ... USING <relation> [[AS] alias] ON join condition
 | 
				
			||||||
 | 
						 * (consisting of one or three words typically used) with WHEN [NOT]
 | 
				
			||||||
 | 
						 * MATCHED
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						else if (TailMatches("USING", MatchAny, "ON", MatchAny) ||
 | 
				
			||||||
 | 
								 TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny) ||
 | 
				
			||||||
 | 
								 TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny) ||
 | 
				
			||||||
 | 
								 TailMatches("USING", MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")) ||
 | 
				
			||||||
 | 
								 TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")) ||
 | 
				
			||||||
 | 
								 TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")))
 | 
				
			||||||
		COMPLETE_WITH("WHEN MATCHED", "WHEN NOT MATCHED");
 | 
							COMPLETE_WITH("WHEN MATCHED", "WHEN NOT MATCHED");
 | 
				
			||||||
	else if (TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny))
 | 
						else if (TailMatches("USING", MatchAny, "ON", MatchAny, "WHEN") ||
 | 
				
			||||||
		COMPLETE_WITH("WHEN MATCHED", "WHEN NOT MATCHED");
 | 
								 TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, "WHEN") ||
 | 
				
			||||||
	else if (TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny))
 | 
								 TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, "WHEN") ||
 | 
				
			||||||
		COMPLETE_WITH("WHEN MATCHED", "WHEN NOT MATCHED");
 | 
								 TailMatches("USING", MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN") ||
 | 
				
			||||||
	else if (TailMatches("WHEN", "MATCHED"))
 | 
								 TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN") ||
 | 
				
			||||||
		COMPLETE_WITH("THEN", "AND");
 | 
								 TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN"))
 | 
				
			||||||
	else if (TailMatches("WHEN", "NOT", "MATCHED"))
 | 
							COMPLETE_WITH("MATCHED", "NOT MATCHED");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Complete ... WHEN [NOT] MATCHED with THEN/AND */
 | 
				
			||||||
 | 
						else if (TailMatches("WHEN", "MATCHED") ||
 | 
				
			||||||
 | 
								 TailMatches("WHEN", "NOT", "MATCHED"))
 | 
				
			||||||
		COMPLETE_WITH("THEN", "AND");
 | 
							COMPLETE_WITH("THEN", "AND");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Complete ... WHEN MATCHED THEN with UPDATE SET/DELETE/DO NOTHING */
 | 
				
			||||||
	else if (TailMatches("WHEN", "MATCHED", "THEN"))
 | 
						else if (TailMatches("WHEN", "MATCHED", "THEN"))
 | 
				
			||||||
		COMPLETE_WITH("UPDATE", "DELETE");
 | 
							COMPLETE_WITH("UPDATE SET", "DELETE", "DO NOTHING");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Complete ... WHEN NOT MATCHED THEN with INSERT/DO NOTHING */
 | 
				
			||||||
	else if (TailMatches("WHEN", "NOT", "MATCHED", "THEN"))
 | 
						else if (TailMatches("WHEN", "NOT", "MATCHED", "THEN"))
 | 
				
			||||||
		COMPLETE_WITH("INSERT", "DO NOTHING");
 | 
							COMPLETE_WITH("INSERT", "DO NOTHING");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Complete LOCK [TABLE] [ONLY] <table> [IN lockmode MODE] with "NOWAIT" */
 | 
					 | 
				
			||||||
	else if (HeadMatches("LOCK") && TailMatches("MODE"))
 | 
					 | 
				
			||||||
		COMPLETE_WITH("NOWAIT");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTIFY --- can be inside EXPLAIN, RULE, etc */
 | 
					/* NOTIFY --- can be inside EXPLAIN, RULE, etc */
 | 
				
			||||||
	else if (TailMatches("NOTIFY"))
 | 
						else if (TailMatches("NOTIFY"))
 | 
				
			||||||
		COMPLETE_WITH_QUERY(Query_for_list_of_channels);
 | 
							COMPLETE_WITH_QUERY(Query_for_list_of_channels);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user