From 20f66b8aaf336a2a2344a463ae8fd96740b04893 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 13 Jul 2024 12:41:33 -0400
Subject: [PATCH v1 4/5] Convert tab-complete's long else-if chain to a switch
 statement.

The initial HeadMatches/TailMatches/Matches test in each else-if arm
is now performed in a table-driven loop.  Where we get a match, the
corresponding switch case is invoked to see if the match succeeds.
(It might not, if there were additional conditions in the original
else-if test.)

99% of the mind-numbingly repetitious changes inside
match_previous_words were performed by a Perl script, which isn't
proposed for commit, but I'll include it in the email thread.

The total number of string comparisons done is just about the
same as it was in the previous coding; however, now that we
have table-driven logic underlying the handmade rules, there
is room to improve that.  For now I haven't bothered because
tab completion is still plenty fast enough for human use.
If the number of rules keeps increasing, we might someday
need to do more in that area.

The immediate benefit of all this thrashing is that C compilers
frequently don't deal well with long else-if chains.  On gcc 8.5.0,
this reduces the compile time of tab-complete.c by about a factor of
four, while MSVC is reported to crash outright with the previous
coding.
---
 src/bin/psql/tab-complete.in.c | 2850 +++++++++++++++++++-------------
 1 file changed, 1726 insertions(+), 1124 deletions(-)

diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index c92fc729be..a3bd6b7970 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -1304,6 +1304,47 @@ static const pgsql_thing_t words_after_create[] = {
 	{NULL}						/* end of list */
 };
 
+/*
+ * The tcpatterns[] table provides the initial pattern-match rule for each
+ * switch case in match_previous_words().  The contents of the table
+ * are constructed by gen_tabcomplete.pl.
+ */
+
+/* Basic match rules appearing in tcpatterns[].kind */
+enum TCPatternKind
+{
+	Match,
+	MatchCS,
+	HeadMatch,
+	HeadMatchCS,
+	TailMatch,
+	TailMatchCS,
+};
+
+/* Things besides string literals that can appear in tcpatterns[].words */
+#define MatchAny  NULL
+#define MatchAnyExcept(pattern)  ("!" pattern)
+#define MatchAnyN ""
+
+/* One entry in tcpatterns[] */
+typedef struct
+{
+	int			id;				/* case label used in match_previous_words */
+	enum TCPatternKind kind;	/* match kind, see above */
+	int			nwords;			/* length of words[] array */
+	const char *const *words;	/* array of match words */
+} TCPattern;
+
+/* Macro emitted by gen_tabcomplete.pl to fill a tcpatterns[] entry */
+#define TCPAT(id, kind, ...) \
+	{ (id), (kind), VA_ARGS_NARGS(__VA_ARGS__), \
+	  (const char * const []) { __VA_ARGS__ } }
+
+static const TCPattern tcpatterns[] =
+{
+	/* Insert tab-completion pattern data here. */
+};
+
 /* Storage parameters for CREATE TABLE and ALTER TABLE */
 static const char *const table_storage_parameters[] = {
 	"autovacuum_analyze_scale_factor",
@@ -1357,7 +1398,8 @@ static const char *const view_optional_parameters[] = {
 
 /* Forward declaration of functions */
 static char **psql_completion(const char *text, int start, int end);
-static char **match_previous_words(const char *text, int start, int end,
+static char **match_previous_words(int pattern_id,
+								   const char *text, int start, int end,
 								   char **previous_words,
 								   int previous_words_count);
 static char *create_command_generator(const char *text, int state);
@@ -1469,10 +1511,6 @@ initialize_readline(void)
  * just be written directly in patterns.)  There is also MatchAnyN, but that
  * is supported only in Matches/MatchesCS and is not handled here.
  */
-#define MatchAny  NULL
-#define MatchAnyExcept(pattern)  ("!" pattern)
-#define MatchAnyN ""
-
 static bool
 word_matches(const char *pattern,
 			 const char *word,
@@ -1894,17 +1932,78 @@ psql_completion(const char *text, int start, int end)
 		COMPLETE_WITH_LIST(sql_commands);
 
 	/* Else try completions based on matching patterns of previous words */
-	else if ((matches = match_previous_words(text, start, end,
+	else
+	{
+		/*
+		 * For now, we have to try the patterns in the order they are stored
+		 * (matching the order of switch cases in match_previous_words),
+		 * because some of the logic in match_previous_words assumes that
+		 * previous matches have been eliminated.  This is fairly
+		 * unprincipled, and it is likely that there are undesirable as well
+		 * as desirable interactions hidden in the order of the pattern
+		 * checks.  TODO: think about a better way to manage that.
+		 */
+		for (int tindx = 0; tindx < lengthof(tcpatterns); tindx++)
+		{
+			const TCPattern *tcpat = tcpatterns + tindx;
+			bool		match = false;
+
+			switch (tcpat->kind)
+			{
+				case Match:
+					match = MatchesArray(false,
+										 previous_words_count,
+										 previous_words,
+										 tcpat->nwords, tcpat->words);
+					break;
+				case MatchCS:
+					match = MatchesArray(true,
+										 previous_words_count,
+										 previous_words,
+										 tcpat->nwords, tcpat->words);
+					break;
+				case HeadMatch:
+					match = HeadMatchesArray(false,
+											 previous_words_count,
+											 previous_words,
+											 tcpat->nwords, tcpat->words);
+					break;
+				case HeadMatchCS:
+					match = HeadMatchesArray(true,
+											 previous_words_count,
+											 previous_words,
+											 tcpat->nwords, tcpat->words);
+					break;
+				case TailMatch:
+					match = TailMatchesArray(false,
+											 previous_words_count,
 											 previous_words,
-											 previous_words_count)) != NULL)
-		 /* skip */ ;
+											 tcpat->nwords, tcpat->words);
+					break;
+				case TailMatchCS:
+					match = TailMatchesArray(true,
+											 previous_words_count,
+											 previous_words,
+											 tcpat->nwords, tcpat->words);
+					break;
+			}
+			if (match)
+			{
+				matches = match_previous_words(tcpat->id, text, start, end,
+											   previous_words,
+											   previous_words_count);
+				if (matches != NULL)
+					break;
+			}
+		}
+	}
 
 	/*
 	 * 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
+	if (matches == NULL)
 	{
 		const pgsql_thing_t *wac;
 
@@ -1963,20 +2062,19 @@ psql_completion(const char *text, int start, int end)
  * Returns a matches list, or NULL if no match.
  */
 static char **
-match_previous_words(const char *text, int start, int end,
+match_previous_words(int pattern_id,
+					 const char *text, int start, int end,
 					 char **previous_words, int previous_words_count)
 {
 	/* This is the variable we'll return. */
 	char	  **matches = NULL;
 
-	/* Dummy, to be replaced by switch */
-	if (0)
-		;
-
+	/* Examine the pattern identified by the caller. */
+	switch (pattern_id)
+	{
 /* CREATE */
 	/* complete with something you can create */
-	else if (TailMatches("CREATE"))
-	{
+		case TailMatches("CREATE"):
 		/* only some object types can be created as part of CREATE SCHEMA */
 		if (HeadMatches("CREATE", "SCHEMA"))
 			COMPLETE_WITH("TABLE", "VIEW", "INDEX", "SEQUENCE", "TRIGGER",
@@ -1984,97 +2082,110 @@ match_previous_words(const char *text, int start, int end,
 						  "UNIQUE", "UNLOGGED");
 		else
 			matches = rl_completion_matches(text, create_command_generator);
-	}
+			break;
 	/* complete with something you can create or replace */
-	else if (TailMatches("CREATE", "OR", "REPLACE"))
+		case TailMatches("CREATE", "OR", "REPLACE"):
 		COMPLETE_WITH("FUNCTION", "PROCEDURE", "LANGUAGE", "RULE", "VIEW",
 					  "AGGREGATE", "TRANSFORM", "TRIGGER");
+			break;
 
 /* DROP, but not DROP embedded in other commands */
 	/* complete with something you can drop */
-	else if (Matches("DROP"))
+		case Matches("DROP"):
 		matches = rl_completion_matches(text, drop_command_generator);
+			break;
 
 /* ALTER */
 
 	/* ALTER TABLE */
-	else if (Matches("ALTER", "TABLE"))
+		case Matches("ALTER", "TABLE"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables,
 										"ALL IN TABLESPACE");
+			break;
 
 	/* ALTER something */
-	else if (Matches("ALTER"))
+		case Matches("ALTER"):
 		matches = rl_completion_matches(text, alter_command_generator);
+			break;
 	/* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */
-	else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny))
+		case TailMatches("ALL", "IN", "TABLESPACE", MatchAny):
 		COMPLETE_WITH("SET TABLESPACE", "OWNED BY");
+			break;
 	/* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */
-	else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY"))
+		case TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
+			break;
 	/* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */
-	else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny))
+		case TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny):
 		COMPLETE_WITH("SET TABLESPACE");
+			break;
 	/* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> */
-	else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
+		case Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny):
 		COMPLETE_WITH("(");
+			break;
 	/* ALTER AGGREGATE <name> (...) */
-	else if (Matches("ALTER", "AGGREGATE", MatchAny, MatchAny))
-	{
+		case Matches("ALTER", "AGGREGATE", MatchAny, MatchAny):
 		if (ends_with(prev_wd, ')'))
 			COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
 		else
 			COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
-	}
+			break;
 	/* ALTER FUNCTION <name> (...) */
-	else if (Matches("ALTER", "FUNCTION", MatchAny, MatchAny))
-	{
+		case Matches("ALTER", "FUNCTION", MatchAny, MatchAny):
 		if (ends_with(prev_wd, ')'))
 			COMPLETE_WITH(Alter_function_options);
 		else
 			COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
-	}
+			break;
 	/* ALTER PROCEDURE <name> (...) */
-	else if (Matches("ALTER", "PROCEDURE", MatchAny, MatchAny))
-	{
+		case Matches("ALTER", "PROCEDURE", MatchAny, MatchAny):
 		if (ends_with(prev_wd, ')'))
 			COMPLETE_WITH(Alter_procedure_options);
 		else
 			COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
-	}
+			break;
 	/* ALTER ROUTINE <name> (...) */
-	else if (Matches("ALTER", "ROUTINE", MatchAny, MatchAny))
-	{
+		case Matches("ALTER", "ROUTINE", MatchAny, MatchAny):
 		if (ends_with(prev_wd, ')'))
 			COMPLETE_WITH(Alter_routine_options);
 		else
 			COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
-	}
+			break;
 	/* ALTER FUNCTION|ROUTINE <name> (...) PARALLEL */
-	else if (Matches("ALTER", "FUNCTION|ROUTINE", MatchAny, MatchAny, "PARALLEL"))
+		case Matches("ALTER", "FUNCTION|ROUTINE", MatchAny, MatchAny, "PARALLEL"):
 		COMPLETE_WITH("RESTRICTED", "SAFE", "UNSAFE");
+			break;
 	/* ALTER FUNCTION|PROCEDURE|ROUTINE <name> (...) [EXTERNAL] SECURITY */
-	else if (Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny, "SECURITY") ||
-			 Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny, "EXTERNAL", "SECURITY"))
+		case Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny, "SECURITY"):
+		case Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny, "EXTERNAL", "SECURITY"):
 		COMPLETE_WITH("DEFINER", "INVOKER");
+			break;
 	/* ALTER FUNCTION|PROCEDURE|ROUTINE <name> (...) RESET */
-	else if (Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny, "RESET"))
+		case Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny, "RESET"):
 		COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_set_vars,
 										  "ALL");
+			break;
 	/* ALTER FUNCTION|PROCEDURE|ROUTINE <name> (...) SET */
-	else if (Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny, "SET"))
+		case Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny, "SET"):
 		COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_set_vars,
 										  "SCHEMA");
+			break;
 
 	/* ALTER PUBLICATION <name> */
-	else if (Matches("ALTER", "PUBLICATION", MatchAny))
+		case Matches("ALTER", "PUBLICATION", MatchAny):
 		COMPLETE_WITH("ADD", "DROP", "OWNER TO", "RENAME TO", "SET");
+			break;
 	/* ALTER PUBLICATION <name> ADD */
-	else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD"))
+		case Matches("ALTER", "PUBLICATION", MatchAny, "ADD"):
 		COMPLETE_WITH("TABLES IN SCHEMA", "TABLE");
-	else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE") ||
-			 (HeadMatches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE") &&
-			  ends_with(prev_wd, ',')))
+			break;
+		case Matches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE"):
+		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
+		case HeadMatches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE"):
+		if (ends_with(prev_wd, ','))
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 
 	/*
 	 * "ALTER PUBLICATION <name> SET TABLE <name> WHERE (" - complete with
@@ -2083,235 +2194,280 @@ match_previous_words(const char *text, int start, int end,
 	 * "ALTER PUBLICATION <name> ADD TABLE <name> WHERE (" - complete with
 	 * table attributes
 	 */
-	else if (Matches("ALTER", "PUBLICATION", MatchAny, MatchAnyN, "WHERE"))
+		case Matches("ALTER", "PUBLICATION", MatchAny, MatchAnyN, "WHERE"):
 		COMPLETE_WITH("(");
-	else if (Matches("ALTER", "PUBLICATION", MatchAny, MatchAnyN, "WHERE", "("))
+			break;
+		case Matches("ALTER", "PUBLICATION", MatchAny, MatchAnyN, "WHERE", "("):
 		COMPLETE_WITH_ATTR(prev3_wd);
-	else if (HeadMatches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE") &&
-			 !TailMatches("WHERE", "(*)"))
+			break;
+		case HeadMatches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE"):
+		if (!TailMatches("WHERE", "(*)"))
 		COMPLETE_WITH(",", "WHERE (");
-	else if (HeadMatches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE"))
+			break;
+		case HeadMatches("ALTER", "PUBLICATION", MatchAny, "ADD|SET", "TABLE"):
 		COMPLETE_WITH(",");
+			break;
 	/* ALTER PUBLICATION <name> DROP */
-	else if (Matches("ALTER", "PUBLICATION", MatchAny, "DROP"))
+		case Matches("ALTER", "PUBLICATION", MatchAny, "DROP"):
 		COMPLETE_WITH("TABLES IN SCHEMA", "TABLE");
+			break;
 	/* ALTER PUBLICATION <name> SET */
-	else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET"))
+		case Matches("ALTER", "PUBLICATION", MatchAny, "SET"):
 		COMPLETE_WITH("(", "TABLES IN SCHEMA", "TABLE");
-	else if (Matches("ALTER", "PUBLICATION", MatchAny, "ADD|DROP|SET", "TABLES", "IN", "SCHEMA"))
+			break;
+		case Matches("ALTER", "PUBLICATION", MatchAny, "ADD|DROP|SET", "TABLES", "IN", "SCHEMA"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas
 								 " AND nspname NOT LIKE E'pg\\\\_%%'",
 								 "CURRENT_SCHEMA");
+			break;
 	/* ALTER PUBLICATION <name> SET ( */
-	else if (Matches("ALTER", "PUBLICATION", MatchAny, MatchAnyN, "SET", "("))
+		case Matches("ALTER", "PUBLICATION", MatchAny, MatchAnyN, "SET", "("):
 		COMPLETE_WITH("publish", "publish_via_partition_root");
+			break;
 	/* ALTER SUBSCRIPTION <name> */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny))
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny):
 		COMPLETE_WITH("CONNECTION", "ENABLE", "DISABLE", "OWNER TO",
 					  "RENAME TO", "REFRESH PUBLICATION", "SET", "SKIP (",
 					  "ADD PUBLICATION", "DROP PUBLICATION");
+			break;
 	/* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "REFRESH", "PUBLICATION"))
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "REFRESH", "PUBLICATION"):
 		COMPLETE_WITH("WITH (");
+			break;
 	/* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION WITH ( */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "REFRESH", "PUBLICATION", "WITH", "("))
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "REFRESH", "PUBLICATION", "WITH", "("):
 		COMPLETE_WITH("copy_data");
+			break;
 	/* ALTER SUBSCRIPTION <name> SET */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, "SET"))
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny, "SET"):
 		COMPLETE_WITH("(", "PUBLICATION");
+			break;
 	/* ALTER SUBSCRIPTION <name> SET ( */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "SET", "("))
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "SET", "("):
 		COMPLETE_WITH("binary", "disable_on_error", "failover", "origin",
 					  "password_required", "run_as_owner", "slot_name",
 					  "streaming", "synchronous_commit");
+			break;
 	/* ALTER SUBSCRIPTION <name> SKIP ( */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "SKIP", "("))
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "SKIP", "("):
 		COMPLETE_WITH("lsn");
+			break;
 	/* ALTER SUBSCRIPTION <name> SET PUBLICATION */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "SET", "PUBLICATION"))
-	{
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "SET", "PUBLICATION"):
 		/* complete with nothing here as this refers to remote publications */
-	}
+			break;
 	/* ALTER SUBSCRIPTION <name> ADD|DROP|SET PUBLICATION <name> */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN,
-					 "ADD|DROP|SET", "PUBLICATION", MatchAny))
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "ADD|DROP|SET", "PUBLICATION", MatchAny):
 		COMPLETE_WITH("WITH (");
+			break;
 	/* ALTER SUBSCRIPTION <name> ADD|DROP|SET PUBLICATION <name> WITH ( */
-	else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN,
-					 "ADD|DROP|SET", "PUBLICATION", MatchAny, "WITH", "("))
+		case Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "ADD|DROP|SET", "PUBLICATION", MatchAny, "WITH", "("):
 		COMPLETE_WITH("copy_data", "refresh");
+			break;
 
 	/* ALTER SCHEMA <name> */
-	else if (Matches("ALTER", "SCHEMA", MatchAny))
+		case Matches("ALTER", "SCHEMA", MatchAny):
 		COMPLETE_WITH("OWNER TO", "RENAME TO");
+			break;
 
 	/* ALTER COLLATION <name> */
-	else if (Matches("ALTER", "COLLATION", MatchAny))
+		case Matches("ALTER", "COLLATION", MatchAny):
 		COMPLETE_WITH("OWNER TO", "REFRESH VERSION", "RENAME TO", "SET SCHEMA");
+			break;
 
 	/* ALTER CONVERSION <name> */
-	else if (Matches("ALTER", "CONVERSION", MatchAny))
+		case Matches("ALTER", "CONVERSION", MatchAny):
 		COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
+			break;
 
 	/* ALTER DATABASE <name> */
-	else if (Matches("ALTER", "DATABASE", MatchAny))
+		case Matches("ALTER", "DATABASE", MatchAny):
 		COMPLETE_WITH("RESET", "SET", "OWNER TO", "REFRESH COLLATION VERSION", "RENAME TO",
 					  "IS_TEMPLATE", "ALLOW_CONNECTIONS",
 					  "CONNECTION LIMIT");
+			break;
 
 	/* ALTER DATABASE <name> SET TABLESPACE */
-	else if (Matches("ALTER", "DATABASE", MatchAny, "SET", "TABLESPACE"))
+		case Matches("ALTER", "DATABASE", MatchAny, "SET", "TABLESPACE"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
+			break;
 
 	/* ALTER EVENT TRIGGER */
-	else if (Matches("ALTER", "EVENT", "TRIGGER"))
+		case Matches("ALTER", "EVENT", "TRIGGER"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
+			break;
 
 	/* ALTER EVENT TRIGGER <name> */
-	else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny))
+		case Matches("ALTER", "EVENT", "TRIGGER", MatchAny):
 		COMPLETE_WITH("DISABLE", "ENABLE", "OWNER TO", "RENAME TO");
+			break;
 
 	/* ALTER EVENT TRIGGER <name> ENABLE */
-	else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE"))
+		case Matches("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE"):
 		COMPLETE_WITH("REPLICA", "ALWAYS");
+			break;
 
 	/* ALTER EXTENSION <name> */
-	else if (Matches("ALTER", "EXTENSION", MatchAny))
+		case Matches("ALTER", "EXTENSION", MatchAny):
 		COMPLETE_WITH("ADD", "DROP", "UPDATE", "SET SCHEMA");
+			break;
 
 	/* ALTER EXTENSION <name> ADD|DROP */
-	else if (Matches("ALTER", "EXTENSION", MatchAny, "ADD|DROP"))
+		case Matches("ALTER", "EXTENSION", MatchAny, "ADD|DROP"):
 		COMPLETE_WITH("ACCESS METHOD", "AGGREGATE", "CAST", "COLLATION",
 					  "CONVERSION", "DOMAIN", "EVENT TRIGGER", "FOREIGN",
 					  "FUNCTION", "MATERIALIZED VIEW", "OPERATOR",
 					  "LANGUAGE", "PROCEDURE", "ROUTINE", "SCHEMA",
 					  "SEQUENCE", "SERVER", "TABLE", "TEXT SEARCH",
 					  "TRANSFORM FOR", "TYPE", "VIEW");
+			break;
 
 	/* ALTER EXTENSION <name> ADD|DROP FOREIGN */
-	else if (Matches("ALTER", "EXTENSION", MatchAny, "ADD|DROP", "FOREIGN"))
+		case Matches("ALTER", "EXTENSION", MatchAny, "ADD|DROP", "FOREIGN"):
 		COMPLETE_WITH("DATA WRAPPER", "TABLE");
+			break;
 
 	/* ALTER EXTENSION <name> ADD|DROP OPERATOR */
-	else if (Matches("ALTER", "EXTENSION", MatchAny, "ADD|DROP", "OPERATOR"))
+		case Matches("ALTER", "EXTENSION", MatchAny, "ADD|DROP", "OPERATOR"):
 		COMPLETE_WITH("CLASS", "FAMILY");
+			break;
 
 	/* ALTER EXTENSION <name> ADD|DROP TEXT SEARCH */
-	else if (Matches("ALTER", "EXTENSION", MatchAny, "ADD|DROP", "TEXT", "SEARCH"))
+		case Matches("ALTER", "EXTENSION", MatchAny, "ADD|DROP", "TEXT", "SEARCH"):
 		COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
+			break;
 
 	/* ALTER EXTENSION <name> UPDATE */
-	else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE"))
+		case Matches("ALTER", "EXTENSION", MatchAny, "UPDATE"):
 		COMPLETE_WITH("TO");
+			break;
 
 	/* ALTER EXTENSION <name> UPDATE TO */
-	else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO"))
-	{
+		case Matches("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
-	}
+			break;
 
 	/* ALTER FOREIGN */
-	else if (Matches("ALTER", "FOREIGN"))
+		case Matches("ALTER", "FOREIGN"):
 		COMPLETE_WITH("DATA WRAPPER", "TABLE");
+			break;
 
 	/* ALTER FOREIGN DATA WRAPPER <name> */
-	else if (Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny))
+		case Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny):
 		COMPLETE_WITH("HANDLER", "VALIDATOR", "NO",
 					  "OPTIONS", "OWNER TO", "RENAME TO");
-	else if (Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny, "NO"))
+			break;
+		case Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny, "NO"):
 		COMPLETE_WITH("HANDLER", "VALIDATOR");
+			break;
 
 	/* ALTER FOREIGN TABLE <name> */
-	else if (Matches("ALTER", "FOREIGN", "TABLE", MatchAny))
+		case Matches("ALTER", "FOREIGN", "TABLE", MatchAny):
 		COMPLETE_WITH("ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE",
 					  "INHERIT", "NO INHERIT", "OPTIONS", "OWNER TO",
 					  "RENAME", "SET", "VALIDATE CONSTRAINT");
