[Patch]Add tab completion for DELETE ... USING
Hi,
I noticed that tab completion for DELETE ... USING clause was not
implemented. There was a TODO comment in tab-complete.in.c:
/* XXX: implement tab completion for DELETE ... USING */
The attached patch implements this feature. The following completions are
now supported:
DELETE FROM <table> USING <TAB> -> suggests a list of tables
DELETE FROM <table> USING <table> <TAB> -> suggests AS, WHERE
DELETE FROM <table> USING <table> AS <alias> <TAB> -> suggests WHERE
DELETE FROM <table> USING <table> <alias> <TAB> -> suggests WHERE (without
AS keyword)
I've also added tests for all these cases in 010_tab_completion.pl.
Regards,
Tatsuya Kawata
Attachments:
v1-0001-Add-tab-completion-for-DELETE-USING.patchapplication/octet-stream; name=v1-0001-Add-tab-completion-for-DELETE-USING.patchDownload
From a7d1fd0c316086847693e7f780a8199f7f44c120 Mon Sep 17 00:00:00 2001
From: TatsuyaKawata <kawatatatsuya0913@gmail.com>
Date: Fri, 26 Dec 2025 00:33:34 +0900
Subject: [PATCH v1] 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
---
src/bin/psql/t/010_tab_completion.pl | 30 ++++++++++++++++++++++++++++
src/bin/psql/tab-complete.in.c | 13 +++++++++++-
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/src/bin/psql/t/010_tab_completion.pl b/src/bin/psql/t/010_tab_completion.pl
index fa7427af8c5..9e3e92f42a2 100644
--- a/src/bin/psql/t/010_tab_completion.pl
+++ b/src/bin/psql/t/010_tab_completion.pl
@@ -423,6 +423,36 @@ check_completion(
clear_line();
+# check DELETE ... USING completion
+check_completion(
+ "DELETE FROM tab1 USING my\t",
+ qr/mytab/,
+ "complete DELETE FROM tab USING 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();
+
+check_completion(
+ "DELETE FROM tab1 USING mytab123 AS a \t",
+ qr/WHERE /,
+ "complete DELETE FROM tab USING tab AS alias with WHERE");
+
+clear_query();
+
+check_completion(
+ "DELETE FROM tab1 USING mytab123 a \t",
+ qr/WHERE /,
+ "complete DELETE FROM tab USING tab alias with 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 ab2712216b5..964da197ec6 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -4254,7 +4254,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
On Dec 25, 2025, at 23:51, Tatsuya Kawata <kawatatatsuya0913@gmail.com> wrote:
Hi,
I noticed that tab completion for DELETE ... USING clause was not implemented. There was a TODO comment in tab-complete.in.c:
/* XXX: implement tab completion for DELETE ... USING */
The attached patch implements this feature. The following completions are now supported:DELETE FROM <table> USING <TAB> -> suggests a list of tables
DELETE FROM <table> USING <table> <TAB> -> suggests AS, WHERE
DELETE FROM <table> USING <table> AS <alias> <TAB> -> suggests WHERE
DELETE FROM <table> USING <table> <alias> <TAB> -> suggests WHERE (without AS keyword)I've also added tests for all these cases in 010_tab_completion.pl.
Regards,
Tatsuya Kawata
<v1-0001-Add-tab-completion-for-DELETE-USING.patch>
Overall looks good to me. A very tiny nitpick:
Firs the first case:
```
+# check DELETE ... USING completion
+check_completion(
+ "DELETE FROM tab1 USING my\t",
+ qr/mytab/,
+ "complete DELETE FROM tab USING with table name");
```
Maybe just say “with tab”, because the rest test cases’ messages all say “USING tab”.
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
Hi Chao-san,
Thank you very much for your review!
Firs the first case: ``` +# check DELETE ... USING completion +check_completion( + "DELETE FROM tab1 USING my\t", + qr/mytab/, + "complete DELETE FROM tab USING with table name"); ```Maybe just say “with tab”, because the rest test cases’ messages all say
“USING tab”.
I fixed it as you mentioned.
The updated v2 is attached.
Regards,
Tatsuya Kawata
Attachments:
v2-0001-Add-tab-completion-for-DELETE-USING.patchapplication/octet-stream; name=v2-0001-Add-tab-completion-for-DELETE-USING.patchDownload
From aa89fa476c8144bc621a0db18a71f0134c3fd814 Mon Sep 17 00:00:00 2001
From: TatsuyaKawata <kawatatatsuya0913@gmail.com>
Date: Sat, 27 Dec 2025 09:39:03 +0900
Subject: [PATCH v2] 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
---
src/bin/psql/t/010_tab_completion.pl | 30 ++++++++++++++++++++++++++++
src/bin/psql/tab-complete.in.c | 13 +++++++++++-
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/src/bin/psql/t/010_tab_completion.pl b/src/bin/psql/t/010_tab_completion.pl
index fa7427af8c5..3ca2669212c 100644
--- a/src/bin/psql/t/010_tab_completion.pl
+++ b/src/bin/psql/t/010_tab_completion.pl
@@ -423,6 +423,36 @@ 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();
+
+check_completion(
+ "DELETE FROM tab1 USING mytab123 AS a \t",
+ qr/WHERE /,
+ "complete DELETE FROM tab USING tab AS alias with WHERE");
+
+clear_query();
+
+check_completion(
+ "DELETE FROM tab1 USING mytab123 a \t",
+ qr/WHERE /,
+ "complete DELETE FROM tab USING tab alias with 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 ab2712216b5..964da197ec6 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -4254,7 +4254,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
On Sat, 27 Dec 2025 at 05:50, Tatsuya Kawata
<kawatatatsuya0913@gmail.com> wrote:
Hi Chao-san,
Thank you very much for your review!
Firs the first case: ``` +# check DELETE ... USING completion +check_completion( + "DELETE FROM tab1 USING my\t", + qr/mytab/, + "complete DELETE FROM tab USING with table name"); ```Maybe just say “with tab”, because the rest test cases’ messages all say “USING tab”.
I fixed it as you mentioned.
The updated v2 is attached.Regards,
Tatsuya Kawata
HI! What makes you think we need additional tab completion tests at all?
If we consult src/bin/psql changes history [0]https://github.com/postgres/postgres/commits/master/src/bin/psql, it can be easily seen
that not every change to tab-complete.in.c is made with a new test.
This is (my own understanding, I may be wrong) because we only need to
test tab-complete patterns that are functionally different, not mirror
all cases from tab-complete.in.c in the TAP test.
WDYT?
[0]: https://github.com/postgres/postgres/commits/master/src/bin/psql
--
Best regards,
Kirill Reshke
Hi!
Thank you for your review!
HI! What makes you think we need additional tab completion tests at all?
If we consult src/bin/psql changes history [0], it can be easily seen
that not every change to tab-complete.in.c is made with a new test.
This is (my own understanding, I may be wrong) because we only need to
test tab-complete patterns that are functionally different, not mirror
all cases from tab-complete.in.c in the TAP test.
I agree that not every tab-complete change requires tests, and we don't
need to mirror all cases from tab-complete.in.c. I also think tests that
provide little benefit compared to their maintenance cost can be omitted.
However, since this patch implements a previously unimplemented feature
(removing a XXX TODO comment), I believe the primary test cases should be
kept to verify the core functionality and prevent regressions.
That said, I can reduce the test cases. The current 4 tests could be
reduced to 2:
One for USING <TAB> (core functionality: table completion)
One for USING <table> <TAB> (keyword completion after table)
WDYT?
Regards,
Tatsuya Kawata
Hi!
The updated v3 patch is attached as above.
Just reduced test cases.
Regards,
Tatsuya Kawata
Attachments:
v3-0001-Add-tab-completion-for-DELETE-USING.patchapplication/octet-stream; name=v3-0001-Add-tab-completion-for-DELETE-USING.patchDownload
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
On Sun, 11 Jan 2026 at 12:35, Tatsuya Kawata
<kawatatatsuya0913@gmail.com> wrote:
Hi!
The updated v3 patch is attached as above.
Just reduced test cases.Regards,
Tatsuya Kawata
Hi!
Sorry for the long response, no more complaints from my side.
I have changed CF entry status to Ready FC
--
Best regards,
Kirill Reshke