From 0f2f82df0a287098601721466894558442d6ab5d Mon Sep 17 00:00:00 2001
From: TatsuyaKawata <kawatatatsuya0913@gmail.com>
Date: Sun, 11 Jan 2026 16:25:11 +0900
Subject: [PATCH v3] Add tab completion for DELETE USING

This implements the tab completion that was marked as XXX TODO in the
source code. The following completions are now supported:

- DELETE FROM <table> USING <TAB> -> list of tables
- DELETE FROM <table> USING <table> <TAB> -> AS, WHERE
- DELETE FROM <table> USING <table> AS <alias> <TAB> -> WHERE
- DELETE FROM <table> USING <table> <alias> <TAB> -> WHERE

Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CALdSSPg8WGhfcaH-HUBU-CPjWQpKmsK1tw0O5S7cMnkPd8Scow%40mail.gmail.com#41f8e54a7cbb53120f761e719464be32
---
 src/bin/psql/t/010_tab_completion.pl | 16 ++++++++++++++++
 src/bin/psql/tab-complete.in.c       | 13 ++++++++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/bin/psql/t/010_tab_completion.pl b/src/bin/psql/t/010_tab_completion.pl
index 7104aba2394..c55dc5561f4 100644
--- a/src/bin/psql/t/010_tab_completion.pl
+++ b/src/bin/psql/t/010_tab_completion.pl
@@ -423,6 +423,22 @@ check_completion(
 
 clear_line();
 
+# check DELETE ... USING completion
+check_completion(
+	"DELETE FROM tab1 USING my\t",
+	qr/mytab/,
+	"complete DELETE FROM tab USING tab with table name");
+
+clear_query();
+
+# some versions of readline/libedit require two tabs here, some only need one
+check_completion(
+	"DELETE FROM tab1 USING mytab123 \t\t",
+	qr/AS +WHERE/,
+	"complete DELETE FROM tab USING tab with AS or WHERE");
+
+clear_query();
+
 # send psql an explicit \q to shut it down, else pty won't close properly
 $h->quit or die "psql returned $?";
 
diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index 8b91bc00062..4ed846524ef 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -4266,7 +4266,18 @@ match_previous_words(int pattern_id,
 	/* Complete DELETE FROM <table> */
 	else if (TailMatches("DELETE", "FROM", MatchAny))
 		COMPLETE_WITH("USING", "WHERE");
-	/* XXX: implement tab completion for DELETE ... USING */
+	/* Complete DELETE FROM <table> USING with a list of tables */
+	else if (TailMatches("DELETE", "FROM", MatchAny, "USING"))
+		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
+	/* Complete DELETE FROM <table> USING <table> */
+	else if (TailMatches("DELETE", "FROM", MatchAny, "USING", MatchAny))
+		COMPLETE_WITH("AS", "WHERE");
+	/* Complete DELETE FROM <table> USING <table> AS <alias> */
+	else if (TailMatches("DELETE", "FROM", MatchAny, "USING", MatchAny, "AS", MatchAny))
+		COMPLETE_WITH("WHERE");
+	/* Complete DELETE FROM <table> USING <table> <alias> (without AS) */
+	else if (TailMatches("DELETE", "FROM", MatchAny, "USING", MatchAny, MatchAnyExcept("AS|WHERE")))
+		COMPLETE_WITH("WHERE");
 
 /* DISCARD */
 	else if (Matches("DISCARD"))
-- 
2.34.1