+			break;
 
 	/* ALTER INDEX */
-	else if (Matches("ALTER", "INDEX"))
+		case Matches("ALTER", "INDEX"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
 										"ALL IN TABLESPACE");
+			break;
 	/* ALTER INDEX <name> */
-	else if (Matches("ALTER", "INDEX", MatchAny))
+		case Matches("ALTER", "INDEX", MatchAny):
 		COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET",
 					  "RESET", "ATTACH PARTITION",
 					  "DEPENDS ON EXTENSION", "NO DEPENDS ON EXTENSION");
-	else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH"))
+			break;
+		case Matches("ALTER", "INDEX", MatchAny, "ATTACH"):
 		COMPLETE_WITH("PARTITION");
-	else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION"))
+			break;
+		case Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
+			break;
 	/* ALTER INDEX <name> ALTER */
-	else if (Matches("ALTER", "INDEX", MatchAny, "ALTER"))
+		case Matches("ALTER", "INDEX", MatchAny, "ALTER"):
 		COMPLETE_WITH("COLUMN");
+			break;
 	/* ALTER INDEX <name> ALTER COLUMN */
-	else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN"))
-	{
+		case Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY_VERBATIM(Query_for_list_of_attribute_numbers);
-	}
+			break;
 	/* ALTER INDEX <name> ALTER COLUMN <colnum> */
-	else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny))
+		case Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny):
 		COMPLETE_WITH("SET STATISTICS");
+			break;
 	/* ALTER INDEX <name> ALTER COLUMN <colnum> SET */
-	else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET"))
+		case Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET"):
 		COMPLETE_WITH("STATISTICS");
+			break;
 	/* ALTER INDEX <name> ALTER COLUMN <colnum> SET STATISTICS */
-	else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS"))
-	{
+		case Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS"):
 		/* Enforce no completion here, as an integer has to be specified */
-	}
+			break;
 	/* ALTER INDEX <name> SET */
-	else if (Matches("ALTER", "INDEX", MatchAny, "SET"))
+		case Matches("ALTER", "INDEX", MatchAny, "SET"):
 		COMPLETE_WITH("(", "TABLESPACE");
+			break;
 	/* ALTER INDEX <name> RESET */
-	else if (Matches("ALTER", "INDEX", MatchAny, "RESET"))
+		case Matches("ALTER", "INDEX", MatchAny, "RESET"):
 		COMPLETE_WITH("(");
+			break;
 	/* ALTER INDEX <foo> SET|RESET ( */
-	else if (Matches("ALTER", "INDEX", MatchAny, "RESET", "("))
+		case Matches("ALTER", "INDEX", MatchAny, "RESET", "("):
 		COMPLETE_WITH("fillfactor",
 					  "deduplicate_items",	/* BTREE */
 					  "fastupdate", "gin_pending_list_limit",	/* GIN */
 					  "buffering",	/* GiST */
 					  "pages_per_range", "autosummarize"	/* BRIN */
 			);
-	else if (Matches("ALTER", "INDEX", MatchAny, "SET", "("))
+			break;
+		case Matches("ALTER", "INDEX", MatchAny, "SET", "("):
 		COMPLETE_WITH("fillfactor =",
 					  "deduplicate_items =",	/* BTREE */
 					  "fastupdate =", "gin_pending_list_limit =",	/* GIN */
 					  "buffering =",	/* GiST */
 					  "pages_per_range =", "autosummarize ="	/* BRIN */
 			);
-	else if (Matches("ALTER", "INDEX", MatchAny, "NO", "DEPENDS"))
+			break;
+		case Matches("ALTER", "INDEX", MatchAny, "NO", "DEPENDS"):
 		COMPLETE_WITH("ON EXTENSION");
-	else if (Matches("ALTER", "INDEX", MatchAny, "DEPENDS"))
+			break;
+		case Matches("ALTER", "INDEX", MatchAny, "DEPENDS"):
 		COMPLETE_WITH("ON EXTENSION");
+			break;
 
 	/* ALTER LANGUAGE <name> */
-	else if (Matches("ALTER", "LANGUAGE", MatchAny))
+		case Matches("ALTER", "LANGUAGE", MatchAny):
 		COMPLETE_WITH("OWNER TO", "RENAME TO");
+			break;
 
 	/* ALTER LARGE OBJECT <oid> */
-	else if (Matches("ALTER", "LARGE", "OBJECT", MatchAny))
+		case Matches("ALTER", "LARGE", "OBJECT", MatchAny):
 		COMPLETE_WITH("OWNER TO");
+			break;
 
 	/* ALTER MATERIALIZED VIEW */
-	else if (Matches("ALTER", "MATERIALIZED", "VIEW"))
+		case Matches("ALTER", "MATERIALIZED", "VIEW"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_matviews,
 										"ALL IN TABLESPACE");
+			break;
 
 	/* ALTER USER,ROLE <name> */
-	else if (Matches("ALTER", "USER|ROLE", MatchAny) &&
-			 !TailMatches("USER", "MAPPING"))
+		case Matches("ALTER", "USER|ROLE", MatchAny):
+		if (!TailMatches("USER", "MAPPING"))
 		COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
 					  "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
 					  "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
 					  "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
 					  "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER",
 					  "VALID UNTIL", "WITH");
+			break;
 
 	/* ALTER USER,ROLE <name> WITH */
-	else if (Matches("ALTER", "USER|ROLE", MatchAny, "WITH"))
+		case Matches("ALTER", "USER|ROLE", MatchAny, "WITH"):
 		/* Similar to the above, but don't complete "WITH" again. */
 		COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
 					  "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
@@ -2319,210 +2475,254 @@ match_previous_words(const char *text, int start, int end,
 					  "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
 					  "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER",
 					  "VALID UNTIL");
+			break;
 
 	/* ALTER DEFAULT PRIVILEGES */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES"))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES"):
 		COMPLETE_WITH("FOR", "GRANT", "IN SCHEMA", "REVOKE");
+			break;
 	/* ALTER DEFAULT PRIVILEGES FOR */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR"):
 		COMPLETE_WITH("ROLE");
+			break;
 	/* ALTER DEFAULT PRIVILEGES IN */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN"):
 		COMPLETE_WITH("SCHEMA");
+			break;
 	/* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
-					 MatchAny))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", MatchAny):
 		COMPLETE_WITH("GRANT", "REVOKE", "IN SCHEMA");
+			break;
 	/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
-					 MatchAny))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", MatchAny):
 		COMPLETE_WITH("GRANT", "REVOKE", "FOR ROLE");
+			break;
 	/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
-					 MatchAny, "FOR"))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", MatchAny, "FOR"):
 		COMPLETE_WITH("ROLE");
+			break;
 	/* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
 	/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
-					 MatchAny, "IN", "SCHEMA", MatchAny) ||
-			 Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
-					 MatchAny, "FOR", "ROLE|USER", MatchAny))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", MatchAny, "IN", "SCHEMA", MatchAny):
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", MatchAny, "FOR", "ROLE|USER", MatchAny):
 		COMPLETE_WITH("GRANT", "REVOKE");
+			break;
 	/* ALTER DOMAIN <name> */
-	else if (Matches("ALTER", "DOMAIN", MatchAny))
+		case Matches("ALTER", "DOMAIN", MatchAny):
 		COMPLETE_WITH("ADD", "DROP", "OWNER TO", "RENAME", "SET",
 					  "VALIDATE CONSTRAINT");
+			break;
 	/* ALTER DOMAIN <sth> DROP */
-	else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP"))
+		case Matches("ALTER", "DOMAIN", MatchAny, "DROP"):
 		COMPLETE_WITH("CONSTRAINT", "DEFAULT", "NOT NULL");
+			break;
 	/* ALTER DOMAIN <sth> DROP|RENAME|VALIDATE CONSTRAINT */
-	else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"))
-	{
+		case Matches("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_constraint_of_type);
-	}
+			break;
 	/* ALTER DOMAIN <sth> RENAME */
-	else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME"))
+		case Matches("ALTER", "DOMAIN", MatchAny, "RENAME"):
 		COMPLETE_WITH("CONSTRAINT", "TO");
+			break;
 	/* ALTER DOMAIN <sth> RENAME CONSTRAINT <sth> */
-	else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny))
+		case Matches("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny):
 		COMPLETE_WITH("TO");
+			break;
 
 	/* ALTER DOMAIN <sth> SET */
-	else if (Matches("ALTER", "DOMAIN", MatchAny, "SET"))
+		case Matches("ALTER", "DOMAIN", MatchAny, "SET"):
 		COMPLETE_WITH("DEFAULT", "NOT NULL", "SCHEMA");
+			break;
 	/* ALTER SEQUENCE <name> */
-	else if (Matches("ALTER", "SEQUENCE", MatchAny))
+		case Matches("ALTER", "SEQUENCE", MatchAny):
 		COMPLETE_WITH("AS", "INCREMENT", "MINVALUE", "MAXVALUE", "RESTART",
 					  "START", "NO", "CACHE", "CYCLE", "SET", "OWNED BY",
 					  "OWNER TO", "RENAME TO");
+			break;
 	/* ALTER SEQUENCE <name> AS */
-	else if (TailMatches("ALTER", "SEQUENCE", MatchAny, "AS"))
+		case TailMatches("ALTER", "SEQUENCE", MatchAny, "AS"):
 		COMPLETE_WITH_CS("smallint", "integer", "bigint");
+			break;
 	/* ALTER SEQUENCE <name> NO */
-	else if (Matches("ALTER", "SEQUENCE", MatchAny, "NO"))
+		case Matches("ALTER", "SEQUENCE", MatchAny, "NO"):
 		COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
+			break;
 	/* ALTER SEQUENCE <name> SET */
-	else if (Matches("ALTER", "SEQUENCE", MatchAny, "SET"))
+		case Matches("ALTER", "SEQUENCE", MatchAny, "SET"):
 		COMPLETE_WITH("SCHEMA", "LOGGED", "UNLOGGED");
+			break;
 	/* ALTER SERVER <name> */
-	else if (Matches("ALTER", "SERVER", MatchAny))
+		case Matches("ALTER", "SERVER", MatchAny):
 		COMPLETE_WITH("VERSION", "OPTIONS", "OWNER TO", "RENAME TO");
+			break;
 	/* ALTER SERVER <name> VERSION <version> */
-	else if (Matches("ALTER", "SERVER", MatchAny, "VERSION", MatchAny))
+		case Matches("ALTER", "SERVER", MatchAny, "VERSION", MatchAny):
 		COMPLETE_WITH("OPTIONS");
+			break;
 	/* ALTER SYSTEM SET, RESET, RESET ALL */
-	else if (Matches("ALTER", "SYSTEM"))
+		case Matches("ALTER", "SYSTEM"):
 		COMPLETE_WITH("SET", "RESET");
-	else if (Matches("ALTER", "SYSTEM", "SET|RESET"))
+			break;
+		case Matches("ALTER", "SYSTEM", "SET|RESET"):
 		COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_alter_system_set_vars,
 										  "ALL");
-	else if (Matches("ALTER", "SYSTEM", "SET", MatchAny))
+			break;
+		case Matches("ALTER", "SYSTEM", "SET", MatchAny):
 		COMPLETE_WITH("TO");
+			break;
 	/* ALTER VIEW <name> */
-	else if (Matches("ALTER", "VIEW", MatchAny))
+		case Matches("ALTER", "VIEW", MatchAny):
 		COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME", "RESET", "SET");
+			break;
 	/* ALTER VIEW xxx RENAME */
-	else if (Matches("ALTER", "VIEW", MatchAny, "RENAME"))
+		case Matches("ALTER", "VIEW", MatchAny, "RENAME"):
 		COMPLETE_WITH_ATTR_PLUS(prev2_wd, "COLUMN", "TO");
-	else if (Matches("ALTER", "VIEW", MatchAny, "ALTER|RENAME", "COLUMN"))
+			break;
+		case Matches("ALTER", "VIEW", MatchAny, "ALTER|RENAME", "COLUMN"):
 		COMPLETE_WITH_ATTR(prev3_wd);
+			break;
 	/* ALTER VIEW xxx ALTER [ COLUMN ] yyy */
-	else if (Matches("ALTER", "VIEW", MatchAny, "ALTER", MatchAny) ||
-			 Matches("ALTER", "VIEW", MatchAny, "ALTER", "COLUMN", MatchAny))
+		case Matches("ALTER", "VIEW", MatchAny, "ALTER", MatchAny):
+		case Matches("ALTER", "VIEW", MatchAny, "ALTER", "COLUMN", MatchAny):
 		COMPLETE_WITH("SET DEFAULT", "DROP DEFAULT");
+			break;
 	/* ALTER VIEW xxx RENAME yyy */
-	else if (Matches("ALTER", "VIEW", MatchAny, "RENAME", MatchAnyExcept("TO")))
+		case Matches("ALTER", "VIEW", MatchAny, "RENAME", MatchAnyExcept("TO")):
 		COMPLETE_WITH("TO");
+			break;
 	/* ALTER VIEW xxx RENAME COLUMN yyy */
-	else if (Matches("ALTER", "VIEW", MatchAny, "RENAME", "COLUMN", MatchAnyExcept("TO")))
+		case Matches("ALTER", "VIEW", MatchAny, "RENAME", "COLUMN", MatchAnyExcept("TO")):
 		COMPLETE_WITH("TO");
+			break;
 	/* ALTER VIEW xxx RESET ( */
-	else if (Matches("ALTER", "VIEW", MatchAny, "RESET"))
+		case Matches("ALTER", "VIEW", MatchAny, "RESET"):
 		COMPLETE_WITH("(");
+			break;
 	/* Complete ALTER VIEW xxx SET with "(" or "SCHEMA" */
-	else if (Matches("ALTER", "VIEW", MatchAny, "SET"))
+		case Matches("ALTER", "VIEW", MatchAny, "SET"):
 		COMPLETE_WITH("(", "SCHEMA");
+			break;
 	/* ALTER VIEW xxx SET|RESET ( yyy [= zzz] ) */
-	else if (Matches("ALTER", "VIEW", MatchAny, "SET|RESET", "("))
+		case Matches("ALTER", "VIEW", MatchAny, "SET|RESET", "("):
 		COMPLETE_WITH_LIST(view_optional_parameters);
-	else if (Matches("ALTER", "VIEW", MatchAny, "SET", "(", MatchAny))
+			break;
+		case Matches("ALTER", "VIEW", MatchAny, "SET", "(", MatchAny):
 		COMPLETE_WITH("=");
-	else if (Matches("ALTER", "VIEW", MatchAny, "SET", "(", "check_option", "="))
+			break;
+		case Matches("ALTER", "VIEW", MatchAny, "SET", "(", "check_option", "="):
 		COMPLETE_WITH("local", "cascaded");
-	else if (Matches("ALTER", "VIEW", MatchAny, "SET", "(", "security_barrier|security_invoker", "="))
+			break;
+		case Matches("ALTER", "VIEW", MatchAny, "SET", "(", "security_barrier|security_invoker", "="):
 		COMPLETE_WITH("true", "false");
+			break;
 
 	/* ALTER MATERIALIZED VIEW <name> */
-	else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny))
+		case Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny):
 		COMPLETE_WITH("ALTER COLUMN", "CLUSTER ON", "DEPENDS ON EXTENSION",
 					  "NO DEPENDS ON EXTENSION", "OWNER TO", "RENAME",
 					  "RESET (", "SET");
+			break;
 	/* ALTER MATERIALIZED VIEW xxx RENAME */
-	else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "RENAME"))
+		case Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "RENAME"):
 		COMPLETE_WITH_ATTR_PLUS(prev2_wd, "COLUMN", "TO");
-	else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "ALTER|RENAME", "COLUMN"))
+			break;
+		case Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "ALTER|RENAME", "COLUMN"):
 		COMPLETE_WITH_ATTR(prev3_wd);
+			break;
 	/* ALTER MATERIALIZED VIEW xxx RENAME yyy */
-	else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "RENAME", MatchAnyExcept("TO")))
+		case Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "RENAME", MatchAnyExcept("TO")):
 		COMPLETE_WITH("TO");
+			break;
 	/* ALTER MATERIALIZED VIEW xxx RENAME COLUMN yyy */
-	else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "RENAME", "COLUMN", MatchAnyExcept("TO")))
+		case Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "RENAME", "COLUMN", MatchAnyExcept("TO")):
 		COMPLETE_WITH("TO");
+			break;
 	/* ALTER MATERIALIZED VIEW xxx SET */
-	else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "SET"))
+		case Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "SET"):
 		COMPLETE_WITH("(", "ACCESS METHOD", "SCHEMA", "TABLESPACE", "WITHOUT CLUSTER");
+			break;
 	/* ALTER MATERIALIZED VIEW xxx SET ACCESS METHOD */
-	else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "SET", "ACCESS", "METHOD"))
+		case Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "SET", "ACCESS", "METHOD"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_table_access_methods);
+			break;
 
 	/* ALTER POLICY <name> */
-	else if (Matches("ALTER", "POLICY"))
+		case Matches("ALTER", "POLICY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_policies);
+			break;
 	/* ALTER POLICY <name> ON */
-	else if (Matches("ALTER", "POLICY", MatchAny))
+		case Matches("ALTER", "POLICY", MatchAny):
 		COMPLETE_WITH("ON");
+			break;
 	/* ALTER POLICY <name> ON <table> */
-	else if (Matches("ALTER", "POLICY", MatchAny, "ON"))
-	{
+		case Matches("ALTER", "POLICY", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_policy);
-	}
+			break;
 	/* ALTER POLICY <name> ON <table> - show options */
-	else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny))
+		case Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny):
 		COMPLETE_WITH("RENAME TO", "TO", "USING (", "WITH CHECK (");
+			break;
 	/* ALTER POLICY <name> ON <table> TO <role> */
-	else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"))
+		case Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 Keywords_for_list_of_grant_roles);
+			break;
 	/* ALTER POLICY <name> ON <table> USING ( */
-	else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"))
+		case Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"):
 		COMPLETE_WITH("(");
+			break;
 	/* ALTER POLICY <name> ON <table> WITH CHECK ( */
-	else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"))
+		case Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"):
 		COMPLETE_WITH("(");
+			break;
 
 	/* ALTER RULE <name>, add ON */
-	else if (Matches("ALTER", "RULE", MatchAny))
+		case Matches("ALTER", "RULE", MatchAny):
 		COMPLETE_WITH("ON");
+			break;
 
 	/* If we have ALTER RULE <name> ON, then add the correct tablename */
-	else if (Matches("ALTER", "RULE", MatchAny, "ON"))
-	{
+		case Matches("ALTER", "RULE", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_rule);
-	}
+			break;
 
 	/* ALTER RULE <name> ON <name> */
-	else if (Matches("ALTER", "RULE", MatchAny, "ON", MatchAny))
+		case Matches("ALTER", "RULE", MatchAny, "ON", MatchAny):
 		COMPLETE_WITH("RENAME TO");
+			break;
 
 	/* ALTER STATISTICS <name> */
-	else if (Matches("ALTER", "STATISTICS", MatchAny))
+		case Matches("ALTER", "STATISTICS", MatchAny):
 		COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA", "SET STATISTICS");
+			break;
 	/* ALTER STATISTICS <name> SET */
-	else if (Matches("ALTER", "STATISTICS", MatchAny, "SET"))
+		case Matches("ALTER", "STATISTICS", MatchAny, "SET"):
 		COMPLETE_WITH("SCHEMA", "STATISTICS");
+			break;
 
 	/* ALTER TRIGGER <name>, add ON */
-	else if (Matches("ALTER", "TRIGGER", MatchAny))
+		case Matches("ALTER", "TRIGGER", MatchAny):
 		COMPLETE_WITH("ON");
+			break;
 
-	else if (Matches("ALTER", "TRIGGER", MatchAny, "ON"))
-	{
+		case Matches("ALTER", "TRIGGER", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_trigger);
-	}
+			break;
 
 	/* ALTER TRIGGER <name> ON <name> */
-	else if (Matches("ALTER", "TRIGGER", MatchAny, "ON", MatchAny))
+		case Matches("ALTER", "TRIGGER", MatchAny, "ON", MatchAny):
 		COMPLETE_WITH("RENAME TO", "DEPENDS ON EXTENSION",
 					  "NO DEPENDS ON EXTENSION");
+			break;
 
 	/*
 	 * If we detect ALTER TABLE <name>, suggest sub commands
 	 */
-	else if (Matches("ALTER", "TABLE", MatchAny))
+		case Matches("ALTER", "TABLE", MatchAny):
 		COMPLETE_WITH("ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP",
 					  "ENABLE", "INHERIT", "NO", "RENAME", "RESET",
 					  "OWNER TO", "SET", "VALIDATE CONSTRAINT",
@@ -2530,366 +2730,412 @@ match_previous_words(const char *text, int start, int end,
 					  "DETACH PARTITION", "FORCE ROW LEVEL SECURITY",
 					  "SPLIT PARTITION", "MERGE PARTITIONS (",
 					  "OF", "NOT OF");
+			break;
 	/* ALTER TABLE xxx ADD */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ADD"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "ADD"):
 		/* make sure to keep this list and the !Matches() below in sync */
 		COMPLETE_WITH("COLUMN", "CONSTRAINT", "CHECK", "UNIQUE", "PRIMARY KEY",
 					  "EXCLUDE", "FOREIGN KEY");
-	}
+			break;
 	/* ALTER TABLE xxx ADD [COLUMN] yyy */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "COLUMN", MatchAny) ||
-			 (Matches("ALTER", "TABLE", MatchAny, "ADD", MatchAny) &&
-			  !Matches("ALTER", "TABLE", MatchAny, "ADD", "COLUMN|CONSTRAINT|CHECK|UNIQUE|PRIMARY|EXCLUDE|FOREIGN")))
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "COLUMN", MatchAny):
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", MatchAnyExcept("COLUMN|CONSTRAINT|CHECK|UNIQUE|PRIMARY|EXCLUDE|FOREIGN")):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
+			break;
 	/* ALTER TABLE xxx ADD CONSTRAINT yyy */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny))
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny):
 		COMPLETE_WITH("CHECK", "UNIQUE", "PRIMARY KEY", "EXCLUDE", "FOREIGN KEY");
+			break;
 	/* ALTER TABLE xxx ADD [CONSTRAINT yyy] (PRIMARY KEY|UNIQUE) */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "PRIMARY", "KEY") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ADD", "UNIQUE") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "PRIMARY", "KEY") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "UNIQUE"))
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "PRIMARY", "KEY"):
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "UNIQUE"):
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "PRIMARY", "KEY"):
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "UNIQUE"):
 		COMPLETE_WITH("(", "USING INDEX");
+			break;
 	/* ALTER TABLE xxx ADD PRIMARY KEY USING INDEX */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "PRIMARY", "KEY", "USING", "INDEX"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "PRIMARY", "KEY", "USING", "INDEX"):
 		set_completion_reference(prev6_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_unique_index_of_table);
-	}
+			break;
 	/* ALTER TABLE xxx ADD UNIQUE USING INDEX */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "UNIQUE", "USING", "INDEX"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "UNIQUE", "USING", "INDEX"):
 		set_completion_reference(prev5_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_unique_index_of_table);
-	}
+			break;
 	/* ALTER TABLE xxx ADD CONSTRAINT yyy PRIMARY KEY USING INDEX */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny,
