From 824f0e9352f9876ee807993e850e1eecb8a75556 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Mon, 26 Dec 2016 10:56:30 +0900
Subject: [PATCH 16/17] Simplify completion for ALTER DEFAULT PRIVILEGES.

Simplify completion for ALTER DEFAULT PRIVILEGES. This patch
additionally allows to appear IN SCHEMA and FOR ROLE in arbitrary
order.
---
 src/bin/psql/tab-complete.c | 63 ++++++++++++++++++++++++++++++---------------
 1 file changed, 42 insertions(+), 21 deletions(-)

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 71bfcc9..b69e278 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -999,7 +999,10 @@ typedef enum
 {
 	CMPL_CTX_NONE,
 	CMPL_CTX_CREATE_SCHEMA,
-	CMPL_CTX_ALTER_DEFAULT_PRIV
+	CMPL_CTX_ALTER_DEFAULT_PRIV,
+	CMPL_CTX_ALT_DEF_PRIV_FORROLE,
+	CMPL_CTX_ALT_DEF_PRIV_INSCHEMA,
+	CMPL_CTX_ALT_DEF_PRIV_BOTH
 } completion_context;
 
 
@@ -1294,33 +1297,51 @@ psql_completion_internal(const char *text, char **previous_words,
 	if (Matches4("ALTER", "USER|ROLE", MatchAny, "ENCRYPTED|UNENCRYPTED"))
 		COMPLETE_WITH_CONST("PASSWORD");
 	/* ALTER DEFAULT PRIVILEGES */
+
+	if (Matches2("ALTER", "DEFAULT"))
+		COMPLETE_WITH_CONST("PRIVILEGES");
+
+	/* Remove intermediate words. These two phrases can appear in arbitrary
+	 * order, but assuming that each one appears once.
+	 */
+	if(HeadMatchAndRemove6(4, 3, "ALTER", "DEFAULT", "PRIVILEGES",
+						   "FOR", "ROLE|USER", MatchAny))
+		cmp_ctx = CMPL_CTX_ALT_DEF_PRIV_FORROLE;
+	if(HeadMatchAndRemove6(4, 3, "ALTER", "DEFAULT", "PRIVILEGES",
+						   "IN", "SCHEMA", MatchAny))
+		cmp_ctx = (cmp_ctx == CMPL_CTX_ALT_DEF_PRIV_FORROLE ?
+				   CMPL_CTX_ALT_DEF_PRIV_BOTH : CMPL_CTX_ALT_DEF_PRIV_INSCHEMA);
+	if(cmp_ctx == CMPL_CTX_ALT_DEF_PRIV_INSCHEMA &&
+	   HeadMatchAndRemove6(4, 3, "ALTER", "DEFAULT", "PRIVILEGES",
+						   "FOR", "ROLE|USER", MatchAny))
+		cmp_ctx = CMPL_CTX_ALT_DEF_PRIV_BOTH;
+
+	/* ALTER DEFAULT PRIVILEGES ... IN SCHEMA/FOR ROLE/GRANT/REVOKE */
 	if (Matches3("ALTER", "DEFAULT", "PRIVILEGES"))
-		COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA");
+	{
+		switch (cmp_ctx)
+		{
+		case CMPL_CTX_ALT_DEF_PRIV_INSCHEMA:
+			COMPLETE_WITH_LIST3("FOR ROLE", "GRANT", "REVOKE");
+			break;
+		case CMPL_CTX_ALT_DEF_PRIV_FORROLE:
+			COMPLETE_WITH_LIST3("IN SCHEMA", "GRANT", "REVOKE");
+			break;
+		case CMPL_CTX_ALT_DEF_PRIV_BOTH:
+			COMPLETE_WITH_LIST2("GRANT", "REVOKE");
+			break;
+		default:
+			COMPLETE_WITH_LIST4("FOR ROLE", "IN SCHEMA", "GRANT", "REVOKE");
+			break;
+		}
+	}
 	/* ALTER DEFAULT PRIVILEGES FOR */
 	if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
 		COMPLETE_WITH_CONST("ROLE");
 	/* ALTER DEFAULT PRIVILEGES IN */
 	if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
 		COMPLETE_WITH_CONST("SCHEMA");
-	/* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
-	if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
-				MatchAny))
-		COMPLETE_WITH_LIST3("GRANT", "REVOKE", "IN SCHEMA");
-	/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
-	if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
-				MatchAny))
-		COMPLETE_WITH_LIST3("GRANT", "REVOKE", "FOR ROLE");
-	/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
-	if (Matches7("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
-				MatchAny, "FOR"))
-		COMPLETE_WITH_CONST("ROLE");
-	/* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
-	/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
-	if (Matches9("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
-					MatchAny, "IN", "SCHEMA", MatchAny) ||
-		Matches9("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
-					MatchAny, "FOR", "ROLE|USER", MatchAny))
-		COMPLETE_WITH_LIST2("GRANT", "REVOKE");
+
 	/* ALTER DOMAIN <name> */
 	if (Matches3("ALTER", "DOMAIN", MatchAny))
 		COMPLETE_WITH_LIST6("ADD", "DROP", "OWNER TO", "RENAME", "SET",
-- 
2.9.2

