From b657b3d1a31af927231a7d51002d00d830f473b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Tue, 8 Jul 2025 19:21:59 +0100
Subject: [PATCH 1/3] Improve tab completion around GRANT/REVOKE ... ON LARGE
 OBJECT

Because large objects are the only two-word object type, it was
completing with TO or FROM immediately after LARGE OBJECT, not after
having entered the OID.
---
 src/bin/psql/tab-complete.in.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index 53e7d35fe98..fe97179b979 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -4531,6 +4531,8 @@ match_previous_words(int pattern_id,
 			COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions);
 		else if (TailMatches("LANGUAGE"))
 			COMPLETE_WITH_QUERY(Query_for_list_of_languages);
+		else if (TailMatches("LARGE"))
+			COMPLETE_WITH("OBJECT");
 		else if (TailMatches("PROCEDURE"))
 			COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures);
 		else if (TailMatches("ROUTINE"))
@@ -4589,9 +4591,11 @@ match_previous_words(int pattern_id,
 	else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", MatchAnyN, "TO", MatchAny))
 		COMPLETE_WITH("WITH GRANT OPTION");
 	/* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
-	else if (Matches("GRANT", MatchAnyN, "ON", MatchAny, MatchAny))
+	else if (Matches("GRANT", MatchAnyN, "ON", MatchAny, MatchAny) ||
+			 Matches("GRANT", MatchAnyN, "ON", "LARGE", "OBJECT", MatchAny))
 		COMPLETE_WITH("TO");
-	else if (Matches("REVOKE", MatchAnyN, "ON", MatchAny, MatchAny))
+	else if (Matches("REVOKE", MatchAnyN, "ON", MatchAny, MatchAny) ||
+			 Matches("REVOKE", MatchAnyN, "ON", "LARGE", "OBJECT", MatchAny))
 		COMPLETE_WITH("FROM");
 
 	/* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
-- 
2.50.0