-					 "PRIMARY", "KEY", "USING", "INDEX"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "PRIMARY", "KEY", "USING", "INDEX"):
 		set_completion_reference(prev8_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_unique_index_of_table);
-	}
+			break;
 	/* ALTER TABLE xxx ADD CONSTRAINT yyy UNIQUE USING INDEX */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny,
-					 "UNIQUE", "USING", "INDEX"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "UNIQUE", "USING", "INDEX"):
 		set_completion_reference(prev7_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_unique_index_of_table);
-	}
+			break;
 	/* ALTER TABLE xxx ENABLE */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE"))
+		case Matches("ALTER", "TABLE", MatchAny, "ENABLE"):
 		COMPLETE_WITH("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
 					  "TRIGGER");
-	else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"):
 		COMPLETE_WITH("RULE", "TRIGGER");
-	else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
-	{
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_rule_of_table);
-	}
-	else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
-	{
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"):
 		set_completion_reference(prev4_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_rule_of_table);
-	}
-	else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
-	{
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_trigger_of_table);
-	}
-	else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
-	{
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"):
 		set_completion_reference(prev4_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_trigger_of_table);
-	}
+			break;
 	/* ALTER TABLE xxx INHERIT */
-	else if (Matches("ALTER", "TABLE", MatchAny, "INHERIT"))
+		case Matches("ALTER", "TABLE", MatchAny, "INHERIT"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 	/* ALTER TABLE xxx NO */
-	else if (Matches("ALTER", "TABLE", MatchAny, "NO"))
+		case Matches("ALTER", "TABLE", MatchAny, "NO"):
 		COMPLETE_WITH("FORCE ROW LEVEL SECURITY", "INHERIT");
+			break;
 	/* ALTER TABLE xxx NO INHERIT */
-	else if (Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
+		case Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 	/* ALTER TABLE xxx DISABLE */
-	else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE"))
+		case Matches("ALTER", "TABLE", MatchAny, "DISABLE"):
 		COMPLETE_WITH("ROW LEVEL SECURITY", "RULE", "TRIGGER");
-	else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
-	{
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_rule_of_table);
-	}
-	else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
-	{
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_trigger_of_table);
-	}
+			break;
 
 	/* ALTER TABLE xxx ALTER */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER"):
 		COMPLETE_WITH_ATTR_PLUS(prev2_wd, "COLUMN", "CONSTRAINT");
+			break;
 
 	/* ALTER TABLE xxx RENAME */
-	else if (Matches("ALTER", "TABLE", MatchAny, "RENAME"))
+		case Matches("ALTER", "TABLE", MatchAny, "RENAME"):
 		COMPLETE_WITH_ATTR_PLUS(prev2_wd, "COLUMN", "CONSTRAINT", "TO");
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"):
 		COMPLETE_WITH_ATTR(prev3_wd);
+			break;
 
 	/* ALTER TABLE xxx RENAME yyy */
-	else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
+		case Matches("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")):
 		COMPLETE_WITH("TO");
+			break;
 
 	/* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
-	else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
+		case Matches("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")):
 		COMPLETE_WITH("TO");
+			break;
 
 	/* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
-	else if (Matches("ALTER", "TABLE", MatchAny, "DROP"))
+		case Matches("ALTER", "TABLE", MatchAny, "DROP"):
 		COMPLETE_WITH("COLUMN", "CONSTRAINT");
+			break;
 	/* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
-	else if (Matches("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
+		case Matches("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"):
 		COMPLETE_WITH_ATTR(prev3_wd);
+			break;
 	/* ALTER TABLE <sth> ALTER|DROP|RENAME CONSTRAINT <constraint> */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME", "CONSTRAINT"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME", "CONSTRAINT"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_constraint_of_table);
-	}
+			break;
 	/* ALTER TABLE <sth> VALIDATE CONSTRAINT <non-validated constraint> */
-	else if (Matches("ALTER", "TABLE", MatchAny, "VALIDATE", "CONSTRAINT"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "VALIDATE", "CONSTRAINT"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_constraint_of_table_not_validated);
-	}
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny):
 		COMPLETE_WITH("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> ADD */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD"):
 		COMPLETE_WITH("GENERATED");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> ADD GENERATED */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED"):
 		COMPLETE_WITH("ALWAYS", "BY DEFAULT");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> ADD GENERATED */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED", "ALWAYS") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED", "ALWAYS") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED", "BY", "DEFAULT") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED", "BY", "DEFAULT"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED", "ALWAYS"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED", "ALWAYS"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED", "BY", "DEFAULT"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED", "BY", "DEFAULT"):
 		COMPLETE_WITH("AS IDENTITY");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"):
 		COMPLETE_WITH("(", "COMPRESSION", "DATA TYPE", "DEFAULT", "EXPRESSION", "GENERATED", "NOT NULL",
 					  "STATISTICS", "STORAGE",
 		/* a subset of ALTER SEQUENCE options */
 					  "INCREMENT", "MINVALUE", "MAXVALUE", "START", "NO", "CACHE", "CYCLE");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "("):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("):
 		COMPLETE_WITH("n_distinct", "n_distinct_inherited");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET COMPRESSION */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "COMPRESSION") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "COMPRESSION"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "COMPRESSION"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "COMPRESSION"):
 		COMPLETE_WITH("DEFAULT", "PGLZ", "LZ4");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET EXPRESSION */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "EXPRESSION") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "EXPRESSION"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "EXPRESSION"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "EXPRESSION"):
 		COMPLETE_WITH("AS");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET EXPRESSION AS */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "EXPRESSION", "AS") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "EXPRESSION", "AS"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "EXPRESSION", "AS"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "EXPRESSION", "AS"):
 		COMPLETE_WITH("(");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET GENERATED */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "GENERATED") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "GENERATED"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "GENERATED"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "GENERATED"):
 		COMPLETE_WITH("ALWAYS", "BY DEFAULT");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET NO */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "NO") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "NO"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "NO"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "NO"):
 		COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"):
 		COMPLETE_WITH("DEFAULT", "PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> SET STATISTICS */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STATISTICS"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STATISTICS"):
 		/* Enforce no completion here, as an integer has to be specified */
-	}
+			break;
 	/* ALTER TABLE ALTER [COLUMN] <foo> DROP */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
-			 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP"):
+		case Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"):
 		COMPLETE_WITH("DEFAULT", "EXPRESSION", "IDENTITY", "NOT NULL");
-	else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER"))
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "CLUSTER"):
 		COMPLETE_WITH("ON");
-	else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
-	{
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_index_of_table);
-	}
+			break;
 	/* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
-	else if (Matches("ALTER", "TABLE", MatchAny, "SET"))
+		case Matches("ALTER", "TABLE", MatchAny, "SET"):
 		COMPLETE_WITH("(", "ACCESS METHOD", "LOGGED", "SCHEMA",
 					  "TABLESPACE", "UNLOGGED", "WITH", "WITHOUT");
+			break;
 
 	/*
 	 * If we have ALTER TABLE <sth> SET ACCESS METHOD provide a list of table
 	 * AMs.
 	 */
-	else if (Matches("ALTER", "TABLE", MatchAny, "SET", "ACCESS", "METHOD"))
+		case Matches("ALTER", "TABLE", MatchAny, "SET", "ACCESS", "METHOD"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_table_access_methods,
 								 "DEFAULT");
+			break;
 
 	/*
 	 * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
 	 * tablespaces
 	 */
