From 710474f3dcb41c6078751921566659d6ab0826dd Mon Sep 17 00:00:00 2001 From: reshke Date: Thu, 17 Sep 2026 22:58:36 +0300 Subject: [PATCH v1] psql: Fix tab completion for COMMENT/SECURITY LABEL on multi-word targets COMMENT ON and SECURITY LABEL ON tab completion suggested IS immediately after LARGE OBJECT, EVENT TRIGGER, FOREIGN TABLE, and MATERIALIZED VIEW, without the required object name or OID. --- src/bin/psql/tab-complete.in.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index e27a3e2208a..241a16723dc 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -1213,6 +1213,10 @@ Keywords_for_list_of_owner_roles, "PUBLIC" " AND d.datname = pg_catalog.current_database() "\ " AND s.subdbid = d.oid" +#define Query_for_list_of_large_objects \ +"SELECT oid FROM pg_catalog.pg_largeobject_metadata "\ +" WHERE oid::text LIKE '%s'" + /* Privilege options shared between GRANT and REVOKE */ #define Privilege_options_of_grant_and_revoke \ "SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", \ @@ -3344,6 +3348,10 @@ match_previous_words(int pattern_id, set_completion_reference(prev2_wd); COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_trigger); } + else if (Matches("COMMENT", "ON", "LARGE", "OBJECT")) + COMPLETE_WITH_QUERY(Query_for_list_of_large_objects); + else if (Matches("COMMENT", "ON", "LARGE", "OBJECT", MatchAnyExcept("IS"))) + COMPLETE_WITH("IS"); else if (Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) || Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) || Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")) || @@ -5185,6 +5193,22 @@ match_previous_words(int pattern_id, "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE", "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA", "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW"); + else if (Matches("SECURITY", "LABEL", "ON", "EVENT", "TRIGGER")) + COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); + else if (Matches("SECURITY", "LABEL", "ON", "EVENT", "TRIGGER", MatchAny)) + COMPLETE_WITH("IS"); + else if (Matches("SECURITY", "LABEL", "ON", "FOREIGN", "TABLE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables); + else if (Matches("SECURITY", "LABEL", "ON", "FOREIGN", "TABLE", MatchAny)) + COMPLETE_WITH("IS"); + else if (Matches("SECURITY", "LABEL", "ON", "MATERIALIZED", "VIEW")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews); + else if (Matches("SECURITY", "LABEL", "ON", "MATERIALIZED", "VIEW", MatchAny)) + COMPLETE_WITH("IS"); + else if (Matches("SECURITY", "LABEL", "ON", "LARGE", "OBJECT")) + COMPLETE_WITH_QUERY(Query_for_list_of_large_objects); + else if (Matches("SECURITY", "LABEL", "ON", "LARGE", "OBJECT", MatchAny)) + COMPLETE_WITH("IS"); else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny)) COMPLETE_WITH("IS"); -- 2.43.0