-	else if (Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
+		case Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
+			break;
 	/* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
-	else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
+		case Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"):
 		COMPLETE_WITH("CLUSTER", "OIDS");
+			break;
 	/* ALTER TABLE <foo> RESET */
-	else if (Matches("ALTER", "TABLE", MatchAny, "RESET"))
+		case Matches("ALTER", "TABLE", MatchAny, "RESET"):
 		COMPLETE_WITH("(");
+			break;
 	/* ALTER TABLE <foo> SET|RESET ( */
-	else if (Matches("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
+		case Matches("ALTER", "TABLE", MatchAny, "SET|RESET", "("):
 		COMPLETE_WITH_LIST(table_storage_parameters);
-	else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
-	{
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"):
 		set_completion_reference(prev5_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_index_of_table);
-	}
-	else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"):
 		COMPLETE_WITH("INDEX");
-	else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"):
 		COMPLETE_WITH("FULL", "NOTHING", "DEFAULT", "USING");
-	else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA"))
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "REPLICA"):
 		COMPLETE_WITH("IDENTITY");
+			break;
 
 	/*
 	 * If we have ALTER TABLE <foo> ATTACH PARTITION, provide a list of
 	 * tables.
 	 */
-	else if (Matches("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION"))
+		case Matches("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 	/* Limited completion support for partition bound specification */
-	else if (TailMatches("ATTACH", "PARTITION", MatchAny))
+		case TailMatches("ATTACH", "PARTITION", MatchAny):
 		COMPLETE_WITH("FOR VALUES", "DEFAULT");
-	else if (TailMatches("FOR", "VALUES"))
+			break;
+		case TailMatches("FOR", "VALUES"):
 		COMPLETE_WITH("FROM (", "IN (", "WITH (");
+			break;
 
 	/*
 	 * If we have ALTER TABLE <foo> DETACH|SPLIT PARTITION, provide a list of
 	 * partitions of <foo>.
 	 */
-	else if (Matches("ALTER", "TABLE", MatchAny, "DETACH|SPLIT", "PARTITION"))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "DETACH|SPLIT", "PARTITION"):
 		set_completion_reference(prev3_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_partition_of_table);
-	}
-	else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION", MatchAny))
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION", MatchAny):
 		COMPLETE_WITH("CONCURRENTLY", "FINALIZE");
+			break;
 
 	/* ALTER TABLE <name> SPLIT PARTITION <name> */
-	else if (Matches("ALTER", "TABLE", MatchAny, "SPLIT", "PARTITION", MatchAny))
+		case Matches("ALTER", "TABLE", MatchAny, "SPLIT", "PARTITION", MatchAny):
 		COMPLETE_WITH("INTO ( PARTITION");
+			break;
 
 	/* ALTER TABLE <name> MERGE PARTITIONS ( */
-	else if (Matches("ALTER", "TABLE", MatchAny, "MERGE", "PARTITIONS", "("))
-	{
+		case Matches("ALTER", "TABLE", MatchAny, "MERGE", "PARTITIONS", "("):
 		set_completion_reference(prev4_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_partition_of_table);
-	}
-	else if (Matches("ALTER", "TABLE", MatchAny, "MERGE", "PARTITIONS", "(*)"))
+			break;
+		case Matches("ALTER", "TABLE", MatchAny, "MERGE", "PARTITIONS", "(*)"):
 		COMPLETE_WITH("INTO");
+			break;
 
 	/* ALTER TABLE <name> OF */
-	else if (Matches("ALTER", "TABLE", MatchAny, "OF"))
+		case Matches("ALTER", "TABLE", MatchAny, "OF"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes);
+			break;
 
 	/* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
-	else if (Matches("ALTER", "TABLESPACE", MatchAny))
+		case Matches("ALTER", "TABLESPACE", MatchAny):
 		COMPLETE_WITH("RENAME TO", "OWNER TO", "SET", "RESET");
+			break;
 	/* ALTER TABLESPACE <foo> SET|RESET */
-	else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
+		case Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET"):
 		COMPLETE_WITH("(");
+			break;
 	/* ALTER TABLESPACE <foo> SET|RESET ( */
-	else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
+		case Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("):
 		COMPLETE_WITH("seq_page_cost", "random_page_cost",
 					  "effective_io_concurrency", "maintenance_io_concurrency");
+			break;
 
 	/* ALTER TEXT SEARCH */
-	else if (Matches("ALTER", "TEXT", "SEARCH"))
+		case Matches("ALTER", "TEXT", "SEARCH"):
 		COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
-	else if (Matches("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
+			break;
+		case Matches("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny):
 		COMPLETE_WITH("RENAME TO", "SET SCHEMA");
-	else if (Matches("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
+			break;
+		case Matches("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny):
 		COMPLETE_WITH("(", "OWNER TO", "RENAME TO", "SET SCHEMA");
-	else if (Matches("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
+			break;
+		case Matches("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny):
 		COMPLETE_WITH("ADD MAPPING FOR", "ALTER MAPPING",
 					  "DROP MAPPING FOR",
 					  "OWNER TO", "RENAME TO", "SET SCHEMA");
+			break;
 
 	/* complete ALTER TYPE <foo> with actions */
-	else if (Matches("ALTER", "TYPE", MatchAny))
+		case Matches("ALTER", "TYPE", MatchAny):
 		COMPLETE_WITH("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
 					  "DROP ATTRIBUTE",
 					  "OWNER TO", "RENAME", "SET SCHEMA", "SET (");
+			break;
 	/* complete ALTER TYPE <foo> ADD with actions */
-	else if (Matches("ALTER", "TYPE", MatchAny, "ADD"))
+		case Matches("ALTER", "TYPE", MatchAny, "ADD"):
 		COMPLETE_WITH("ATTRIBUTE", "VALUE");
+			break;
 	/* ALTER TYPE <foo> RENAME	*/
-	else if (Matches("ALTER", "TYPE", MatchAny, "RENAME"))
+		case Matches("ALTER", "TYPE", MatchAny, "RENAME"):
 		COMPLETE_WITH("ATTRIBUTE", "TO", "VALUE");
+			break;
 	/* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
-	else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
+		case Matches("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny):
 		COMPLETE_WITH("TO");
+			break;
 
 	/*
 	 * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
 	 * of attributes
 	 */
-	else if (Matches("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
+		case Matches("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"):
 		COMPLETE_WITH_ATTR(prev3_wd);
+			break;
 	/* ALTER TYPE ALTER ATTRIBUTE <foo> */
-	else if (Matches("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
+		case Matches("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny):
 		COMPLETE_WITH("TYPE");
+			break;
 	/* complete ALTER TYPE <sth> RENAME VALUE with list of enum values */
-	else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
+		case Matches("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"):
 		COMPLETE_WITH_ENUM_VALUE(prev3_wd);
+			break;
 	/* ALTER TYPE <foo> SET */
-	else if (Matches("ALTER", "TYPE", MatchAny, "SET"))
+		case Matches("ALTER", "TYPE", MatchAny, "SET"):
 		COMPLETE_WITH("(", "SCHEMA");
+			break;
 	/* complete ALTER TYPE <foo> SET ( with settable properties */
-	else if (Matches("ALTER", "TYPE", MatchAny, "SET", "("))
+		case Matches("ALTER", "TYPE", MatchAny, "SET", "("):
 		COMPLETE_WITH("ANALYZE", "RECEIVE", "SEND", "STORAGE", "SUBSCRIPT",
 					  "TYPMOD_IN", "TYPMOD_OUT");
+			break;
 
 	/* complete ALTER GROUP <foo> */
-	else if (Matches("ALTER", "GROUP", MatchAny))
+		case Matches("ALTER", "GROUP", MatchAny):
 		COMPLETE_WITH("ADD USER", "DROP USER", "RENAME TO");
+			break;
 	/* complete ALTER GROUP <foo> ADD|DROP with USER */
-	else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP"))
+		case Matches("ALTER", "GROUP", MatchAny, "ADD|DROP"):
 		COMPLETE_WITH("USER");
+			break;
 	/* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
-	else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
+		case Matches("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
+			break;
 
 /*
  * ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
  * ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]
  */
-	else if (Matches("ANALYZE"))
+		case Matches("ANALYZE"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_analyzables,
 										"VERBOSE");
-	else if (HeadMatches("ANALYZE", "(*") &&
-			 !HeadMatches("ANALYZE", "(*)"))
+			break;
+		case HeadMatches("ANALYZE", "(*"):
+		if (!HeadMatches("ANALYZE", "(*)"))
 	{
 		/*
 		 * This fires if we're in an unfinished parenthesized option list.
@@ -2901,60 +3147,75 @@ match_previous_words(const char *text, int start, int end,
 		else if (TailMatches("VERBOSE|SKIP_LOCKED"))
 			COMPLETE_WITH("ON", "OFF");
 	}
-	else if (Matches("ANALYZE", MatchAnyN, "("))
+			break;
+		case Matches("ANALYZE", MatchAnyN, "("):
 		/* "ANALYZE (" should be caught above, so assume we want columns */
 		COMPLETE_WITH_ATTR(prev2_wd);
-	else if (HeadMatches("ANALYZE"))
+			break;
+		case HeadMatches("ANALYZE"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables);
+			break;
 
 /* BEGIN */
-	else if (Matches("BEGIN"))
+		case Matches("BEGIN"):
 		COMPLETE_WITH("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
+			break;
 /* END, ABORT */
-	else if (Matches("END|ABORT"))
+		case Matches("END|ABORT"):
 		COMPLETE_WITH("AND", "WORK", "TRANSACTION");
+			break;
 /* COMMIT */
-	else if (Matches("COMMIT"))
+		case Matches("COMMIT"):
 		COMPLETE_WITH("AND", "WORK", "TRANSACTION", "PREPARED");
+			break;
 /* RELEASE SAVEPOINT */
-	else if (Matches("RELEASE"))
+		case Matches("RELEASE"):
 		COMPLETE_WITH("SAVEPOINT");
+			break;
 /* ROLLBACK */
-	else if (Matches("ROLLBACK"))
+		case Matches("ROLLBACK"):
 		COMPLETE_WITH("AND", "WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
-	else if (Matches("ABORT|END|COMMIT|ROLLBACK", "AND"))
+			break;
+		case Matches("ABORT|END|COMMIT|ROLLBACK", "AND"):
 		COMPLETE_WITH("CHAIN");
+			break;
 /* CALL */
-	else if (Matches("CALL"))
+		case Matches("CALL"):
 		COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures);
-	else if (Matches("CALL", MatchAny))
+			break;
+		case Matches("CALL", MatchAny):
 		COMPLETE_WITH("(");
+			break;
 /* CLOSE */
-	else if (Matches("CLOSE"))
+		case Matches("CLOSE"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,
 								 "ALL");
+			break;
 /* CLUSTER */
-	else if (Matches("CLUSTER"))
+		case Matches("CLUSTER"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_clusterables,
 										"VERBOSE");
-	else if (Matches("CLUSTER", "VERBOSE") ||
-			 Matches("CLUSTER", "(*)"))
+			break;
+		case Matches("CLUSTER", "VERBOSE"):
+		case Matches("CLUSTER", "(*)"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables);
+			break;
 	/* If we have CLUSTER <sth>, then add "USING" */
-	else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON|(|(*)")))
+		case Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON|(|(*)")):
 		COMPLETE_WITH("USING");
+			break;
 	/* If we have CLUSTER VERBOSE <sth>, then add "USING" */
-	else if (Matches("CLUSTER", "VERBOSE|(*)", MatchAny))
+		case Matches("CLUSTER", "VERBOSE|(*)", MatchAny):
 		COMPLETE_WITH("USING");
+			break;
 	/* If we have CLUSTER <sth> USING, then add the index as well */
-	else if (Matches("CLUSTER", MatchAny, "USING") ||
-			 Matches("CLUSTER", "VERBOSE|(*)", MatchAny, "USING"))
-	{
+		case Matches("CLUSTER", MatchAny, "USING"):
+		case Matches("CLUSTER", "VERBOSE|(*)", MatchAny, "USING"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_index_of_table);
-	}
-	else if (HeadMatches("CLUSTER", "(*") &&
-			 !HeadMatches("CLUSTER", "(*)"))
+			break;
+		case HeadMatches("CLUSTER", "(*"):
+		if (!HeadMatches("CLUSTER", "(*)"))
 	{
 		/*
 		 * This fires if we're in an unfinished parenthesized option list.
@@ -2964,11 +3225,13 @@ match_previous_words(const char *text, int start, int end,
 		if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
 			COMPLETE_WITH("VERBOSE");
 	}
+			break;
 
 /* COMMENT */
-	else if (Matches("COMMENT"))
+		case Matches("COMMENT"):
 		COMPLETE_WITH("ON");
-	else if (Matches("COMMENT", "ON"))
+			break;
+		case Matches("COMMENT", "ON"):
 		COMPLETE_WITH("ACCESS METHOD", "AGGREGATE", "CAST", "COLLATION",
 					  "COLUMN", "CONSTRAINT", "CONVERSION", "DATABASE",
 					  "DOMAIN", "EXTENSION", "EVENT TRIGGER",
@@ -2980,77 +3243,94 @@ match_previous_words(const char *text, int start, int end,
 					  "STATISTICS", "SUBSCRIPTION", "TABLE",
 					  "TABLESPACE", "TEXT SEARCH", "TRANSFORM FOR",
 					  "TRIGGER", "TYPE", "VIEW");
-	else if (Matches("COMMENT", "ON", "ACCESS", "METHOD"))
+			break;
+		case Matches("COMMENT", "ON", "ACCESS", "METHOD"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
-	else if (Matches("COMMENT", "ON", "CONSTRAINT"))
+			break;
+		case Matches("COMMENT", "ON", "CONSTRAINT"):
 		COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
-	else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny))
+			break;
+		case Matches("COMMENT", "ON", "CONSTRAINT", MatchAny):
 		COMPLETE_WITH("ON");
-	else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
-	{
+			break;
+		case Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables_for_constraint,
 										"DOMAIN");
-	}
-	else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON", "DOMAIN"))
+			break;
+		case Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON", "DOMAIN"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains);
-	else if (Matches("COMMENT", "ON", "EVENT", "TRIGGER"))
+			break;
+		case Matches("COMMENT", "ON", "EVENT", "TRIGGER"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
-	else if (Matches("COMMENT", "ON", "FOREIGN"))
+			break;
+		case Matches("COMMENT", "ON", "FOREIGN"):
 		COMPLETE_WITH("DATA WRAPPER", "TABLE");
-	else if (Matches("COMMENT", "ON", "FOREIGN", "TABLE"))
+			break;
+		case Matches("COMMENT", "ON", "FOREIGN", "TABLE"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables);
-	else if (Matches("COMMENT", "ON", "MATERIALIZED", "VIEW"))
+			break;
+		case Matches("COMMENT", "ON", "MATERIALIZED", "VIEW"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
-	else if (Matches("COMMENT", "ON", "POLICY"))
+			break;
+		case Matches("COMMENT", "ON", "POLICY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_policies);
-	else if (Matches("COMMENT", "ON", "POLICY", MatchAny))
+			break;
+		case Matches("COMMENT", "ON", "POLICY", MatchAny):
 		COMPLETE_WITH("ON");
-	else if (Matches("COMMENT", "ON", "POLICY", MatchAny, "ON"))
-	{
+			break;
+		case Matches("COMMENT", "ON", "POLICY", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_policy);
-	}
-	else if (Matches("COMMENT", "ON", "PROCEDURAL", "LANGUAGE"))
+			break;
+		case Matches("COMMENT", "ON", "PROCEDURAL", "LANGUAGE"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_languages);
-	else if (Matches("COMMENT", "ON", "RULE", MatchAny))
+			break;
+		case Matches("COMMENT", "ON", "RULE", MatchAny):
 		COMPLETE_WITH("ON");
-	else if (Matches("COMMENT", "ON", "RULE", MatchAny, "ON"))
-	{
+			break;
+		case Matches("COMMENT", "ON", "RULE", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_rule);
-	}
-	else if (Matches("COMMENT", "ON", "TEXT", "SEARCH"))
+			break;
+		case Matches("COMMENT", "ON", "TEXT", "SEARCH"):
 		COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
-	else if (Matches("COMMENT", "ON", "TEXT", "SEARCH", "CONFIGURATION"))
+			break;
+		case Matches("COMMENT", "ON", "TEXT", "SEARCH", "CONFIGURATION"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_configurations);
-	else if (Matches("COMMENT", "ON", "TEXT", "SEARCH", "DICTIONARY"))
+			break;
+		case Matches("COMMENT", "ON", "TEXT", "SEARCH", "DICTIONARY"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_dictionaries);
-	else if (Matches("COMMENT", "ON", "TEXT", "SEARCH", "PARSER"))
+			break;
+		case Matches("COMMENT", "ON", "TEXT", "SEARCH", "PARSER"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_parsers);
-	else if (Matches("COMMENT", "ON", "TEXT", "SEARCH", "TEMPLATE"))
+			break;
+		case Matches("COMMENT", "ON", "TEXT", "SEARCH", "TEMPLATE"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_templates);
-	else if (Matches("COMMENT", "ON", "TRANSFORM", "FOR"))
+			break;
+		case Matches("COMMENT", "ON", "TRANSFORM", "FOR"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
-	else if (Matches("COMMENT", "ON", "TRANSFORM", "FOR", MatchAny))
+			break;
+		case Matches("COMMENT", "ON", "TRANSFORM", "FOR", MatchAny):
 		COMPLETE_WITH("LANGUAGE");
-	else if (Matches("COMMENT", "ON", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"))
-	{
+			break;
+		case Matches("COMMENT", "ON", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_QUERY(Query_for_list_of_languages);
-	}
-	else if (Matches("COMMENT", "ON", "TRIGGER", MatchAny))
+			break;
+		case Matches("COMMENT", "ON", "TRIGGER", MatchAny):
 		COMPLETE_WITH("ON");
-	else if (Matches("COMMENT", "ON", "TRIGGER", MatchAny, "ON"))
-	{
+			break;
+		case Matches("COMMENT", "ON", "TRIGGER", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_trigger);
-	}
-	else if (Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
-			 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
-			 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")) ||
-			 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
+			break;
+		case Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")):
+		case Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")):
+		case Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")):
+		case Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")):
 		COMPLETE_WITH("IS");
+			break;
 
 /* COPY */
 
@@ -3058,77 +3338,89 @@ match_previous_words(const char *text, int start, int end,
 	 * If we have COPY, offer list of tables or "(" (Also cover the analogous
 	 * backslash command).
 	 */
-	else if (Matches("COPY|\\copy"))
+		case Matches("COPY|\\copy"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables, "(");
+			break;
 	/* Complete COPY ( with legal query commands */
-	else if (Matches("COPY|\\copy", "("))
+		case Matches("COPY|\\copy", "("):
 		COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT INTO", "UPDATE", "DELETE FROM", "WITH");
+			break;
 	/* Complete COPY <sth> */
-	else if (Matches("COPY|\\copy", MatchAny))
+		case Matches("COPY|\\copy", MatchAny):
 		COMPLETE_WITH("FROM", "TO");
+			break;
 	/* Complete COPY <sth> FROM|TO with filename */
-	else if (Matches("COPY", MatchAny, "FROM|TO"))
-	{
+		case Matches("COPY", MatchAny, "FROM|TO"):
 		completion_charp = "";
 		completion_force_quote = true;	/* COPY requires quoted filename */
 		matches = rl_completion_matches(text, complete_from_files);
-	}
-	else if (Matches("\\copy", MatchAny, "FROM|TO"))
-	{
+			break;
+		case Matches("\\copy", MatchAny, "FROM|TO"):
 		completion_charp = "";
 		completion_force_quote = false;
 		matches = rl_completion_matches(text, complete_from_files);
-	}
+			break;
 
 	/* Complete COPY <sth> TO <sth> */
-	else if (Matches("COPY|\\copy", MatchAny, "TO", MatchAny))
+		case Matches("COPY|\\copy", MatchAny, "TO", MatchAny):
 		COMPLETE_WITH("WITH (");
+			break;
 
 	/* Complete COPY <sth> FROM <sth> */
-	else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAny))
+		case Matches("COPY|\\copy", MatchAny, "FROM", MatchAny):
 		COMPLETE_WITH("WITH (", "WHERE");
+			break;
 
 	/* Complete COPY <sth> FROM|TO filename WITH ( */
-	else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
+		case Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("):
 		COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
 					  "HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
 					  "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING", "DEFAULT",
 					  "ON_ERROR", "LOG_VERBOSITY");
+			break;
 
 	/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
-	else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
+		case Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"):
 		COMPLETE_WITH("binary", "csv", "text");
+			break;
 
 	/* Complete COPY <sth> FROM filename WITH (ON_ERROR */
-	else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "ON_ERROR"))
+		case Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "ON_ERROR"):
 		COMPLETE_WITH("stop", "ignore");
+			break;
 
 	/* Complete COPY <sth> FROM filename WITH (LOG_VERBOSITY */
-	else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "LOG_VERBOSITY"))
+		case Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "LOG_VERBOSITY"):
 		COMPLETE_WITH("default", "verbose");
+			break;
 
 	/* Complete COPY <sth> FROM <sth> WITH (<options>) */
-	else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAny, "WITH", MatchAny))
+		case Matches("COPY|\\copy", MatchAny, "FROM", MatchAny, "WITH", MatchAny):
 		COMPLETE_WITH("WHERE");
+			break;
 
 	/* CREATE ACCESS METHOD */
 	/* Complete "CREATE ACCESS METHOD <name>" */
-	else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny))
+		case Matches("CREATE", "ACCESS", "METHOD", MatchAny):
 		COMPLETE_WITH("TYPE");
+			break;
 	/* Complete "CREATE ACCESS METHOD <name> TYPE" */
-	else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
+		case Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"):
 		COMPLETE_WITH("INDEX", "TABLE");
+			break;
 	/* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
-	else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
+		case Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny):
 		COMPLETE_WITH("HANDLER");
+			break;
 
 	/* CREATE COLLATION */
-	else if (Matches("CREATE", "COLLATION", MatchAny))
+		case Matches("CREATE", "COLLATION", MatchAny):
 		COMPLETE_WITH("(", "FROM");
-	else if (Matches("CREATE", "COLLATION", MatchAny, "FROM"))
+			break;
+		case Matches("CREATE", "COLLATION", MatchAny, "FROM"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_collations);
-	else if (HeadMatches("CREATE", "COLLATION", MatchAny, "(*"))
-	{
+			break;
+		case HeadMatches("CREATE", "COLLATION", MatchAny, "(*"):
 		if (TailMatches("(|*,"))
 			COMPLETE_WITH("LOCALE =", "LC_COLLATE =", "LC_CTYPE =",
 						  "PROVIDER =", "DETERMINISTIC =");
@@ -3136,410 +3428,499 @@ match_previous_words(const char *text, int start, int end,
 			COMPLETE_WITH("libc", "icu");
 		else if (TailMatches("DETERMINISTIC", "="))
 			COMPLETE_WITH("true", "false");
-	}
+			break;
 
 	/* CREATE DATABASE */
-	else if (Matches("CREATE", "DATABASE", MatchAny))
+		case Matches("CREATE", "DATABASE", MatchAny):
 		COMPLETE_WITH("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
 					  "IS_TEMPLATE", "STRATEGY",
 					  "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
 					  "LC_COLLATE", "LC_CTYPE", "LOCALE", "OID",
 					  "LOCALE_PROVIDER", "ICU_LOCALE");
+			break;
 
-	else if (Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
+		case Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
-	else if (Matches("CREATE", "DATABASE", MatchAny, "STRATEGY"))
+			break;
+		case Matches("CREATE", "DATABASE", MatchAny, "STRATEGY"):
 		COMPLETE_WITH("WAL_LOG", "FILE_COPY");
+			break;
 
 	/* CREATE DOMAIN */
-	else if (Matches("CREATE", "DOMAIN", MatchAny))
+		case Matches("CREATE", "DOMAIN", MatchAny):
 		COMPLETE_WITH("AS");
-	else if (Matches("CREATE", "DOMAIN", MatchAny, "AS"))
+			break;
+		case Matches("CREATE", "DOMAIN", MatchAny, "AS"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
-	else if (Matches("CREATE", "DOMAIN", MatchAny, "AS", MatchAny))
+			break;
+		case Matches("CREATE", "DOMAIN", MatchAny, "AS", MatchAny):
 		COMPLETE_WITH("COLLATE", "DEFAULT", "CONSTRAINT",
 					  "NOT NULL", "NULL", "CHECK (");
-	else if (Matches("CREATE", "DOMAIN", MatchAny, "COLLATE"))
+			break;
+		case Matches("CREATE", "DOMAIN", MatchAny, "COLLATE"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_collations);
+			break;
 
 	/* CREATE EXTENSION */
 	/* Complete with available extensions rather than installed ones. */
-	else if (Matches("CREATE", "EXTENSION"))
+		case Matches("CREATE", "EXTENSION"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
+			break;
 	/* CREATE EXTENSION <name> */
-	else if (Matches("CREATE", "EXTENSION", MatchAny))
+		case Matches("CREATE", "EXTENSION", MatchAny):
 		COMPLETE_WITH("WITH SCHEMA", "CASCADE", "VERSION");
+			break;
 	/* CREATE EXTENSION <name> VERSION */
-	else if (Matches("CREATE", "EXTENSION", MatchAny, "VERSION"))
-	{
+		case Matches("CREATE", "EXTENSION", MatchAny, "VERSION"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
-	}
+			break;
 
 	/* CREATE FOREIGN */
-	else if (Matches("CREATE", "FOREIGN"))
+		case Matches("CREATE", "FOREIGN"):
 		COMPLETE_WITH("DATA WRAPPER", "TABLE");
+			break;
 
 	/* CREATE FOREIGN DATA WRAPPER */
-	else if (Matches("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
+		case Matches("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny):
 		COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS");
+			break;
 
 	/* CREATE FOREIGN TABLE */
-	else if (Matches("CREATE", "FOREIGN", "TABLE", MatchAny))
+		case Matches("CREATE", "FOREIGN", "TABLE", MatchAny):
 		COMPLETE_WITH("(", "PARTITION OF");
+			break;
 
 	/* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
 	/* First off we complete CREATE UNIQUE with "INDEX" */
-	else if (TailMatches("CREATE", "UNIQUE"))
+		case TailMatches("CREATE", "UNIQUE"):
 		COMPLETE_WITH("INDEX");
+			break;
 
 	/*
 	 * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
 	 * existing indexes
 	 */
-	else if (TailMatches("CREATE|UNIQUE", "INDEX"))
+		case TailMatches("CREATE|UNIQUE", "INDEX"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
 										"ON", "CONCURRENTLY");
+			break;
 
 	/*
 	 * Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of relations
 	 * that indexes can be created on
 	 */
-	else if (TailMatches("INDEX|CONCURRENTLY", MatchAny, "ON") ||
-			 TailMatches("INDEX|CONCURRENTLY", "ON"))
+		case TailMatches("INDEX|CONCURRENTLY", MatchAny, "ON"):
+		case TailMatches("INDEX|CONCURRENTLY", "ON"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables);
+			break;
 
 	/*
 	 * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
 	 * indexes
 	 */
-	else if (TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
+		case TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
 										"ON");
+			break;
 	/* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
-	else if (TailMatches("CREATE|UNIQUE", "INDEX", MatchAny) ||
-			 TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
+		case TailMatches("CREATE|UNIQUE", "INDEX", MatchAny):
+		case TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny):
 		COMPLETE_WITH("ON");
+			break;
 
 	/*
 	 * Complete INDEX <name> ON <table> with a list of table columns (which
 	 * should really be in parens)
 	 */
-	else if (TailMatches("INDEX", MatchAny, "ON", MatchAny) ||
-			 TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny))
+		case TailMatches("INDEX", MatchAny, "ON", MatchAny):
+		case TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny):
 		COMPLETE_WITH("(", "USING");
-	else if (TailMatches("INDEX", MatchAny, "ON", MatchAny, "(") ||
-			 TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
+			break;
+		case TailMatches("INDEX", MatchAny, "ON", MatchAny, "("):
+		case TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny, "("):
 		COMPLETE_WITH_ATTR(prev2_wd);
+			break;
 	/* same if you put in USING */
-	else if (TailMatches("ON", MatchAny, "USING", MatchAny, "("))
+		case TailMatches("ON", MatchAny, "USING", MatchAny, "("):
 		COMPLETE_WITH_ATTR(prev4_wd);
+			break;
 	/* Complete USING with an index method */
-	else if (TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
-			 TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING") ||
-			 TailMatches("INDEX", "ON", MatchAny, "USING"))
+		case TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING"):
+		case TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING"):
+		case TailMatches("INDEX", "ON", MatchAny, "USING"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_index_access_methods);
-	else if (TailMatches("ON", MatchAny, "USING", MatchAny) &&
-			 !TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
-			 !TailMatches("FOR", MatchAny, MatchAny, MatchAny))
+			break;
+		case TailMatches("ON", MatchAny, "USING", MatchAny):
+		if (!TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) && !TailMatches("FOR", MatchAny, MatchAny, MatchAny))
 		COMPLETE_WITH("(");
+			break;
 
 	/* CREATE OR REPLACE */
-	else if (Matches("CREATE", "OR"))
+		case Matches("CREATE", "OR"):
 		COMPLETE_WITH("REPLACE");
+			break;
 
 	/* CREATE POLICY */
 	/* Complete "CREATE POLICY <name> ON" */
-	else if (Matches("CREATE", "POLICY", MatchAny))
+		case Matches("CREATE", "POLICY", MatchAny):
 		COMPLETE_WITH("ON");
+			break;
 	/* Complete "CREATE POLICY <name> ON <table>" */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 	/* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny):
 		COMPLETE_WITH("AS", "FOR", "TO", "USING (", "WITH CHECK (");
+			break;
 	/* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"):
 		COMPLETE_WITH("PERMISSIVE", "RESTRICTIVE");
+			break;
 
 	/*
 	 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
 	 * FOR|TO|USING|WITH CHECK
 	 */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny):
 		COMPLETE_WITH("FOR", "TO", "USING", "WITH CHECK");
+			break;
 	/* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"):
 		COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
+			break;
 	/* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"):
 		COMPLETE_WITH("TO", "WITH CHECK (");
+			break;
 	/* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"):
 		COMPLETE_WITH("TO", "USING (");
+			break;
 	/* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"):
 		COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
+			break;
 	/* Complete "CREATE POLICY <name> ON <table> TO <role>" */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 Keywords_for_list_of_grant_roles);
+			break;
 	/* Complete "CREATE POLICY <name> ON <table> USING (" */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"):
 		COMPLETE_WITH("(");
+			break;
 
 	/*
 	 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
 	 * ALL|SELECT|INSERT|UPDATE|DELETE
 	 */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"):
 		COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
+			break;
 
 	/*
 	 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
 	 * INSERT TO|WITH CHECK"
 	 */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"):
 		COMPLETE_WITH("TO", "WITH CHECK (");
+			break;
 
 	/*
 	 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
 	 * SELECT|DELETE TO|USING"
 	 */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"):
 		COMPLETE_WITH("TO", "USING (");
+			break;
 
 	/*
 	 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
 	 * ALL|UPDATE TO|USING|WITH CHECK
 	 */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"):
 		COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
+			break;
 
 	/*
 	 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO
 	 * <role>"
 	 */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 Keywords_for_list_of_grant_roles);
+			break;
 
 	/*
 	 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
 	 * USING ("
 	 */
-	else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
+		case Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"):
 		COMPLETE_WITH("(");
+			break;
 
 
 /* CREATE PUBLICATION */
-	else if (Matches("CREATE", "PUBLICATION", MatchAny))
+		case Matches("CREATE", "PUBLICATION", MatchAny):
 		COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "FOR TABLES IN SCHEMA", "WITH (");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR"))
+			break;
+		case Matches("CREATE", "PUBLICATION", MatchAny, "FOR"):
 		COMPLETE_WITH("TABLE", "ALL TABLES", "TABLES IN SCHEMA");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL"))
+			break;
+		case Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL"):
 		COMPLETE_WITH("TABLES");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES"))
+			break;
+		case Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES"):
 		COMPLETE_WITH("WITH (");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES"))
+			break;
+		case Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES"):
 		COMPLETE_WITH("IN SCHEMA");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE", MatchAny) && !ends_with(prev_wd, ','))
+			break;
+		case Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE", MatchAny):
+		if (!ends_with(prev_wd, ','))
 		COMPLETE_WITH("WHERE (", "WITH (");
+			break;
 	/* Complete "CREATE PUBLICATION <name> FOR TABLE" with "<table>, ..." */
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE"))
+		case Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 
 	/*
 	 * "CREATE PUBLICATION <name> FOR TABLE <name> WHERE (" - complete with
 	 * table attributes
 	 */
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, MatchAnyN, "WHERE"))
+		case Matches("CREATE", "PUBLICATION", MatchAny, MatchAnyN, "WHERE"):
 		COMPLETE_WITH("(");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, MatchAnyN, "WHERE", "("))
+			break;
+		case Matches("CREATE", "PUBLICATION", MatchAny, MatchAnyN, "WHERE", "("):
 		COMPLETE_WITH_ATTR(prev3_wd);
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, MatchAnyN, "WHERE", "(*)"))
+			break;
+		case Matches("CREATE", "PUBLICATION", MatchAny, MatchAnyN, "WHERE", "(*)"):
 		COMPLETE_WITH(" WITH (");
+			break;
 
 	/*
 	 * Complete "CREATE PUBLICATION <name> FOR TABLES IN SCHEMA <schema>, ..."
 	 */
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA"))
+		case Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas
 								 " AND nspname NOT LIKE E'pg\\\\_%%'",
 								 "CURRENT_SCHEMA");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA", MatchAny) && (!ends_with(prev_wd, ',')))
+			break;
+		case Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA", MatchAny):
+		if ((!ends_with(prev_wd, ',')))
 		COMPLETE_WITH("WITH (");
+			break;
 	/* Complete "CREATE PUBLICATION <name> [...] WITH" */
-	else if (Matches("CREATE", "PUBLICATION", MatchAnyN, "WITH", "("))
+		case Matches("CREATE", "PUBLICATION", MatchAnyN, "WITH", "("):
 		COMPLETE_WITH("publish", "publish_via_partition_root");
+			break;
 
 /* CREATE RULE */
 	/* Complete "CREATE [ OR REPLACE ] RULE <sth>" with "AS ON" */
-	else if (Matches("CREATE", "RULE", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny))
+		case Matches("CREATE", "RULE", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny):
 		COMPLETE_WITH("AS ON");
+			break;
 	/* Complete "CREATE [ OR REPLACE ] RULE <sth> AS" with "ON" */
-	else if (Matches("CREATE", "RULE", MatchAny, "AS") ||
-			 Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny, "AS"))
+		case Matches("CREATE", "RULE", MatchAny, "AS"):
+		case Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny, "AS"):
 		COMPLETE_WITH("ON");
+			break;
 
 	/*
 	 * Complete "CREATE [ OR REPLACE ] RULE <sth> AS ON" with
 	 * SELECT|UPDATE|INSERT|DELETE
 	 */
-	else if (Matches("CREATE", "RULE", MatchAny, "AS", "ON") ||
-			 Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny, "AS", "ON"))
+		case Matches("CREATE", "RULE", MatchAny, "AS", "ON"):
+		case Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny, "AS", "ON"):
 		COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE");
+			break;
 	/* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
-	else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
+		case TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"):
 		COMPLETE_WITH("TO");
+			break;
 	/* Complete "AS ON <sth> TO" with a table name */
-	else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
+		case TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 
 /* CREATE SCHEMA [ <name> ] [ AUTHORIZATION ] */
-	else if (Matches("CREATE", "SCHEMA"))
+		case Matches("CREATE", "SCHEMA"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas,
 								 "AUTHORIZATION");
-	else if (Matches("CREATE", "SCHEMA", "AUTHORIZATION") ||
-			 Matches("CREATE", "SCHEMA", MatchAny, "AUTHORIZATION"))
+			break;
+		case Matches("CREATE", "SCHEMA", "AUTHORIZATION"):
+		case Matches("CREATE", "SCHEMA", MatchAny, "AUTHORIZATION"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 Keywords_for_list_of_owner_roles);
-	else if (Matches("CREATE", "SCHEMA", "AUTHORIZATION", MatchAny) ||
-			 Matches("CREATE", "SCHEMA", MatchAny, "AUTHORIZATION", MatchAny))
+			break;
+		case Matches("CREATE", "SCHEMA", "AUTHORIZATION", MatchAny):
+		case Matches("CREATE", "SCHEMA", MatchAny, "AUTHORIZATION", MatchAny):
 		COMPLETE_WITH("CREATE", "GRANT");
-	else if (Matches("CREATE", "SCHEMA", MatchAny))
+			break;
+		case Matches("CREATE", "SCHEMA", MatchAny):
 		COMPLETE_WITH("AUTHORIZATION", "CREATE", "GRANT");
+			break;
 
 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
-	else if (TailMatches("CREATE", "SEQUENCE", MatchAny) ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
+		case TailMatches("CREATE", "SEQUENCE", MatchAny):
+		case TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny):
 		COMPLETE_WITH("AS", "INCREMENT BY", "MINVALUE", "MAXVALUE", "NO",
 					  "CACHE", "CYCLE", "OWNED BY", "START WITH");
-	else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "AS") ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "AS"))
+			break;
+		case TailMatches("CREATE", "SEQUENCE", MatchAny, "AS"):
+		case TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "AS"):
 		COMPLETE_WITH_CS("smallint", "integer", "bigint");
-	else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "NO") ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
+			break;
+		case TailMatches("CREATE", "SEQUENCE", MatchAny, "NO"):
+		case TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"):
 		COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
+			break;
 
 /* CREATE SERVER <name> */
-	else if (Matches("CREATE", "SERVER", MatchAny))
+		case Matches("CREATE", "SERVER", MatchAny):
 		COMPLETE_WITH("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
+			break;
 
 /* CREATE STATISTICS <name> */
-	else if (Matches("CREATE", "STATISTICS", MatchAny))
+		case Matches("CREATE", "STATISTICS", MatchAny):
 		COMPLETE_WITH("(", "ON");
-	else if (Matches("CREATE", "STATISTICS", MatchAny, "("))
+			break;
+		case Matches("CREATE", "STATISTICS", MatchAny, "("):
 		COMPLETE_WITH("ndistinct", "dependencies", "mcv");
-	else if (Matches("CREATE", "STATISTICS", MatchAny, "(*)"))
+			break;
+		case Matches("CREATE", "STATISTICS", MatchAny, "(*)"):
 		COMPLETE_WITH("ON");
-	else if (Matches("CREATE", "STATISTICS", MatchAny, MatchAnyN, "FROM"))
+			break;
+		case Matches("CREATE", "STATISTICS", MatchAny, MatchAnyN, "FROM"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 
 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
 	/* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
-	else if (TailMatches("CREATE", "TEMP|TEMPORARY"))
+		case TailMatches("CREATE", "TEMP|TEMPORARY"):
 		COMPLETE_WITH("SEQUENCE", "TABLE", "VIEW");
+			break;
 	/* Complete "CREATE UNLOGGED" with TABLE, SEQUENCE or MATVIEW */
-	else if (TailMatches("CREATE", "UNLOGGED"))
-	{
+		case TailMatches("CREATE", "UNLOGGED"):
 		/* but not MATVIEW in CREATE SCHEMA */
 		if (HeadMatches("CREATE", "SCHEMA"))
 			COMPLETE_WITH("TABLE", "SEQUENCE");
 		else
 			COMPLETE_WITH("TABLE", "SEQUENCE", "MATERIALIZED VIEW");
-	}
+			break;
 	/* Complete PARTITION BY with RANGE ( or LIST ( or ... */
-	else if (TailMatches("PARTITION", "BY"))
+		case TailMatches("PARTITION", "BY"):
 		COMPLETE_WITH("RANGE (", "LIST (", "HASH (");
+			break;
 	/* If we have xxx PARTITION OF, provide a list of partitioned tables */
-	else if (TailMatches("PARTITION", "OF"))
+		case TailMatches("PARTITION", "OF"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables);
+			break;
 	/* Limited completion support for partition bound specification */
-	else if (TailMatches("PARTITION", "OF", MatchAny))
+		case TailMatches("PARTITION", "OF", MatchAny):
 		COMPLETE_WITH("FOR VALUES", "DEFAULT");
+			break;
 	/* Complete CREATE TABLE <name> with '(', AS, OF or PARTITION OF */
-	else if (TailMatches("CREATE", "TABLE", MatchAny) ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny))
+		case TailMatches("CREATE", "TABLE", MatchAny):
+		case TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny):
 		COMPLETE_WITH("(", "AS", "OF", "PARTITION OF");
+			break;
 	/* Complete CREATE TABLE <name> OF with list of composite types */
-	else if (TailMatches("CREATE", "TABLE", MatchAny, "OF") ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "OF"))
+		case TailMatches("CREATE", "TABLE", MatchAny, "OF"):
+		case TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "OF"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes);
+			break;
 	/* Complete CREATE TABLE <name> [ (...) ] AS with list of keywords */
-	else if (TailMatches("CREATE", "TABLE", MatchAny, "AS") ||
-			 TailMatches("CREATE", "TABLE", MatchAny, "(*)", "AS") ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "AS") ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "AS"))
+		case TailMatches("CREATE", "TABLE", MatchAny, "AS"):
+		case TailMatches("CREATE", "TABLE", MatchAny, "(*)", "AS"):
+		case TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "AS"):
+		case TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "AS"):
 		COMPLETE_WITH("EXECUTE", "SELECT", "TABLE", "VALUES", "WITH");
+			break;
 	/* Complete CREATE TABLE name (...) with supported options */
-	else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)") ||
-			 TailMatches("CREATE", "UNLOGGED", "TABLE", MatchAny, "(*)"))
+		case TailMatches("CREATE", "TABLE", MatchAny, "(*)"):
+		case TailMatches("CREATE", "UNLOGGED", "TABLE", MatchAny, "(*)"):
 		COMPLETE_WITH("AS", "INHERITS (", "PARTITION BY", "USING", "TABLESPACE", "WITH (");
-	else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)"))
+			break;
+		case TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)"):
 		COMPLETE_WITH("AS", "INHERITS (", "ON COMMIT", "PARTITION BY",
 					  "TABLESPACE", "WITH (");
+			break;
 	/* Complete CREATE TABLE (...) USING with table access methods */
-	else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "USING") ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "USING"))
+		case TailMatches("CREATE", "TABLE", MatchAny, "(*)", "USING"):
+		case TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "USING"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_table_access_methods);
+			break;
 	/* Complete CREATE TABLE (...) WITH with storage parameters */
-	else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "WITH", "(") ||
-			 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "WITH", "("))
+		case TailMatches("CREATE", "TABLE", MatchAny, "(*)", "WITH", "("):
+		case TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "WITH", "("):
 		COMPLETE_WITH_LIST(table_storage_parameters);
+			break;
 	/* Complete CREATE TABLE ON COMMIT with actions */
-	else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)", "ON", "COMMIT"))
+		case TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)", "ON", "COMMIT"):
 		COMPLETE_WITH("DELETE ROWS", "DROP", "PRESERVE ROWS");
+			break;
 
 /* CREATE TABLESPACE */
-	else if (Matches("CREATE", "TABLESPACE", MatchAny))
+		case Matches("CREATE", "TABLESPACE", MatchAny):
 		COMPLETE_WITH("OWNER", "LOCATION");
+			break;
 	/* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
-	else if (Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
+		case Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny):
 		COMPLETE_WITH("LOCATION");
+			break;
 
 /* CREATE TEXT SEARCH */
-	else if (Matches("CREATE", "TEXT", "SEARCH"))
+		case Matches("CREATE", "TEXT", "SEARCH"):
 		COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
-	else if (Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
+			break;
+		case Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny):
 		COMPLETE_WITH("(");
+			break;
 
 /* CREATE TRANSFORM */
-	else if (Matches("CREATE", "TRANSFORM") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRANSFORM"))
+		case Matches("CREATE", "TRANSFORM"):
+		case Matches("CREATE", "OR", "REPLACE", "TRANSFORM"):
 		COMPLETE_WITH("FOR");
-	else if (Matches("CREATE", "TRANSFORM", "FOR") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR"))
+			break;
+		case Matches("CREATE", "TRANSFORM", "FOR"):
+		case Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
-	else if (Matches("CREATE", "TRANSFORM", "FOR", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR", MatchAny))
+			break;
+		case Matches("CREATE", "TRANSFORM", "FOR", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR", MatchAny):
 		COMPLETE_WITH("LANGUAGE");
-	else if (Matches("CREATE", "TRANSFORM", "FOR", MatchAny, "LANGUAGE") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"))
-	{
+			break;
+		case Matches("CREATE", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"):
+		case Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_QUERY(Query_for_list_of_languages);
-	}
+			break;
 
 /* CREATE SUBSCRIPTION */
-	else if (Matches("CREATE", "SUBSCRIPTION", MatchAny))
+		case Matches("CREATE", "SUBSCRIPTION", MatchAny):
 		COMPLETE_WITH("CONNECTION");
-	else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny))
+			break;
+		case Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny):
 		COMPLETE_WITH("PUBLICATION");
-	else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION",
-					 MatchAny, "PUBLICATION"))
-	{
+			break;
+		case Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny, "PUBLICATION"):
 		/* complete with nothing here as this refers to remote publications */
-	}
-	else if (Matches("CREATE", "SUBSCRIPTION", MatchAnyN, "PUBLICATION", MatchAny))
+			break;
+		case Matches("CREATE", "SUBSCRIPTION", MatchAnyN, "PUBLICATION", MatchAny):
 		COMPLETE_WITH("WITH (");
+			break;
 	/* Complete "CREATE SUBSCRIPTION <name> ...  WITH ( <opt>" */
-	else if (Matches("CREATE", "SUBSCRIPTION", MatchAnyN, "WITH", "("))
+		case Matches("CREATE", "SUBSCRIPTION", MatchAnyN, "WITH", "("):
 		COMPLETE_WITH("binary", "connect", "copy_data", "create_slot",
 					  "disable_on_error", "enabled", "failover", "origin",
 					  "password_required", "run_as_owner", "slot_name",
 					  "streaming", "synchronous_commit", "two_phase");
+			break;
 
 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
 
@@ -3547,192 +3928,155 @@ match_previous_words(const char *text, int start, int end,
 	 * Complete CREATE [ OR REPLACE ] TRIGGER <name> with BEFORE|AFTER|INSTEAD
 	 * OF.
 	 */
-	else if (TailMatches("CREATE", "TRIGGER", MatchAny) ||
-			 TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny))
+		case TailMatches("CREATE", "TRIGGER", MatchAny):
+		case TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny):
 		COMPLETE_WITH("BEFORE", "AFTER", "INSTEAD OF");
+			break;
 
 	/*
 	 * Complete CREATE [ OR REPLACE ] TRIGGER <name> BEFORE,AFTER with an
 	 * event.
 	 */
-	else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
+		case TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER"):
+		case TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER"):
 		COMPLETE_WITH("INSERT", "DELETE", "UPDATE", "TRUNCATE");
+			break;
 	/* Complete CREATE [ OR REPLACE ] TRIGGER <name> INSTEAD OF with an event */
-	else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
+		case TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF"):
+		case TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF"):
 		COMPLETE_WITH("INSERT", "DELETE", "UPDATE");
+			break;
 
 	/*
 	 * Complete CREATE [ OR REPLACE ] TRIGGER <name> BEFORE,AFTER sth with
 	 * OR|ON.
 	 */
-	else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
-			 TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
-			 TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny) ||
-			 TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
+		case TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny):
+		case TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny):
+		case TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny):
+		case TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny):
 		COMPLETE_WITH("ON", "OR");
+			break;
 
 	/*
 	 * Complete CREATE [ OR REPLACE ] TRIGGER <name> BEFORE,AFTER event ON
 	 * with a list of tables.  EXECUTE FUNCTION is the recommended grammar
 	 * instead of EXECUTE PROCEDURE in version 11 and upwards.
 	 */
-	else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
+		case TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"):
+		case TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 
 	/*
 	 * Complete CREATE [ OR REPLACE ] TRIGGER ... INSTEAD OF event ON with a
 	 * list of views.
 	 */
-	else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
+		case TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"):
+		case TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "ON", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "ON", MatchAny))
-	{
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "ON", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "ON", MatchAny):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
 						  "REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
 						  "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
-	}
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "DEFERRABLE") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "DEFERRABLE") ||
-			 Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "INITIALLY", "IMMEDIATE|DEFERRED") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "INITIALLY", "IMMEDIATE|DEFERRED"))
-	{
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "DEFERRABLE"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "DEFERRABLE"):
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "INITIALLY", "IMMEDIATE|DEFERRED"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "INITIALLY", "IMMEDIATE|DEFERRED"):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
-	}
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING"))
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING"):
 		COMPLETE_WITH("OLD TABLE", "NEW TABLE");
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "OLD|NEW", "TABLE") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "OLD|NEW", "TABLE"))
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "OLD|NEW", "TABLE"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "OLD|NEW", "TABLE"):
 		COMPLETE_WITH("AS");
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
-			 Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD", "TABLE", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD", "TABLE", MatchAny))
-	{
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD", "TABLE", "AS", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD", "TABLE", "AS", MatchAny):
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD", "TABLE", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD", "TABLE", MatchAny):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
-	}
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
-			 Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "NEW", "TABLE", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "NEW", "TABLE", MatchAny))
-	{
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING", "NEW", "TABLE", "AS", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING", "NEW", "TABLE", "AS", MatchAny):
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING", "NEW", "TABLE", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING", "NEW", "TABLE", MatchAny):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
-	}
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
-			 Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
-			 Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
-			 Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny))
-	{
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny):
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny):
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny):
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("FOR", "WHEN (", "EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("FOR", "WHEN (", "EXECUTE PROCEDURE");
-	}
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "FOR") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "FOR"))
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "FOR"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "FOR"):
 		COMPLETE_WITH("EACH", "ROW", "STATEMENT");
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "FOR", "EACH") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "FOR", "EACH"))
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "FOR", "EACH"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "FOR", "EACH"):
 		COMPLETE_WITH("ROW", "STATEMENT");
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "FOR", "EACH", "ROW|STATEMENT") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "FOR", "EACH", "ROW|STATEMENT") ||
-			 Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "FOR", "ROW|STATEMENT") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "FOR", "ROW|STATEMENT"))
-	{
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "FOR", "EACH", "ROW|STATEMENT"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "FOR", "EACH", "ROW|STATEMENT"):
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "FOR", "ROW|STATEMENT"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "FOR", "ROW|STATEMENT"):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("WHEN (", "EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("WHEN (", "EXECUTE PROCEDURE");
-	}
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "WHEN", "(*)") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "WHEN", "(*)"))
-	{
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "WHEN", "(*)"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "WHEN", "(*)"):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("EXECUTE PROCEDURE");
-	}
+			break;
 
 	/*
 	 * Complete CREATE [ OR REPLACE ] TRIGGER ... EXECUTE with
 	 * PROCEDURE|FUNCTION.
 	 */
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "EXECUTE") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "EXECUTE"))
-	{
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "EXECUTE"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "EXECUTE"):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("FUNCTION");
 		else
 			COMPLETE_WITH("PROCEDURE");
-	}
-	else if (Matches("CREATE", "TRIGGER", MatchAnyN,
-					 "EXECUTE", "FUNCTION|PROCEDURE") ||
-			 Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN,
-					 "EXECUTE", "FUNCTION|PROCEDURE"))
+			break;
+		case Matches("CREATE", "TRIGGER", MatchAnyN, "EXECUTE", "FUNCTION|PROCEDURE"):
+		case Matches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAnyN, "EXECUTE", "FUNCTION|PROCEDURE"):
 		COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions);
+			break;
 
 /* CREATE ROLE,USER,GROUP <name> */
-	else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny) &&
-			 !TailMatches("USER", "MAPPING"))
+		case Matches("CREATE", "ROLE|GROUP|USER", MatchAny):
+		if (!TailMatches("USER", "MAPPING"))
 		COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
 					  "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
 					  "LOGIN", "NOBYPASSRLS",
@@ -3740,9 +4084,10 @@ match_previous_words(const char *text, int start, int end,
 					  "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
 					  "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
 					  "VALID UNTIL", "WITH");
+			break;
 
 /* CREATE ROLE,USER,GROUP <name> WITH */
-	else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
+		case Matches("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"):
 		/* Similar to the above, but don't complete "WITH" again. */
 		COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
 					  "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
@@ -3751,27 +4096,30 @@ match_previous_words(const char *text, int start, int end,
 					  "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
 					  "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
 					  "VALID UNTIL");
+			break;
 
 	/* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
-	else if (Matches("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
+		case Matches("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"):
 		COMPLETE_WITH("GROUP", "ROLE");
+			break;
 
 /* CREATE TYPE */
-	else if (Matches("CREATE", "TYPE", MatchAny))
+		case Matches("CREATE", "TYPE", MatchAny):
 		COMPLETE_WITH("(", "AS");
-	else if (Matches("CREATE", "TYPE", MatchAny, "AS"))
+			break;
+		case Matches("CREATE", "TYPE", MatchAny, "AS"):
 		COMPLETE_WITH("ENUM", "RANGE", "(");
-	else if (HeadMatches("CREATE", "TYPE", MatchAny, "AS", "("))
-	{
+			break;
+		case HeadMatches("CREATE", "TYPE", MatchAny, "AS", "("):
 		if (TailMatches("(|*,", MatchAny))
 			COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
 		else if (TailMatches("(|*,", MatchAny, MatchAnyExcept("*)")))
 			COMPLETE_WITH("COLLATE", ",", ")");
-	}
-	else if (Matches("CREATE", "TYPE", MatchAny, "AS", "ENUM|RANGE"))
+			break;
+		case Matches("CREATE", "TYPE", MatchAny, "AS", "ENUM|RANGE"):
 		COMPLETE_WITH("(");
-	else if (HeadMatches("CREATE", "TYPE", MatchAny, "("))
-	{
+			break;
+		case HeadMatches("CREATE", "TYPE", MatchAny, "("):
 		if (TailMatches("(|*,"))
 			COMPLETE_WITH("INPUT", "OUTPUT", "RECEIVE", "SEND",
 						  "TYPMOD_IN", "TYPMOD_OUT", "ANALYZE", "SUBSCRIPT",
@@ -3783,9 +4131,8 @@ match_previous_words(const char *text, int start, int end,
 			COMPLETE_WITH("=");
 		else if (TailMatches("=", MatchAnyExcept("*)")))
 			COMPLETE_WITH(",", ")");
-	}
-	else if (HeadMatches("CREATE", "TYPE", MatchAny, "AS", "RANGE", "("))
-	{
+			break;
+		case HeadMatches("CREATE", "TYPE", MatchAny, "AS", "RANGE", "("):
 		if (TailMatches("(|*,"))
 			COMPLETE_WITH("SUBTYPE", "SUBTYPE_OPCLASS", "COLLATION",
 						  "CANONICAL", "SUBTYPE_DIFF",
@@ -3794,86 +4141,100 @@ match_previous_words(const char *text, int start, int end,
 			COMPLETE_WITH("=");
 		else if (TailMatches("=", MatchAnyExcept("*)")))
 			COMPLETE_WITH(",", ")");
-	}
+			break;
 
 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
 	/* Complete CREATE [ OR REPLACE ] VIEW <name> with AS or WITH */
-	else if (TailMatches("CREATE", "VIEW", MatchAny) ||
-			 TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny))
+		case TailMatches("CREATE", "VIEW", MatchAny):
+		case TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny):
 		COMPLETE_WITH("AS", "WITH");
+			break;
 	/* Complete "CREATE [ OR REPLACE ] VIEW <sth> AS with "SELECT" */
-	else if (TailMatches("CREATE", "VIEW", MatchAny, "AS") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "AS"))
+		case TailMatches("CREATE", "VIEW", MatchAny, "AS"):
+		case TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "AS"):
 		COMPLETE_WITH("SELECT");
+			break;
 	/* CREATE [ OR REPLACE ] VIEW <name> WITH ( yyy [= zzz] ) */
-	else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH"))
+		case TailMatches("CREATE", "VIEW", MatchAny, "WITH"):
+		case TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH"):
 		COMPLETE_WITH("(");
-	else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "("))
+			break;
+		case TailMatches("CREATE", "VIEW", MatchAny, "WITH", "("):
+		case TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "("):
 		COMPLETE_WITH_LIST(view_optional_parameters);
-	else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(", "check_option") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(", "check_option"))
+			break;
+		case TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(", "check_option"):
+		case TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(", "check_option"):
 		COMPLETE_WITH("=");
-	else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(", "check_option", "=") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(", "check_option", "="))
+			break;
+		case TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(", "check_option", "="):
+		case TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(", "check_option", "="):
 		COMPLETE_WITH("local", "cascaded");
+			break;
 	/* CREATE [ OR REPLACE ] VIEW <name> WITH ( ... ) AS */
-	else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(*)") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(*)"))
+		case TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(*)"):
+		case TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(*)"):
 		COMPLETE_WITH("AS");
+			break;
 	/* CREATE [ OR REPLACE ] VIEW <name> WITH ( ... ) AS SELECT */
-	else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(*)", "AS") ||
-			 TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(*)", "AS"))
+		case TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(*)", "AS"):
+		case TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(*)", "AS"):
 		COMPLETE_WITH("SELECT");
+			break;
 
 /* CREATE MATERIALIZED VIEW */
-	else if (Matches("CREATE", "MATERIALIZED"))
+		case Matches("CREATE", "MATERIALIZED"):
 		COMPLETE_WITH("VIEW");
+			break;
 	/* Complete CREATE MATERIALIZED VIEW <name> with AS */
-	else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny))
+		case Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny):
 		COMPLETE_WITH("AS");
+			break;
 	/* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
-	else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
+		case Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"):
 		COMPLETE_WITH("SELECT");
+			break;
 
 /* CREATE EVENT TRIGGER */
-	else if (Matches("CREATE", "EVENT"))
+		case Matches("CREATE", "EVENT"):
 		COMPLETE_WITH("TRIGGER");
+			break;
 	/* Complete CREATE EVENT TRIGGER <name> with ON */
-	else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny))
+		case Matches("CREATE", "EVENT", "TRIGGER", MatchAny):
 		COMPLETE_WITH("ON");
+			break;
 	/* Complete CREATE EVENT TRIGGER <name> ON with event_type */
-	else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
+		case Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"):
 		COMPLETE_WITH("ddl_command_start", "ddl_command_end", "login",
 					  "sql_drop", "table_rewrite");
+			break;
 
 	/*
 	 * Complete CREATE EVENT TRIGGER <name> ON <event_type>.  EXECUTE FUNCTION
 	 * is the recommended grammar instead of EXECUTE PROCEDURE in version 11
 	 * and upwards.
 	 */
-	else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON", MatchAny))
-	{
+		case Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON", MatchAny):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("WHEN TAG IN (", "EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("WHEN TAG IN (", "EXECUTE PROCEDURE");
-	}
-	else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAnyN, "WHEN|AND", MatchAny, "IN", "(*)"))
-	{
+			break;
+		case Matches("CREATE", "EVENT", "TRIGGER", MatchAnyN, "WHEN|AND", MatchAny, "IN", "(*)"):
 		if (pset.sversion >= 110000)
 			COMPLETE_WITH("EXECUTE FUNCTION");
 		else
 			COMPLETE_WITH("EXECUTE PROCEDURE");
-	}
-	else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAnyN, "EXECUTE", "FUNCTION|PROCEDURE"))
+			break;
+		case Matches("CREATE", "EVENT", "TRIGGER", MatchAnyN, "EXECUTE", "FUNCTION|PROCEDURE"):
 		COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions);
+			break;
 
 /* DEALLOCATE */
-	else if (Matches("DEALLOCATE"))
+		case Matches("DEALLOCATE"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_prepared_statements,
 								 "ALL");
+			break;
 
 /* DECLARE */
 
@@ -3881,9 +4242,10 @@ match_previous_words(const char *text, int start, int end,
 	 * Complete DECLARE <name> with one of BINARY, ASENSITIVE, INSENSITIVE,
 	 * SCROLL, NO SCROLL, and CURSOR.
 	 */
-	else if (Matches("DECLARE", MatchAny))
+		case Matches("DECLARE", MatchAny):
 		COMPLETE_WITH("BINARY", "ASENSITIVE", "INSENSITIVE", "SCROLL", "NO SCROLL",
 					  "CURSOR");
+			break;
 
 	/*
 	 * Complete DECLARE ... <option> with other options. The PostgreSQL parser
@@ -3892,183 +4254,226 @@ match_previous_words(const char *text, int start, int end,
 	 * provides, like the syntax of DECLARE command in the documentation
 	 * indicates.
 	 */
-	else if (Matches("DECLARE", MatchAnyN, "BINARY"))
+		case Matches("DECLARE", MatchAnyN, "BINARY"):
 		COMPLETE_WITH("ASENSITIVE", "INSENSITIVE", "SCROLL", "NO SCROLL", "CURSOR");
-	else if (Matches("DECLARE", MatchAnyN, "ASENSITIVE|INSENSITIVE"))
+			break;
+		case Matches("DECLARE", MatchAnyN, "ASENSITIVE|INSENSITIVE"):
 		COMPLETE_WITH("SCROLL", "NO SCROLL", "CURSOR");
-	else if (Matches("DECLARE", MatchAnyN, "SCROLL"))
+			break;
+		case Matches("DECLARE", MatchAnyN, "SCROLL"):
 		COMPLETE_WITH("CURSOR");
+			break;
 	/* Complete DECLARE ... [options] NO with SCROLL */
-	else if (Matches("DECLARE", MatchAnyN, "NO"))
+		case Matches("DECLARE", MatchAnyN, "NO"):
 		COMPLETE_WITH("SCROLL");
+			break;
 
 	/*
 	 * Complete DECLARE ... CURSOR with one of WITH HOLD, WITHOUT HOLD, and
 	 * FOR
 	 */
-	else if (Matches("DECLARE", MatchAnyN, "CURSOR"))
+		case Matches("DECLARE", MatchAnyN, "CURSOR"):
 		COMPLETE_WITH("WITH HOLD", "WITHOUT HOLD", "FOR");
+			break;
 	/* Complete DECLARE ... CURSOR WITH|WITHOUT with HOLD */
-	else if (Matches("DECLARE", MatchAnyN, "CURSOR", "WITH|WITHOUT"))
+		case Matches("DECLARE", MatchAnyN, "CURSOR", "WITH|WITHOUT"):
 		COMPLETE_WITH("HOLD");
+			break;
 	/* Complete DECLARE ... CURSOR WITH|WITHOUT HOLD with FOR */
-	else if (Matches("DECLARE", MatchAnyN, "CURSOR", "WITH|WITHOUT", "HOLD"))
+		case Matches("DECLARE", MatchAnyN, "CURSOR", "WITH|WITHOUT", "HOLD"):
 		COMPLETE_WITH("FOR");
+			break;
 
 /* DELETE --- can be inside EXPLAIN, RULE, etc */
 	/* Complete DELETE with "FROM" */
-	else if (Matches("DELETE"))
+		case Matches("DELETE"):
 		COMPLETE_WITH("FROM");
+			break;
 	/* Complete DELETE FROM with a list of tables */
-	else if (TailMatches("DELETE", "FROM"))
+		case TailMatches("DELETE", "FROM"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables);
+			break;
 	/* Complete DELETE FROM <table> */
-	else if (TailMatches("DELETE", "FROM", MatchAny))
+		case TailMatches("DELETE", "FROM", MatchAny):
 		COMPLETE_WITH("USING", "WHERE");
+			break;
 	/* XXX: implement tab completion for DELETE ... USING */
 
 /* DISCARD */
-	else if (Matches("DISCARD"))
+		case Matches("DISCARD"):
 		COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP");
+			break;
 
 /* DO */
-	else if (Matches("DO"))
+		case Matches("DO"):
 		COMPLETE_WITH("LANGUAGE");
+			break;
 
 /* DROP */
 	/* Complete DROP object with CASCADE / RESTRICT */
-	else if (Matches("DROP",
-					 "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW",
-					 MatchAny) ||
-			 Matches("DROP", "ACCESS", "METHOD", MatchAny) ||
-			 (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) &&
-			  ends_with(prev_wd, ')')) ||
-			 Matches("DROP", "EVENT", "TRIGGER", MatchAny) ||
-			 Matches("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
-			 Matches("DROP", "FOREIGN", "TABLE", MatchAny) ||
-			 Matches("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
+		case Matches("DROP", "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW", MatchAny):
+		case Matches("DROP", "ACCESS", "METHOD", MatchAny):
+		case Matches("DROP", "EVENT", "TRIGGER", MatchAny):
+		case Matches("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny):
+		case Matches("DROP", "FOREIGN", "TABLE", MatchAny):
+		case Matches("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny):
+		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
+		case Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny):
+		if (ends_with(prev_wd, ')'))
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 	/* help completing some of the variants */
-	else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
+		case Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny):
 		COMPLETE_WITH("(");
-	else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "("))
+			break;
+		case Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "("):
 		COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
-	else if (Matches("DROP", "FOREIGN"))
+			break;
+		case Matches("DROP", "FOREIGN"):
 		COMPLETE_WITH("DATA WRAPPER", "TABLE");
-	else if (Matches("DROP", "DATABASE", MatchAny))
+			break;
+		case Matches("DROP", "DATABASE", MatchAny):
 		COMPLETE_WITH("WITH (");
-	else if (HeadMatches("DROP", "DATABASE") && (ends_with(prev_wd, '(')))
+			break;
+		case HeadMatches("DROP", "DATABASE"):
+		if ((ends_with(prev_wd, '(')))
 		COMPLETE_WITH("FORCE");
+			break;
 
 	/* DROP INDEX */
-	else if (Matches("DROP", "INDEX"))
+		case Matches("DROP", "INDEX"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
 										"CONCURRENTLY");
-	else if (Matches("DROP", "INDEX", "CONCURRENTLY"))
+			break;
+		case Matches("DROP", "INDEX", "CONCURRENTLY"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
-	else if (Matches("DROP", "INDEX", MatchAny))
+			break;
+		case Matches("DROP", "INDEX", MatchAny):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
-	else if (Matches("DROP", "INDEX", "CONCURRENTLY", MatchAny))
+			break;
+		case Matches("DROP", "INDEX", "CONCURRENTLY", MatchAny):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 	/* DROP MATERIALIZED VIEW */
-	else if (Matches("DROP", "MATERIALIZED"))
+		case Matches("DROP", "MATERIALIZED"):
 		COMPLETE_WITH("VIEW");
-	else if (Matches("DROP", "MATERIALIZED", "VIEW"))
+			break;
+		case Matches("DROP", "MATERIALIZED", "VIEW"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
-	else if (Matches("DROP", "MATERIALIZED", "VIEW", MatchAny))
+			break;
+		case Matches("DROP", "MATERIALIZED", "VIEW", MatchAny):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 	/* DROP OWNED BY */
-	else if (Matches("DROP", "OWNED"))
+		case Matches("DROP", "OWNED"):
 		COMPLETE_WITH("BY");
-	else if (Matches("DROP", "OWNED", "BY"))
+			break;
+		case Matches("DROP", "OWNED", "BY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
-	else if (Matches("DROP", "OWNED", "BY", MatchAny))
+			break;
+		case Matches("DROP", "OWNED", "BY", MatchAny):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 	/* DROP TEXT SEARCH */
-	else if (Matches("DROP", "TEXT", "SEARCH"))
+		case Matches("DROP", "TEXT", "SEARCH"):
 		COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
+			break;
 
 	/* DROP TRIGGER */
-	else if (Matches("DROP", "TRIGGER", MatchAny))
+		case Matches("DROP", "TRIGGER", MatchAny):
 		COMPLETE_WITH("ON");
-	else if (Matches("DROP", "TRIGGER", MatchAny, "ON"))
-	{
+			break;
+		case Matches("DROP", "TRIGGER", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_trigger);
-	}
-	else if (Matches("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
+			break;
+		case Matches("DROP", "TRIGGER", MatchAny, "ON", MatchAny):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 	/* DROP ACCESS METHOD */
-	else if (Matches("DROP", "ACCESS"))
+		case Matches("DROP", "ACCESS"):
 		COMPLETE_WITH("METHOD");
-	else if (Matches("DROP", "ACCESS", "METHOD"))
+			break;
+		case Matches("DROP", "ACCESS", "METHOD"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
+			break;
 
 	/* DROP EVENT TRIGGER */
-	else if (Matches("DROP", "EVENT"))
+		case Matches("DROP", "EVENT"):
 		COMPLETE_WITH("TRIGGER");
-	else if (Matches("DROP", "EVENT", "TRIGGER"))
+			break;
+		case Matches("DROP", "EVENT", "TRIGGER"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
+			break;
 
 	/* DROP POLICY <name>  */
-	else if (Matches("DROP", "POLICY"))
+		case Matches("DROP", "POLICY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_policies);
+			break;
 	/* DROP POLICY <name> ON */
-	else if (Matches("DROP", "POLICY", MatchAny))
+		case Matches("DROP", "POLICY", MatchAny):
 		COMPLETE_WITH("ON");
+			break;
 	/* DROP POLICY <name> ON <table> */
-	else if (Matches("DROP", "POLICY", MatchAny, "ON"))
-	{
+		case Matches("DROP", "POLICY", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_policy);
-	}
-	else if (Matches("DROP", "POLICY", MatchAny, "ON", MatchAny))
+			break;
+		case Matches("DROP", "POLICY", MatchAny, "ON", MatchAny):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 	/* DROP RULE */
-	else if (Matches("DROP", "RULE", MatchAny))
+		case Matches("DROP", "RULE", MatchAny):
 		COMPLETE_WITH("ON");
-	else if (Matches("DROP", "RULE", MatchAny, "ON"))
-	{
+			break;
+		case Matches("DROP", "RULE", MatchAny, "ON"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_rule);
-	}
-	else if (Matches("DROP", "RULE", MatchAny, "ON", MatchAny))
+			break;
+		case Matches("DROP", "RULE", MatchAny, "ON", MatchAny):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 	/* DROP TRANSFORM */
-	else if (Matches("DROP", "TRANSFORM"))
+		case Matches("DROP", "TRANSFORM"):
 		COMPLETE_WITH("FOR");
-	else if (Matches("DROP", "TRANSFORM", "FOR"))
+			break;
+		case Matches("DROP", "TRANSFORM", "FOR"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
-	else if (Matches("DROP", "TRANSFORM", "FOR", MatchAny))
+			break;
+		case Matches("DROP", "TRANSFORM", "FOR", MatchAny):
 		COMPLETE_WITH("LANGUAGE");
-	else if (Matches("DROP", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"))
-	{
+			break;
+		case Matches("DROP", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"):
 		set_completion_reference(prev2_wd);
 		COMPLETE_WITH_QUERY(Query_for_list_of_languages);
-	}
-	else if (Matches("DROP", "TRANSFORM", "FOR", MatchAny, "LANGUAGE", MatchAny))
+			break;
+		case Matches("DROP", "TRANSFORM", "FOR", MatchAny, "LANGUAGE", MatchAny):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 /* EXECUTE */
-	else if (Matches("EXECUTE"))
+		case Matches("EXECUTE"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
+			break;
 
 /*
  * EXPLAIN [ ( option [, ...] ) ] statement
  * EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
  */
-	else if (Matches("EXPLAIN"))
+		case Matches("EXPLAIN"):
 		COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 					  "MERGE INTO", "EXECUTE", "ANALYZE", "VERBOSE");
-	else if (HeadMatches("EXPLAIN", "(*") &&
-			 !HeadMatches("EXPLAIN", "(*)"))
+			break;
+		case HeadMatches("EXPLAIN", "(*"):
+		if (!HeadMatches("EXPLAIN", "(*)"))
 	{
 		/*
 		 * This fires if we're in an unfinished parenthesized option list.
@@ -4086,14 +4491,17 @@ match_previous_words(const char *text, int start, int end,
 		else if (TailMatches("FORMAT"))
 			COMPLETE_WITH("TEXT", "XML", "JSON", "YAML");
 	}
-	else if (Matches("EXPLAIN", "ANALYZE"))
+			break;
+		case Matches("EXPLAIN", "ANALYZE"):
 		COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 					  "MERGE INTO", "EXECUTE", "VERBOSE");
-	else if (Matches("EXPLAIN", "(*)") ||
-			 Matches("EXPLAIN", "VERBOSE") ||
-			 Matches("EXPLAIN", "ANALYZE", "VERBOSE"))
+			break;
+		case Matches("EXPLAIN", "(*)"):
+		case Matches("EXPLAIN", "VERBOSE"):
+		case Matches("EXPLAIN", "ANALYZE", "VERBOSE"):
 		COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
 					  "MERGE INTO", "EXECUTE");
+			break;
 
 /* FETCH && MOVE */
 
@@ -4101,7 +4509,7 @@ match_previous_words(const char *text, int start, int end,
 	 * Complete FETCH with one of ABSOLUTE, BACKWARD, FORWARD, RELATIVE, ALL,
 	 * NEXT, PRIOR, FIRST, LAST, FROM, IN, and a list of cursors
 	 */
-	else if (Matches("FETCH|MOVE"))
+		case Matches("FETCH|MOVE"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,
 								 "ABSOLUTE",
 								 "BACKWARD",
@@ -4114,58 +4522,64 @@ match_previous_words(const char *text, int start, int end,
 								 "LAST",
 								 "FROM",
 								 "IN");
+			break;
 
 	/*
 	 * Complete FETCH BACKWARD or FORWARD with one of ALL, FROM, IN, and a
 	 * list of cursors
 	 */
-	else if (Matches("FETCH|MOVE", "BACKWARD|FORWARD"))
+		case Matches("FETCH|MOVE", "BACKWARD|FORWARD"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,
 								 "ALL",
 								 "FROM",
 								 "IN");
+			break;
 
 	/*
 	 * Complete FETCH <direction> with "FROM" or "IN". These are equivalent,
 	 * but we may as well tab-complete both: perhaps some users prefer one
 	 * variant or the other.
 	 */
-	else if (Matches("FETCH|MOVE", "ABSOLUTE|BACKWARD|FORWARD|RELATIVE",
-					 MatchAnyExcept("FROM|IN")) ||
-			 Matches("FETCH|MOVE", "ALL|NEXT|PRIOR|FIRST|LAST"))
+		case Matches("FETCH|MOVE", "ABSOLUTE|BACKWARD|FORWARD|RELATIVE", MatchAnyExcept("FROM|IN")):
+		case Matches("FETCH|MOVE", "ALL|NEXT|PRIOR|FIRST|LAST"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,
 								 "FROM",
 								 "IN");
+			break;
 	/* Complete FETCH <direction> "FROM" or "IN" with a list of cursors */
-	else if (Matches("FETCH|MOVE", MatchAnyN, "FROM|IN"))
+		case Matches("FETCH|MOVE", MatchAnyN, "FROM|IN"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_cursors);
+			break;
 
 /* FOREIGN DATA WRAPPER */
 	/* applies in ALTER/DROP FDW and in CREATE SERVER */
-	else if (TailMatches("FOREIGN", "DATA", "WRAPPER") &&
-			 !TailMatches("CREATE", MatchAny, MatchAny, MatchAny))
+		case TailMatches("FOREIGN", "DATA", "WRAPPER"):
+		if (!TailMatches("CREATE", MatchAny, MatchAny, MatchAny))
 		COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
+			break;
 	/* applies in CREATE SERVER */
-	else if (Matches("CREATE", "SERVER", MatchAnyN, "FOREIGN", "DATA", "WRAPPER", MatchAny))
+		case Matches("CREATE", "SERVER", MatchAnyN, "FOREIGN", "DATA", "WRAPPER", MatchAny):
 		COMPLETE_WITH("OPTIONS");
+			break;
 
 /* FOREIGN TABLE */
-	else if (TailMatches("FOREIGN", "TABLE") &&
-			 !TailMatches("CREATE", MatchAny, MatchAny))
+		case TailMatches("FOREIGN", "TABLE"):
+		if (!TailMatches("CREATE", MatchAny, MatchAny))
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables);
+			break;
 
 /* FOREIGN SERVER */
-	else if (TailMatches("FOREIGN", "SERVER"))
+		case TailMatches("FOREIGN", "SERVER"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_servers);
+			break;
 
 /*
  * GRANT and REVOKE are allowed inside CREATE SCHEMA and
  * ALTER DEFAULT PRIVILEGES, so use TailMatches
  */
 	/* Complete GRANT/REVOKE with a list of roles and privileges */
-	else if (TailMatches("GRANT|REVOKE") ||
-			 TailMatches("REVOKE", "ADMIN|GRANT|INHERIT|SET", "OPTION", "FOR"))
-	{
+		case TailMatches("GRANT|REVOKE"):
+		case TailMatches("REVOKE", "ADMIN|GRANT|INHERIT|SET", "OPTION", "FOR"):
 		/*
 		 * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable
 		 * privileges (can't grant roles)
@@ -4197,50 +4611,55 @@ match_previous_words(const char *text, int start, int end,
 			COMPLETE_WITH(Privilege_options_of_grant_and_revoke);
 		else if (TailMatches("REVOKE", "ADMIN|INHERIT|SET", "OPTION", "FOR"))
 			COMPLETE_WITH_QUERY(Query_for_list_of_roles);
-	}
+			break;
 
-	else if (TailMatches("GRANT|REVOKE", "ALTER") ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALTER"))
+		case TailMatches("GRANT|REVOKE", "ALTER"):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALTER"):
 		COMPLETE_WITH("SYSTEM");
+			break;
 
-	else if (TailMatches("REVOKE", "SET"))
+		case TailMatches("REVOKE", "SET"):
 		COMPLETE_WITH("ON PARAMETER", "OPTION FOR");
-	else if (TailMatches("GRANT", "SET") ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "SET") ||
-			 TailMatches("GRANT|REVOKE", "ALTER", "SYSTEM") ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALTER", "SYSTEM"))
+			break;
+		case TailMatches("GRANT", "SET"):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "SET"):
+		case TailMatches("GRANT|REVOKE", "ALTER", "SYSTEM"):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALTER", "SYSTEM"):
 		COMPLETE_WITH("ON PARAMETER");
+			break;
 
-	else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "PARAMETER") ||
-			 TailMatches("GRANT|REVOKE", MatchAny, MatchAny, "ON", "PARAMETER") ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "PARAMETER") ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, MatchAny, "ON", "PARAMETER"))
+		case TailMatches("GRANT|REVOKE", MatchAny, "ON", "PARAMETER"):
+		case TailMatches("GRANT|REVOKE", MatchAny, MatchAny, "ON", "PARAMETER"):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "PARAMETER"):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, MatchAny, "ON", "PARAMETER"):
 		COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_alter_system_set_vars);
+			break;
 
-	else if (TailMatches("GRANT", MatchAny, "ON", "PARAMETER", MatchAny) ||
-			 TailMatches("GRANT", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny))
+		case TailMatches("GRANT", MatchAny, "ON", "PARAMETER", MatchAny):
+		case TailMatches("GRANT", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny):
 		COMPLETE_WITH("TO");
+			break;
 
-	else if (TailMatches("REVOKE", MatchAny, "ON", "PARAMETER", MatchAny) ||
-			 TailMatches("REVOKE", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny) ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "PARAMETER", MatchAny) ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny))
+		case TailMatches("REVOKE", MatchAny, "ON", "PARAMETER", MatchAny):
+		case TailMatches("REVOKE", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "PARAMETER", MatchAny):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny):
 		COMPLETE_WITH("FROM");
+			break;
 
 	/*
 	 * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
 	 * TO/FROM
 	 */
-	else if (TailMatches("GRANT|REVOKE", MatchAny) ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny))
-	{
+		case TailMatches("GRANT|REVOKE", MatchAny):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny):
 		if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|MAINTAIN|ALL"))
 			COMPLETE_WITH("ON");
 		else if (TailMatches("GRANT", MatchAny))
 			COMPLETE_WITH("TO");
 		else
 			COMPLETE_WITH("FROM");
-	}
+			break;
 
 	/*
 	 * Complete GRANT/REVOKE <sth> ON with a list of appropriate relations.
@@ -4249,9 +4668,8 @@ match_previous_words(const char *text, int start, int end,
 	 * here will only work if the privilege list contains exactly one
 	 * privilege.
 	 */
-	else if (TailMatches("GRANT|REVOKE", MatchAny, "ON") ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON"))
-	{
+		case TailMatches("GRANT|REVOKE", MatchAny, "ON"):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON"):
 		/*
 		 * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of
 		 * objects supported.
@@ -4280,17 +4698,19 @@ match_previous_words(const char *text, int start, int end,
 											"TABLE",
 											"TABLESPACE",
 											"TYPE");
-	}
-	else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL") ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL"))
+			break;
+		case TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL"):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL"):
 		COMPLETE_WITH("FUNCTIONS IN SCHEMA",
 					  "PROCEDURES IN SCHEMA",
 					  "ROUTINES IN SCHEMA",
 					  "SEQUENCES IN SCHEMA",
 					  "TABLES IN SCHEMA");
-	else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN") ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN"))
+			break;
+		case TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN"):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN"):
 		COMPLETE_WITH("DATA WRAPPER", "SERVER");
+			break;
 
 	/*
 	 * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
@@ -4298,9 +4718,8 @@ match_previous_words(const char *text, int start, int end,
 	 *
 	 * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
 	 */
-	else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny) ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", MatchAny))
-	{
+		case TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", MatchAny):
 		if (TailMatches("DATABASE"))
 			COMPLETE_WITH_QUERY(Query_for_list_of_databases);
 		else if (TailMatches("DOMAIN"))
@@ -4327,305 +4746,362 @@ match_previous_words(const char *text, int start, int end,
 			COMPLETE_WITH("TO");
 		else
 			COMPLETE_WITH("FROM");
-	}
+			break;
 
 	/*
 	 * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
 	 * CURRENT_ROLE, CURRENT_USER, or SESSION_USER.
 	 */
-	else if (Matches("GRANT", MatchAnyN, "TO") ||
-			 Matches("REVOKE", MatchAnyN, "FROM"))
+		case Matches("GRANT", MatchAnyN, "TO"):
+		case Matches("REVOKE", MatchAnyN, "FROM"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 Keywords_for_list_of_grant_roles);
+			break;
 
 	/*
 	 * Offer grant options after that.
 	 */
-	else if (Matches("GRANT", MatchAnyN, "TO", MatchAny))
+		case Matches("GRANT", MatchAnyN, "TO", MatchAny):
 		COMPLETE_WITH("WITH ADMIN",
 					  "WITH INHERIT",
 					  "WITH SET",
 					  "WITH GRANT OPTION",
 					  "GRANTED BY");
-	else if (Matches("GRANT", MatchAnyN, "TO", MatchAny, "WITH"))
+			break;
+		case Matches("GRANT", MatchAnyN, "TO", MatchAny, "WITH"):
 		COMPLETE_WITH("ADMIN",
 					  "INHERIT",
 					  "SET",
 					  "GRANT OPTION");
-	else if (Matches("GRANT", MatchAnyN, "TO", MatchAny, "WITH", "ADMIN|INHERIT|SET"))
+			break;
+		case Matches("GRANT", MatchAnyN, "TO", MatchAny, "WITH", "ADMIN|INHERIT|SET"):
 		COMPLETE_WITH("OPTION", "TRUE", "FALSE");
-	else if (Matches("GRANT", MatchAnyN, "TO", MatchAny, "WITH", MatchAny, "OPTION"))
+			break;
+		case Matches("GRANT", MatchAnyN, "TO", MatchAny, "WITH", MatchAny, "OPTION"):
 		COMPLETE_WITH("GRANTED BY");
-	else if (Matches("GRANT", MatchAnyN, "TO", MatchAny, "WITH", MatchAny, "OPTION", "GRANTED", "BY"))
+			break;
+		case Matches("GRANT", MatchAnyN, "TO", MatchAny, "WITH", MatchAny, "OPTION", "GRANTED", "BY"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 Keywords_for_list_of_grant_roles);
+			break;
 	/* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", MatchAnyN, "TO|FROM"))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", MatchAnyN, "TO|FROM"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 Keywords_for_list_of_grant_roles);
+			break;
 	/* Offer WITH GRANT OPTION after that */
-	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", MatchAnyN, "TO", MatchAny))
+		case Matches("ALTER", "DEFAULT", "PRIVILEGES", MatchAnyN, "TO", MatchAny):
 		COMPLETE_WITH("WITH GRANT OPTION");
+			break;
 	/* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
-	else if (Matches("GRANT", MatchAnyN, "ON", MatchAny, MatchAny))
+		case Matches("GRANT", MatchAnyN, "ON", MatchAny, MatchAny):
 		COMPLETE_WITH("TO");
-	else if (Matches("REVOKE", MatchAnyN, "ON", MatchAny, MatchAny))
+			break;
+		case Matches("REVOKE", MatchAnyN, "ON", MatchAny, MatchAny):
 		COMPLETE_WITH("FROM");
+			break;
 
 	/* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
-	else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny) ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
-	{
+		case TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny):
 		if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
 			COMPLETE_WITH("TO");
 		else
 			COMPLETE_WITH("FROM");
-	}
+			break;
 
 	/* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
-	else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
-	{
+		case TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny):
 		if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
 			COMPLETE_WITH("TO");
 		else
 			COMPLETE_WITH("FROM");
-	}
+			break;
 
 	/* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
-	else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny) ||
-			 TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
-	{
+		case TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny):
+		case TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny):
 		if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
 			COMPLETE_WITH("TO");
 		else
 			COMPLETE_WITH("FROM");
-	}
+			break;
 
 /* GROUP BY */
-	else if (TailMatches("FROM", MatchAny, "GROUP"))
+		case TailMatches("FROM", MatchAny, "GROUP"):
 		COMPLETE_WITH("BY");
+			break;
 
 /* IMPORT FOREIGN SCHEMA */
-	else if (Matches("IMPORT"))
+		case Matches("IMPORT"):
 		COMPLETE_WITH("FOREIGN SCHEMA");
-	else if (Matches("IMPORT", "FOREIGN"))
+			break;
+		case Matches("IMPORT", "FOREIGN"):
 		COMPLETE_WITH("SCHEMA");
-	else if (Matches("IMPORT", "FOREIGN", "SCHEMA", MatchAny))
+			break;
+		case Matches("IMPORT", "FOREIGN", "SCHEMA", MatchAny):
 		COMPLETE_WITH("EXCEPT (", "FROM SERVER", "LIMIT TO (");
-	else if (TailMatches("LIMIT", "TO", "(*)") ||
-			 TailMatches("EXCEPT", "(*)"))
+			break;
+		case TailMatches("LIMIT", "TO", "(*)"):
+		case TailMatches("EXCEPT", "(*)"):
 		COMPLETE_WITH("FROM SERVER");
-	else if (TailMatches("FROM", "SERVER", MatchAny))
+			break;
+		case TailMatches("FROM", "SERVER", MatchAny):
 		COMPLETE_WITH("INTO");
-	else if (TailMatches("FROM", "SERVER", MatchAny, "INTO"))
+			break;
+		case TailMatches("FROM", "SERVER", MatchAny, "INTO"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
-	else if (TailMatches("FROM", "SERVER", MatchAny, "INTO", MatchAny))
+			break;
+		case TailMatches("FROM", "SERVER", MatchAny, "INTO", MatchAny):
 		COMPLETE_WITH("OPTIONS (");
+			break;
 
 /* INSERT --- can be inside EXPLAIN, RULE, etc */
 	/* Complete NOT MATCHED THEN INSERT */
-	else if (TailMatches("NOT", "MATCHED", "THEN", "INSERT"))
+		case TailMatches("NOT", "MATCHED", "THEN", "INSERT"):
 		COMPLETE_WITH("VALUES", "(");
+			break;
 	/* Complete INSERT with "INTO" */
-	else if (TailMatches("INSERT"))
+		case TailMatches("INSERT"):
 		COMPLETE_WITH("INTO");
+			break;
 	/* Complete INSERT INTO with table names */
-	else if (TailMatches("INSERT", "INTO"))
+		case TailMatches("INSERT", "INTO"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables);
+			break;
 	/* Complete "INSERT INTO <table> (" with attribute names */
-	else if (TailMatches("INSERT", "INTO", MatchAny, "("))
+		case TailMatches("INSERT", "INTO", MatchAny, "("):
 		COMPLETE_WITH_ATTR(prev2_wd);
+			break;
 
 	/*
 	 * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
 	 * "TABLE" or "DEFAULT VALUES" or "OVERRIDING"
 	 */
-	else if (TailMatches("INSERT", "INTO", MatchAny))
+		case TailMatches("INSERT", "INTO", MatchAny):
 		COMPLETE_WITH("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING");
+			break;
 
 	/*
 	 * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
 	 * "TABLE" or "OVERRIDING"
 	 */
-	else if (TailMatches("INSERT", "INTO", MatchAny, MatchAny) &&
-			 ends_with(prev_wd, ')'))
+		case TailMatches("INSERT", "INTO", MatchAny, MatchAny):
+		if (ends_with(prev_wd, ')'))
 		COMPLETE_WITH("SELECT", "TABLE", "VALUES", "OVERRIDING");
+			break;
 
 	/* Complete OVERRIDING */
-	else if (TailMatches("OVERRIDING"))
+		case TailMatches("OVERRIDING"):
 		COMPLETE_WITH("SYSTEM VALUE", "USER VALUE");
+			break;
 
 	/* Complete after OVERRIDING clause */
-	else if (TailMatches("OVERRIDING", MatchAny, "VALUE"))
+		case TailMatches("OVERRIDING", MatchAny, "VALUE"):
 		COMPLETE_WITH("SELECT", "TABLE", "VALUES");
+			break;
 
 	/* Insert an open parenthesis after "VALUES" */
-	else if (TailMatches("VALUES") && !TailMatches("DEFAULT", "VALUES"))
+		case TailMatches("VALUES"):
+		if (!TailMatches("DEFAULT", "VALUES"))
 		COMPLETE_WITH("(");
+			break;
 
 /* LOCK */
 	/* Complete LOCK [TABLE] [ONLY] with a list of tables */
-	else if (Matches("LOCK"))
+		case Matches("LOCK"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables,
 										"TABLE", "ONLY");
-	else if (Matches("LOCK", "TABLE"))
+			break;
+		case Matches("LOCK", "TABLE"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables,
 										"ONLY");
-	else if (Matches("LOCK", "TABLE", "ONLY") || Matches("LOCK", "ONLY"))
+			break;
+		case Matches("LOCK", "TABLE", "ONLY"):
+		case Matches("LOCK", "ONLY"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+			break;
 	/* For the following, handle the case of a single table only for now */
 
 	/* Complete LOCK [TABLE] [ONLY] <table> with IN or NOWAIT */
-	else if (Matches("LOCK", MatchAnyExcept("TABLE|ONLY")) ||
-			 Matches("LOCK", "TABLE", MatchAnyExcept("ONLY")) ||
-			 Matches("LOCK", "ONLY", MatchAny) ||
-			 Matches("LOCK", "TABLE", "ONLY", MatchAny))
+		case Matches("LOCK", MatchAnyExcept("TABLE|ONLY")):
+		case Matches("LOCK", "TABLE", MatchAnyExcept("ONLY")):
+		case Matches("LOCK", "ONLY", MatchAny):
+		case Matches("LOCK", "TABLE", "ONLY", MatchAny):
 		COMPLETE_WITH("IN", "NOWAIT");
+			break;
 
 	/* Complete LOCK [TABLE] [ONLY] <table> IN with a lock mode */
-	else if (Matches("LOCK", MatchAnyN, "IN"))
+		case Matches("LOCK", MatchAnyN, "IN"):
 		COMPLETE_WITH("ACCESS SHARE MODE",
 					  "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
 					  "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
 					  "SHARE ROW EXCLUSIVE MODE",
 					  "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
+			break;
 
 	/*
 	 * Complete LOCK [TABLE][ONLY] <table> IN ACCESS|ROW with rest of lock
 	 * mode
 	 */
-	else if (Matches("LOCK", MatchAnyN, "IN", "ACCESS|ROW"))
+		case Matches("LOCK", MatchAnyN, "IN", "ACCESS|ROW"):
 		COMPLETE_WITH("EXCLUSIVE MODE", "SHARE MODE");
+			break;
 
 	/* Complete LOCK [TABLE] [ONLY] <table> IN SHARE with rest of lock mode */
-	else if (Matches("LOCK", MatchAnyN, "IN", "SHARE"))
+		case Matches("LOCK", MatchAnyN, "IN", "SHARE"):
 		COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE",
 					  "UPDATE EXCLUSIVE MODE");
+			break;
 
 	/* Complete LOCK [TABLE] [ONLY] <table> [IN lockmode MODE] with "NOWAIT" */
-	else if (Matches("LOCK", MatchAnyN, "MODE"))
+		case Matches("LOCK", MatchAnyN, "MODE"):
 		COMPLETE_WITH("NOWAIT");
+			break;
 
 /* MERGE --- can be inside EXPLAIN */
-	else if (TailMatches("MERGE"))
+		case TailMatches("MERGE"):
 		COMPLETE_WITH("INTO");
-	else if (TailMatches("MERGE", "INTO"))
+			break;
+		case TailMatches("MERGE", "INTO"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_mergetargets);
+			break;
 
 	/* Complete MERGE INTO <table> [[AS] <alias>] with USING */
-	else if (TailMatches("MERGE", "INTO", MatchAny))
+		case TailMatches("MERGE", "INTO", MatchAny):
 		COMPLETE_WITH("USING", "AS");
-	else if (TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny) ||
-			 TailMatches("MERGE", "INTO", MatchAny, MatchAnyExcept("USING|AS")))
+			break;
+		case TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny):
+		case TailMatches("MERGE", "INTO", MatchAny, MatchAnyExcept("USING|AS")):
 		COMPLETE_WITH("USING");
+			break;
 
 	/*
 	 * Complete MERGE INTO ... USING with a list of relations supporting
 	 * SELECT
 	 */
-	else if (TailMatches("MERGE", "INTO", MatchAny, "USING") ||
-			 TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING") ||
-			 TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING"))
+		case TailMatches("MERGE", "INTO", MatchAny, "USING"):
+		case TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING"):
+		case TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
+			break;
 
 	/*
 	 * 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))
+		case TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny):
+		case TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny):
+		case 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")))
+			break;
+		case TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny, "AS", MatchAny):
+		case TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny):
+		case TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING", MatchAny, "AS", MatchAny):
+		case TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")):
+		case TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")):
+		case TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")):
 		COMPLETE_WITH("ON");
+			break;
 
 	/* Complete MERGE INTO ... ON with target table attributes */
-	else if (TailMatches("INTO", MatchAny, "USING", MatchAny, "ON"))
+		case TailMatches("INTO", MatchAny, "USING", MatchAny, "ON"):
 		COMPLETE_WITH_ATTR(prev4_wd);
-	else if (TailMatches("INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny, "ON"))
+			break;
+		case TailMatches("INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny, "ON"):
 		COMPLETE_WITH_ATTR(prev8_wd);
-	else if (TailMatches("INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAny, "ON"))
+			break;
+		case TailMatches("INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAny, "ON"):
 		COMPLETE_WITH_ATTR(prev6_wd);
+			break;
 
 	/*
 	 * 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")))
+		case TailMatches("USING", MatchAny, "ON", MatchAny):
+		case TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny):
+		case TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny):
+		case TailMatches("USING", MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")):
+		case TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")):
+		case TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")):
 		COMPLETE_WITH("WHEN MATCHED", "WHEN NOT MATCHED");
-	else if (TailMatches("USING", MatchAny, "ON", MatchAny, "WHEN") ||
-			 TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, "WHEN") ||
-			 TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, "WHEN") ||
-			 TailMatches("USING", MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN") ||
-			 TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN") ||
-			 TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN"))
+			break;
+		case TailMatches("USING", MatchAny, "ON", MatchAny, "WHEN"):
+		case TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, "WHEN"):
+		case TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, "WHEN"):
+		case TailMatches("USING", MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN"):
+		case TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN"):
+		case TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN"):
 		COMPLETE_WITH("MATCHED", "NOT MATCHED");
+			break;
 
 	/*
 	 * Complete ... WHEN MATCHED and WHEN NOT MATCHED BY SOURCE|TARGET with
 	 * THEN/AND
 	 */
-	else if (TailMatches("WHEN", "MATCHED") ||
-			 TailMatches("WHEN", "NOT", "MATCHED", "BY", "SOURCE|TARGET"))
+		case TailMatches("WHEN", "MATCHED"):
+		case TailMatches("WHEN", "NOT", "MATCHED", "BY", "SOURCE|TARGET"):
 		COMPLETE_WITH("THEN", "AND");
+			break;
 
 	/* Complete ... WHEN NOT MATCHED with BY/THEN/AND */
-	else if (TailMatches("WHEN", "NOT", "MATCHED"))
+		case TailMatches("WHEN", "NOT", "MATCHED"):
 		COMPLETE_WITH("BY", "THEN", "AND");
+			break;
 
 	/* Complete ... WHEN NOT MATCHED BY with SOURCE/TARGET */
-	else if (TailMatches("WHEN", "NOT", "MATCHED", "BY"))
+		case TailMatches("WHEN", "NOT", "MATCHED", "BY"):
 		COMPLETE_WITH("SOURCE", "TARGET");
+			break;
 
 	/*
 	 * Complete ... WHEN MATCHED THEN and WHEN NOT MATCHED BY SOURCE THEN with
 	 * UPDATE SET/DELETE/DO NOTHING
 	 */
-	else if (TailMatches("WHEN", "MATCHED", "THEN") ||
-			 TailMatches("WHEN", "NOT", "MATCHED", "BY", "SOURCE", "THEN"))
+		case TailMatches("WHEN", "MATCHED", "THEN"):
+		case TailMatches("WHEN", "NOT", "MATCHED", "BY", "SOURCE", "THEN"):
 		COMPLETE_WITH("UPDATE SET", "DELETE", "DO NOTHING");
+			break;
 
 	/*
 	 * Complete ... WHEN NOT MATCHED [BY TARGET] THEN with INSERT/DO NOTHING
 	 */
-	else if (TailMatches("WHEN", "NOT", "MATCHED", "THEN") ||
-			 TailMatches("WHEN", "NOT", "MATCHED", "BY", "TARGET", "THEN"))
+		case TailMatches("WHEN", "NOT", "MATCHED", "THEN"):
+		case TailMatches("WHEN", "NOT", "MATCHED", "BY", "TARGET", "THEN"):
 		COMPLETE_WITH("INSERT", "DO NOTHING");
+			break;
 
 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
-	else if (TailMatches("NOTIFY"))
+		case TailMatches("NOTIFY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_channels);
+			break;
 
 /* OPTIONS */
-	else if (TailMatches("OPTIONS"))
+		case TailMatches("OPTIONS"):
 		COMPLETE_WITH("(");
+			break;
 
 /* OWNER TO  - complete with available roles */
-	else if (TailMatches("OWNER", "TO"))
+		case TailMatches("OWNER", "TO"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 Keywords_for_list_of_owner_roles);
+			break;
 
 /* ORDER BY */
-	else if (TailMatches("FROM", MatchAny, "ORDER"))
+		case TailMatches("FROM", MatchAny, "ORDER"):
 		COMPLETE_WITH("BY");
-	else if (TailMatches("FROM", MatchAny, "ORDER", "BY"))
+			break;
+		case TailMatches("FROM", MatchAny, "ORDER", "BY"):
 		COMPLETE_WITH_ATTR(prev3_wd);
+			break;
 
 /* PREPARE xx AS */
-	else if (Matches("PREPARE", MatchAny, "AS"))
+		case Matches("PREPARE", MatchAny, "AS"):
 		COMPLETE_WITH("SELECT", "UPDATE", "INSERT INTO", "DELETE FROM");
+			break;
 
 /*
  * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
@@ -4633,74 +5109,98 @@ match_previous_words(const char *text, int start, int end,
  */
 
 /* REASSIGN OWNED BY xxx TO yyy */
-	else if (Matches("REASSIGN"))
+		case Matches("REASSIGN"):
 		COMPLETE_WITH("OWNED BY");
-	else if (Matches("REASSIGN", "OWNED"))
+			break;
+		case Matches("REASSIGN", "OWNED"):
 		COMPLETE_WITH("BY");
-	else if (Matches("REASSIGN", "OWNED", "BY"))
+			break;
+		case Matches("REASSIGN", "OWNED", "BY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
-	else if (Matches("REASSIGN", "OWNED", "BY", MatchAny))
+			break;
+		case Matches("REASSIGN", "OWNED", "BY", MatchAny):
 		COMPLETE_WITH("TO");
-	else if (Matches("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
+			break;
+		case Matches("REASSIGN", "OWNED", "BY", MatchAny, "TO"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
+			break;
 
 /* REFRESH MATERIALIZED VIEW */
-	else if (Matches("REFRESH"))
+		case Matches("REFRESH"):
 		COMPLETE_WITH("MATERIALIZED VIEW");
-	else if (Matches("REFRESH", "MATERIALIZED"))
+			break;
+		case Matches("REFRESH", "MATERIALIZED"):
 		COMPLETE_WITH("VIEW");
-	else if (Matches("REFRESH", "MATERIALIZED", "VIEW"))
+			break;
+		case Matches("REFRESH", "MATERIALIZED", "VIEW"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_matviews,
 										"CONCURRENTLY");
-	else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
+			break;
+		case Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
-	else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
+			break;
+		case Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny):
 		COMPLETE_WITH("WITH");
-	else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
+			break;
+		case Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny):
 		COMPLETE_WITH("WITH");
-	else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
+			break;
+		case Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"):
 		COMPLETE_WITH("NO DATA", "DATA");
-	else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
+			break;
+		case Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"):
 		COMPLETE_WITH("NO DATA", "DATA");
-	else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
+			break;
+		case Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"):
 		COMPLETE_WITH("DATA");
-	else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
+			break;
+		case Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"):
 		COMPLETE_WITH("DATA");
+			break;
 
 /* REINDEX */
-	else if (Matches("REINDEX") ||
-			 Matches("REINDEX", "(*)"))
+		case Matches("REINDEX"):
+		case Matches("REINDEX", "(*)"):
 		COMPLETE_WITH("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
-	else if (Matches("REINDEX", "TABLE") ||
-			 Matches("REINDEX", "(*)", "TABLE"))
+			break;
+		case Matches("REINDEX", "TABLE"):
+		case Matches("REINDEX", "(*)", "TABLE"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexables,
 										"CONCURRENTLY");
-	else if (Matches("REINDEX", "INDEX") ||
-			 Matches("REINDEX", "(*)", "INDEX"))
+			break;
+		case Matches("REINDEX", "INDEX"):
+		case Matches("REINDEX", "(*)", "INDEX"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
 										"CONCURRENTLY");
-	else if (Matches("REINDEX", "SCHEMA") ||
-			 Matches("REINDEX", "(*)", "SCHEMA"))
+			break;
+		case Matches("REINDEX", "SCHEMA"):
+		case Matches("REINDEX", "(*)", "SCHEMA"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas,
 								 "CONCURRENTLY");
-	else if (Matches("REINDEX", "SYSTEM|DATABASE") ||
-			 Matches("REINDEX", "(*)", "SYSTEM|DATABASE"))
+			break;
+		case Matches("REINDEX", "SYSTEM|DATABASE"):
+		case Matches("REINDEX", "(*)", "SYSTEM|DATABASE"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_databases,
 								 "CONCURRENTLY");
-	else if (Matches("REINDEX", "TABLE", "CONCURRENTLY") ||
-			 Matches("REINDEX", "(*)", "TABLE", "CONCURRENTLY"))
+			break;
+		case Matches("REINDEX", "TABLE", "CONCURRENTLY"):
+		case Matches("REINDEX", "(*)", "TABLE", "CONCURRENTLY"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables);
-	else if (Matches("REINDEX", "INDEX", "CONCURRENTLY") ||
-			 Matches("REINDEX", "(*)", "INDEX", "CONCURRENTLY"))
+			break;
+		case Matches("REINDEX", "INDEX", "CONCURRENTLY"):
+		case Matches("REINDEX", "(*)", "INDEX", "CONCURRENTLY"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
-	else if (Matches("REINDEX", "SCHEMA", "CONCURRENTLY") ||
-			 Matches("REINDEX", "(*)", "SCHEMA", "CONCURRENTLY"))
+			break;
+		case Matches("REINDEX", "SCHEMA", "CONCURRENTLY"):
+		case Matches("REINDEX", "(*)", "SCHEMA", "CONCURRENTLY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
-	else if (Matches("REINDEX", "SYSTEM|DATABASE", "CONCURRENTLY") ||
-			 Matches("REINDEX", "(*)", "SYSTEM|DATABASE", "CONCURRENTLY"))
+			break;
+		case Matches("REINDEX", "SYSTEM|DATABASE", "CONCURRENTLY"):
+		case Matches("REINDEX", "(*)", "SYSTEM|DATABASE", "CONCURRENTLY"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_databases);
-	else if (HeadMatches("REINDEX", "(*") &&
-			 !HeadMatches("REINDEX", "(*)"))
+			break;
+		case HeadMatches("REINDEX", "(*"):
+		if (!HeadMatches("REINDEX", "(*)"))
 	{
 		/*
 		 * This fires if we're in an unfinished parenthesized option list.
@@ -4712,30 +5212,37 @@ match_previous_words(const char *text, int start, int end,
 		else if (TailMatches("TABLESPACE"))
 			COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
 	}
+			break;
 
 /* SECURITY LABEL */
-	else if (Matches("SECURITY"))
+		case Matches("SECURITY"):
 		COMPLETE_WITH("LABEL");
-	else if (Matches("SECURITY", "LABEL"))
+			break;
+		case Matches("SECURITY", "LABEL"):
 		COMPLETE_WITH("ON", "FOR");
-	else if (Matches("SECURITY", "LABEL", "FOR", MatchAny))
+			break;
+		case Matches("SECURITY", "LABEL", "FOR", MatchAny):
 		COMPLETE_WITH("ON");
-	else if (Matches("SECURITY", "LABEL", "ON") ||
-			 Matches("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
+			break;
+		case Matches("SECURITY", "LABEL", "ON"):
+		case Matches("SECURITY", "LABEL", "FOR", MatchAny, "ON"):
 		COMPLETE_WITH("TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
 					  "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION",
 					  "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE",
 					  "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA",
 					  "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW");
-	else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
+			break;
+		case Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny):
 		COMPLETE_WITH("IS");
+			break;
 
 /* SELECT */
 	/* naah . . . */
 
 /* SET, RESET, SHOW */
 	/* Complete with a variable name */
-	else if (TailMatches("SET|RESET") && !TailMatches("UPDATE", MatchAny, "SET"))
+		case TailMatches("SET|RESET"):
+		if (!TailMatches("UPDATE", MatchAny, "SET"))
 		COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_set_vars,
 										  "CONSTRAINTS",
 										  "TRANSACTION",
@@ -4743,81 +5250,100 @@ match_previous_words(const char *text, int start, int end,
 										  "ROLE",
 										  "TABLESPACE",
 										  "ALL");
-	else if (Matches("SHOW"))
+			break;
+		case Matches("SHOW"):
 		COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_show_vars,
 										  "SESSION AUTHORIZATION",
 										  "ALL");
-	else if (Matches("SHOW", "SESSION"))
+			break;
+		case Matches("SHOW", "SESSION"):
 		COMPLETE_WITH("AUTHORIZATION");
+			break;
 	/* Complete "SET TRANSACTION" */
-	else if (Matches("SET", "TRANSACTION"))
+		case Matches("SET", "TRANSACTION"):
 		COMPLETE_WITH("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
-	else if (Matches("BEGIN|START", "TRANSACTION") ||
-			 Matches("BEGIN", "WORK") ||
-			 Matches("BEGIN") ||
-			 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
+			break;
+		case Matches("BEGIN|START", "TRANSACTION"):
+		case Matches("BEGIN", "WORK"):
+		case Matches("BEGIN"):
+		case Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"):
 		COMPLETE_WITH("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
-	else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
-			 Matches("BEGIN", "NOT") ||
-			 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
+			break;
+		case Matches("SET|BEGIN|START", "TRANSACTION|WORK", "NOT"):
+		case Matches("BEGIN", "NOT"):
+		case Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"):
 		COMPLETE_WITH("DEFERRABLE");
-	else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
-			 Matches("BEGIN", "ISOLATION") ||
-			 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
+			break;
+		case Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION"):
+		case Matches("BEGIN", "ISOLATION"):
+		case Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"):
 		COMPLETE_WITH("LEVEL");
-	else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
-			 Matches("BEGIN", "ISOLATION", "LEVEL") ||
-			 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
+			break;
+		case Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL"):
+		case Matches("BEGIN", "ISOLATION", "LEVEL"):
+		case Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"):
 		COMPLETE_WITH("READ", "REPEATABLE READ", "SERIALIZABLE");
-	else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
-			 Matches("BEGIN", "ISOLATION", "LEVEL", "READ") ||
-			 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
+			break;
+		case Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ"):
+		case Matches("BEGIN", "ISOLATION", "LEVEL", "READ"):
+		case Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"):
 		COMPLETE_WITH("UNCOMMITTED", "COMMITTED");
-	else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
-			 Matches("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
-			 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
+			break;
+		case Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE"):
+		case Matches("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE"):
+		case Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"):
 		COMPLETE_WITH("READ");
-	else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
-			 Matches("BEGIN", "READ") ||
-			 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
+			break;
+		case Matches("SET|BEGIN|START", "TRANSACTION|WORK", "READ"):
+		case Matches("BEGIN", "READ"):
+		case Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"):
 		COMPLETE_WITH("ONLY", "WRITE");
+			break;
 	/* SET CONSTRAINTS */
-	else if (Matches("SET", "CONSTRAINTS"))
+		case Matches("SET", "CONSTRAINTS"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_constraints_with_schema,
 										"ALL");
+			break;
 	/* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
-	else if (Matches("SET", "CONSTRAINTS", MatchAny))
+		case Matches("SET", "CONSTRAINTS", MatchAny):
 		COMPLETE_WITH("DEFERRED", "IMMEDIATE");
+			break;
 	/* Complete SET ROLE */
-	else if (Matches("SET", "ROLE"))
+		case Matches("SET", "ROLE"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
+			break;
 	/* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
-	else if (Matches("SET", "SESSION"))
+		case Matches("SET", "SESSION"):
 		COMPLETE_WITH("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
+			break;
 	/* Complete SET SESSION AUTHORIZATION with username */
-	else if (Matches("SET", "SESSION", "AUTHORIZATION"))
+		case Matches("SET", "SESSION", "AUTHORIZATION"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 "DEFAULT");
+			break;
 	/* Complete RESET SESSION with AUTHORIZATION */
-	else if (Matches("RESET", "SESSION"))
+		case Matches("RESET", "SESSION"):
 		COMPLETE_WITH("AUTHORIZATION");
+			break;
 	/* Complete SET <var> with "TO" */
-	else if (Matches("SET", MatchAny))
+		case Matches("SET", MatchAny):
 		COMPLETE_WITH("TO");
+			break;
 
 	/*
 	 * Complete ALTER DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER ... SET
 	 * <name>
 	 */
-	else if (Matches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER", MatchAnyN, "SET", MatchAnyExcept("SCHEMA")))
+		case Matches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER", MatchAnyN, "SET", MatchAnyExcept("SCHEMA")):
 		COMPLETE_WITH("FROM CURRENT", "TO");
+			break;
 
 	/*
 	 * Suggest possible variable values in SET variable TO|=, along with the
 	 * preceding ALTER syntaxes.
 	 */
-	else if (TailMatches("SET", MatchAny, "TO|=") &&
-			 !TailMatches("UPDATE", MatchAny, "SET", MatchAny, "TO|="))
+		case TailMatches("SET", MatchAny, "TO|="):
+		if (!TailMatches("UPDATE", MatchAny, "SET", MatchAny, "TO|="))
 	{
 		/* special cased code for individual GUCs */
 		if (TailMatches("DateStyle", "TO|="))
@@ -4863,98 +5389,122 @@ match_previous_words(const char *text, int start, int end,
 			}
 		}
 	}
+			break;
 
 /* START TRANSACTION */
-	else if (Matches("START"))
+		case Matches("START"):
 		COMPLETE_WITH("TRANSACTION");
+			break;
 
 /* TABLE, but not TABLE embedded in other commands */
-	else if (Matches("TABLE"))
+		case Matches("TABLE"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
+			break;
 
 /* TABLESAMPLE */
-	else if (TailMatches("TABLESAMPLE"))
+		case TailMatches("TABLESAMPLE"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
-	else if (TailMatches("TABLESAMPLE", MatchAny))
+			break;
+		case TailMatches("TABLESAMPLE", MatchAny):
 		COMPLETE_WITH("(");
+			break;
 
 /* TRUNCATE */
-	else if (Matches("TRUNCATE"))
+		case Matches("TRUNCATE"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_truncatables,
 										"TABLE", "ONLY");
-	else if (Matches("TRUNCATE", "TABLE"))
+			break;
+		case Matches("TRUNCATE", "TABLE"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_truncatables,
 										"ONLY");
-	else if (Matches("TRUNCATE", MatchAnyN, "ONLY"))
+			break;
+		case Matches("TRUNCATE", MatchAnyN, "ONLY"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_truncatables);
-	else if (Matches("TRUNCATE", MatchAny) ||
-			 Matches("TRUNCATE", "TABLE|ONLY", MatchAny) ||
-			 Matches("TRUNCATE", "TABLE", "ONLY", MatchAny))
+			break;
+		case Matches("TRUNCATE", MatchAny):
+		case Matches("TRUNCATE", "TABLE|ONLY", MatchAny):
+		case Matches("TRUNCATE", "TABLE", "ONLY", MatchAny):
 		COMPLETE_WITH("RESTART IDENTITY", "CONTINUE IDENTITY", "CASCADE", "RESTRICT");
-	else if (Matches("TRUNCATE", MatchAnyN, "IDENTITY"))
+			break;
+		case Matches("TRUNCATE", MatchAnyN, "IDENTITY"):
 		COMPLETE_WITH("CASCADE", "RESTRICT");
+			break;
 
 /* UNLISTEN */
-	else if (Matches("UNLISTEN"))
+		case Matches("UNLISTEN"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_channels, "*");
+			break;
 
 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
 	/* If prev. word is UPDATE suggest a list of tables */
-	else if (TailMatches("UPDATE"))
+		case TailMatches("UPDATE"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables);
+			break;
 	/* Complete UPDATE <table> with "SET" */
-	else if (TailMatches("UPDATE", MatchAny))
+		case TailMatches("UPDATE", MatchAny):
 		COMPLETE_WITH("SET");
+			break;
 	/* Complete UPDATE <table> SET with list of attributes */
-	else if (TailMatches("UPDATE", MatchAny, "SET"))
+		case TailMatches("UPDATE", MatchAny, "SET"):
 		COMPLETE_WITH_ATTR(prev2_wd);
+			break;
 	/* UPDATE <table> SET <attr> = */
-	else if (TailMatches("UPDATE", MatchAny, "SET", MatchAnyExcept("*=")))
+		case TailMatches("UPDATE", MatchAny, "SET", MatchAnyExcept("*=")):
 		COMPLETE_WITH("=");
+			break;
 
 /* USER MAPPING */
-	else if (Matches("ALTER|CREATE|DROP", "USER", "MAPPING"))
+		case Matches("ALTER|CREATE|DROP", "USER", "MAPPING"):
 		COMPLETE_WITH("FOR");
-	else if (Matches("CREATE", "USER", "MAPPING", "FOR"))
+			break;
+		case Matches("CREATE", "USER", "MAPPING", "FOR"):
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
 								 "CURRENT_ROLE",
 								 "CURRENT_USER",
 								 "PUBLIC",
 								 "USER");
-	else if (Matches("ALTER|DROP", "USER", "MAPPING", "FOR"))
+			break;
+		case Matches("ALTER|DROP", "USER", "MAPPING", "FOR"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
-	else if (Matches("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
+			break;
+		case Matches("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny):
 		COMPLETE_WITH("SERVER");
-	else if (Matches("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
+			break;
+		case Matches("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny):
 		COMPLETE_WITH("OPTIONS");
+			break;
 
 /*
  * VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
  * VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
  */
-	else if (Matches("VACUUM"))
+		case Matches("VACUUM"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_vacuumables,
 										"FULL",
 										"FREEZE",
 										"ANALYZE",
 										"VERBOSE");
-	else if (Matches("VACUUM", "FULL"))
+			break;
+		case Matches("VACUUM", "FULL"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_vacuumables,
 										"FREEZE",
 										"ANALYZE",
 										"VERBOSE");
-	else if (Matches("VACUUM", "FREEZE") ||
-			 Matches("VACUUM", "FULL", "FREEZE"))
+			break;
+		case Matches("VACUUM", "FREEZE"):
+		case Matches("VACUUM", "FULL", "FREEZE"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_vacuumables,
 										"VERBOSE",
 										"ANALYZE");
-	else if (Matches("VACUUM", "VERBOSE") ||
-			 Matches("VACUUM", "FULL|FREEZE", "VERBOSE") ||
-			 Matches("VACUUM", "FULL", "FREEZE", "VERBOSE"))
+			break;
+		case Matches("VACUUM", "VERBOSE"):
+		case Matches("VACUUM", "FULL|FREEZE", "VERBOSE"):
+		case Matches("VACUUM", "FULL", "FREEZE", "VERBOSE"):
 		COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_vacuumables,
 										"ANALYZE");
-	else if (HeadMatches("VACUUM", "(*") &&
-			 !HeadMatches("VACUUM", "(*)"))
+			break;
+		case HeadMatches("VACUUM", "(*"):
+		if (!HeadMatches("VACUUM", "(*)"))
 	{
 		/*
 		 * This fires if we're in an unfinished parenthesized option list.
@@ -4972,11 +5522,14 @@ match_previous_words(const char *text, int start, int end,
 		else if (TailMatches("INDEX_CLEANUP"))
 			COMPLETE_WITH("AUTO", "ON", "OFF");
 	}
-	else if (Matches("VACUUM", MatchAnyN, "("))
+			break;
+		case Matches("VACUUM", MatchAnyN, "("):
 		/* "VACUUM (" should be caught above, so assume we want columns */
 		COMPLETE_WITH_ATTR(prev2_wd);
-	else if (HeadMatches("VACUUM"))
+			break;
+		case HeadMatches("VACUUM"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables);
+			break;
 
 /* WITH [RECURSIVE] */
 
@@ -4984,139 +5537,186 @@ match_previous_words(const char *text, int start, int end,
 	 * Only match when WITH is the first word, as WITH may appear in many
 	 * other contexts.
 	 */
-	else if (Matches("WITH"))
+		case Matches("WITH"):
 		COMPLETE_WITH("RECURSIVE");
+			break;
 
 /* WHERE */
 	/* Simple case of the word before the where being the table name */
-	else if (TailMatches(MatchAny, "WHERE"))
+		case TailMatches(MatchAny, "WHERE"):
 		COMPLETE_WITH_ATTR(prev2_wd);
+			break;
 
 /* ... FROM ... */
 /* TODO: also include SRF ? */
-	else if (TailMatches("FROM") && !Matches("COPY|\\copy", MatchAny, "FROM"))
+		case TailMatches("FROM"):
+		if (!Matches("COPY|\\copy", MatchAny, "FROM"))
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
+			break;
 
 /* ... JOIN ... */
-	else if (TailMatches("JOIN"))
+		case TailMatches("JOIN"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
+			break;
 
 /* ... AT [ LOCAL | TIME ZONE ] ... */
-	else if (TailMatches("AT"))
+		case TailMatches("AT"):
 		COMPLETE_WITH("LOCAL", "TIME ZONE");
-	else if (TailMatches("AT", "TIME", "ZONE"))
+			break;
+		case TailMatches("AT", "TIME", "ZONE"):
 		COMPLETE_WITH_TIMEZONE_NAME();
+			break;
 
 /* Backslash commands */
 /* TODO:  \dc \dd \dl */
-	else if (TailMatchesCS("\\?"))
+		case TailMatchesCS("\\?"):
 		COMPLETE_WITH_CS("commands", "options", "variables");
-	else if (TailMatchesCS("\\connect|\\c"))
-	{
+			break;
+		case TailMatchesCS("\\connect|\\c"):
 		if (!recognized_connection_string(text))
 			COMPLETE_WITH_QUERY(Query_for_list_of_databases);
-	}
-	else if (TailMatchesCS("\\connect|\\c", MatchAny))
-	{
+			break;
+		case TailMatchesCS("\\connect|\\c", MatchAny):
 		if (!recognized_connection_string(prev_wd))
 			COMPLETE_WITH_QUERY(Query_for_list_of_roles);
-	}
-	else if (TailMatchesCS("\\da*"))
+			break;
+		case TailMatchesCS("\\da*"):
 		COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates);
-	else if (TailMatchesCS("\\dAc*", MatchAny) ||
-			 TailMatchesCS("\\dAf*", MatchAny))
+			break;
+		case TailMatchesCS("\\dAc*", MatchAny):
+		case TailMatchesCS("\\dAf*", MatchAny):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
-	else if (TailMatchesCS("\\dAo*", MatchAny) ||
-			 TailMatchesCS("\\dAp*", MatchAny))
+			break;
+		case TailMatchesCS("\\dAo*", MatchAny):
+		case TailMatchesCS("\\dAp*", MatchAny):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_operator_families);
-	else if (TailMatchesCS("\\dA*"))
+			break;
+		case TailMatchesCS("\\dA*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
-	else if (TailMatchesCS("\\db*"))
+			break;
+		case TailMatchesCS("\\db*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
-	else if (TailMatchesCS("\\dconfig*"))
+			break;
+		case TailMatchesCS("\\dconfig*"):
 		COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_show_vars);
-	else if (TailMatchesCS("\\dD*"))
+			break;
+		case TailMatchesCS("\\dD*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains);
-	else if (TailMatchesCS("\\des*"))
+			break;
+		case TailMatchesCS("\\des*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_servers);
-	else if (TailMatchesCS("\\deu*"))
+			break;
+		case TailMatchesCS("\\deu*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
-	else if (TailMatchesCS("\\dew*"))
+			break;
+		case TailMatchesCS("\\dew*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
-	else if (TailMatchesCS("\\df*"))
+			break;
+		case TailMatchesCS("\\df*"):
 		COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions);
-	else if (HeadMatchesCS("\\df*"))
+			break;
+		case HeadMatchesCS("\\df*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
+			break;
 
-	else if (TailMatchesCS("\\dFd*"))
+		case TailMatchesCS("\\dFd*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_dictionaries);
-	else if (TailMatchesCS("\\dFp*"))
+			break;
+		case TailMatchesCS("\\dFp*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_parsers);
-	else if (TailMatchesCS("\\dFt*"))
+			break;
+		case TailMatchesCS("\\dFt*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_templates);
+			break;
 	/* must be at end of \dF alternatives: */
-	else if (TailMatchesCS("\\dF*"))
+		case TailMatchesCS("\\dF*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_configurations);
+			break;
 
-	else if (TailMatchesCS("\\di*"))
+		case TailMatchesCS("\\di*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
-	else if (TailMatchesCS("\\dL*"))
+			break;
+		case TailMatchesCS("\\dL*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_languages);
-	else if (TailMatchesCS("\\dn*"))
+			break;
+		case TailMatchesCS("\\dn*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
+			break;
 	/* no support for completing operators, but we can complete types: */
-	else if (HeadMatchesCS("\\do*", MatchAny))
+		case HeadMatchesCS("\\do*", MatchAny):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
-	else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z"))
+			break;
+		case TailMatchesCS("\\dp"):
+		case TailMatchesCS("\\z"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables);
-	else if (TailMatchesCS("\\dPi*"))
+			break;
+		case TailMatchesCS("\\dPi*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_indexes);
-	else if (TailMatchesCS("\\dPt*"))
+			break;
+		case TailMatchesCS("\\dPt*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables);
-	else if (TailMatchesCS("\\dP*"))
+			break;
+		case TailMatchesCS("\\dP*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_relations);
-	else if (TailMatchesCS("\\dRp*"))
+			break;
+		case TailMatchesCS("\\dRp*"):
 		COMPLETE_WITH_VERSIONED_QUERY(Query_for_list_of_publications);
-	else if (TailMatchesCS("\\dRs*"))
+			break;
+		case TailMatchesCS("\\dRs*"):
 		COMPLETE_WITH_VERSIONED_QUERY(Query_for_list_of_subscriptions);
-	else if (TailMatchesCS("\\ds*"))
+			break;
+		case TailMatchesCS("\\ds*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences);
-	else if (TailMatchesCS("\\dt*"))
+			break;
+		case TailMatchesCS("\\dt*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
-	else if (TailMatchesCS("\\dT*"))
+			break;
+		case TailMatchesCS("\\dT*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
-	else if (TailMatchesCS("\\du*") ||
-			 TailMatchesCS("\\dg*") ||
-			 TailMatchesCS("\\drg*"))
+			break;
+		case TailMatchesCS("\\du*"):
+		case TailMatchesCS("\\dg*"):
+		case TailMatchesCS("\\drg*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
-	else if (TailMatchesCS("\\dv*"))
+			break;
+		case TailMatchesCS("\\dv*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
-	else if (TailMatchesCS("\\dx*"))
+			break;
+		case TailMatchesCS("\\dx*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
-	else if (TailMatchesCS("\\dX*"))
+			break;
+		case TailMatchesCS("\\dX*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_statistics);
-	else if (TailMatchesCS("\\dm*"))
+			break;
+		case TailMatchesCS("\\dm*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
-	else if (TailMatchesCS("\\dE*"))
+			break;
+		case TailMatchesCS("\\dE*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables);
-	else if (TailMatchesCS("\\dy*"))
+			break;
+		case TailMatchesCS("\\dy*"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
+			break;
 
 	/* must be at end of \d alternatives: */
-	else if (TailMatchesCS("\\d*"))
+		case TailMatchesCS("\\d*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations);
+			break;
 
-	else if (TailMatchesCS("\\ef"))
+		case TailMatchesCS("\\ef"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines);
-	else if (TailMatchesCS("\\ev"))
+			break;
+		case TailMatchesCS("\\ev"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
+			break;
 
-	else if (TailMatchesCS("\\encoding"))
+		case TailMatchesCS("\\encoding"):
 		COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_encodings);
-	else if (TailMatchesCS("\\h|\\help"))
+			break;
+		case TailMatchesCS("\\h|\\help"):
 		COMPLETE_WITH_LIST(sql_commands);
-	else if (TailMatchesCS("\\h|\\help", MatchAny))
-	{
+			break;
+		case TailMatchesCS("\\h|\\help", MatchAny):
 		if (TailMatches("DROP"))
 			matches = rl_completion_matches(text, drop_command_generator);
 		else if (TailMatches("ALTER"))
@@ -5126,9 +5726,8 @@ match_previous_words(const char *text, int start, int end,
 		 * CREATE is recognized by tail match elsewhere, so doesn't need to be
 		 * repeated here
 		 */
-	}
-	else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny))
-	{
+			break;
+		case TailMatchesCS("\\h|\\help", MatchAny, MatchAny):
 		if (TailMatches("CREATE|DROP", "ACCESS"))
 			COMPLETE_WITH("METHOD");
 		else if (TailMatches("ALTER", "DEFAULT"))
@@ -5145,21 +5744,23 @@ match_previous_words(const char *text, int start, int end,
 			COMPLETE_WITH("SEARCH");
 		else if (TailMatches("CREATE|ALTER|DROP", "USER"))
 			COMPLETE_WITH("MAPPING FOR");
-	}
-	else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny, MatchAny))
-	{
+			break;
+		case TailMatchesCS("\\h|\\help", MatchAny, MatchAny, MatchAny):
 		if (TailMatches("CREATE|ALTER|DROP", "FOREIGN", "DATA"))
 			COMPLETE_WITH("WRAPPER");
 		else if (TailMatches("CREATE|ALTER|DROP", "TEXT", "SEARCH"))
 			COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
 		else if (TailMatches("CREATE|ALTER|DROP", "USER", "MAPPING"))
 			COMPLETE_WITH("FOR");
-	}
-	else if (TailMatchesCS("\\l*") && !TailMatchesCS("\\lo*"))
+			break;
+		case TailMatchesCS("\\l*"):
+		if (!TailMatchesCS("\\lo*"))
 		COMPLETE_WITH_QUERY(Query_for_list_of_databases);
-	else if (TailMatchesCS("\\password"))
+			break;
+		case TailMatchesCS("\\password"):
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
-	else if (TailMatchesCS("\\pset"))
+			break;
+		case TailMatchesCS("\\pset"):
 		COMPLETE_WITH_CS("border", "columns", "csv_fieldsep", "expanded",
 						 "fieldsep", "fieldsep_zero", "footer", "format",
 						 "linestyle", "null", "numericlocale",
@@ -5170,8 +5771,8 @@ match_previous_words(const char *text, int start, int end,
 						 "unicode_column_linestyle",
 						 "unicode_header_linestyle",
 						 "xheader_width");
-	else if (TailMatchesCS("\\pset", MatchAny))
-	{
+			break;
+		case TailMatchesCS("\\pset", MatchAny):
 		if (TailMatchesCS("format"))
 			COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex",
 							 "latex-longtable", "troff-ms", "unaligned",
@@ -5186,13 +5787,14 @@ match_previous_words(const char *text, int start, int end,
 							   "unicode_column_linestyle|"
 							   "unicode_header_linestyle"))
 			COMPLETE_WITH_CS("single", "double");
-	}
-	else if (TailMatchesCS("\\unset"))
+			break;
+		case TailMatchesCS("\\unset"):
 		matches = complete_from_variables(text, "", "", true);
-	else if (TailMatchesCS("\\set"))
+			break;
+		case TailMatchesCS("\\set"):
 		matches = complete_from_variables(text, "", "", false);
-	else if (TailMatchesCS("\\set", MatchAny))
-	{
+			break;
+		case TailMatchesCS("\\set", MatchAny):
 		if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|SHOW_ALL_RESULTS|"
 						  "SINGLELINE|SINGLESTEP"))
 			COMPLETE_WITH_CS("on", "off");
@@ -5212,18 +5814,18 @@ match_previous_words(const char *text, int start, int end,
 			COMPLETE_WITH_CS("never", "errors", "always");
 		else if (TailMatchesCS("VERBOSITY"))
 			COMPLETE_WITH_CS("default", "verbose", "terse", "sqlstate");
-	}
-	else if (TailMatchesCS("\\sf*"))
+			break;
+		case TailMatchesCS("\\sf*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines);
-	else if (TailMatchesCS("\\sv*"))
+			break;
+		case TailMatchesCS("\\sv*"):
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
-	else if (TailMatchesCS("\\cd|\\e|\\edit|\\g|\\gx|\\i|\\include|"
-						   "\\ir|\\include_relative|\\o|\\out|"
-						   "\\s|\\w|\\write|\\lo_import"))
-	{
+			break;
+		case TailMatchesCS("\\cd|\\e|\\edit|\\g|\\gx|\\i|\\include|\\ir|\\include_relative|\\o|\\out|\\s|\\w|\\write|\\lo_import"):
 		completion_charp = "\\";
 		completion_force_quote = false;
 		matches = rl_completion_matches(text, complete_from_files);
+			break;
 	}
 
 	return matches;
-- 
2.43.5

