Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wfMVa-005Pcb-1c for pgsql-hackers@arkaria.postgresql.org; Thu, 02 Jul 2026 18:51:34 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wfMVZ-002om0-0n for pgsql-hackers@arkaria.postgresql.org; Thu, 02 Jul 2026 18:51:33 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wfMVY-002olq-2K for pgsql-hackers@lists.postgresql.org; Thu, 02 Jul 2026 18:51:32 +0000 Received: from mail-oa1-x33.google.com ([2001:4860:4864:20::33]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wfMVW-00000001FZR-0V0v for pgsql-hackers@postgresql.org; Thu, 02 Jul 2026 18:51:31 +0000 Received: by mail-oa1-x33.google.com with SMTP id 586e51a60fabf-446f87b6de1so967457fac.3 for ; Thu, 02 Jul 2026 11:51:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783018289; x=1783623089; darn=postgresql.org; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=Nptb51yjNwROPwxaNf+pKzCcpjo5sy5uH56xEU5sQHw=; b=lYqLt8XTy11P4oZattSrvWGEsies591MZ7sHRFUl0zHn1uXWUg8BZnjHi3Cxod5WIY 4lDGfGq58moMUe6uqyn6DH4pbUZHqGoMMrj3mRfdvHKsGH+kYCyDohFvL3MMrAE/FRFg HRAemlzrWn1+PaHm2l/X/lKo4c4jfC3aY+gmz8IWCbQMtAWNpgKE7R6XWyo/QiHrVirG T2XYjTkaSKf1zPuH0qAgzL5yknr3yJesMPi1+eZZwrLVYgVDgELQTDNq21y9//9NKjPT AfYEiPRrhSVwNMJ+ftBDlvMJEtdmerqo9/TnztK12BfagRXMF5pSSLPdS6I454pSZ1da 0jCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783018289; x=1783623089; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Nptb51yjNwROPwxaNf+pKzCcpjo5sy5uH56xEU5sQHw=; b=rRkwJ+Ad6C5MeXdt59Bl1lUuWQ5DQlS4HXYqCW5BX/KVziH2rD48qGTNRcJGYgQ64g bcRyYsmiCR8r1ScRc1a6EB5bFQlFRdyL/0Pj16aFHzyWDi2dz/TFHVH2FBh7ef0VODqQ TDWzbLgvC0obRkw7L6BvHm9+tz1j35KSXAh4plDH4XtRWwdeIJ/d+XVwdfY48PrdpwD6 5HWMkOjRAks5w9yQb1sEfdRdC/4Bl5uXEAXtYL7ne6TuW5I4NF1IM8QO9vJGZuraKf8P mNPmhfeXEWsYPEo0VCOZzH7IiOZGteTGJLmKrvj+HzcKshOwFPvi0vZ/JYnIdqGZ5hT1 uutQ== X-Gm-Message-State: AOJu0YxQ8p9F3ON+jI3T5qpWcI1y/K7wgDdI9g5snXh6IaJkf3mVzgTJ cR7HvcHqpNbiA2FS3Zri0+AVD978w6oBhhCzeKp2ct+yZorPyReRSRDktH6Pwg== X-Gm-Gg: AfdE7clRITCbEs/29oSrgiX+IDXttus54nnia83tEZl8upXW5TXJLQ+lz5KOHM6s4GC a8MMQqNPEyHR3cZkwIkl+K0+ZOaxGVgGiwoAqhJJIkC5fXU+KQ60GJC6IZhZS/329hTM21+zFdo dcOG8dp3bXiM6Z3zB6fXZqzBdVyIVftOoSoHr9PvgatVjUd2CB4g12oQp/J+8hHivF2oe/6AcL5 B3mBU6JeifwqsaWcEGI2xyFpzsJJIiPPg2JR3T868QFA2bu7TzyNQ0AjsqYC2awxRkA1gYU0Zqz hVp1J1dr3Zj5uiqPDng4kPK/R+Vp5YudwcYVw84bTykgU8mMYF3HHtHMuwhFLxJ6KOvUgeQAiyW Kyx4/ze/3OJ4VqmTaZpNr1KVg6iPueAcJljbRiSJ8Uh4lPsMvjqcx9q7PhkES1/mZnrp+ukG407 ludJ3g5Hu2CA9yN+/wx4AZR1O9yG/QKmQfJQCyAHBg6YmuYIt+cEdH62MBaDH5CDb+keJ1MvtG9 bNwFVDWnhk/g3AaoXJ/jQ== X-Received: by 2002:a05:6870:ac21:b0:430:b7d:f248 with SMTP id 586e51a60fabf-44cab8dc791mr4578370fac.24.1783018288899; Thu, 02 Jul 2026 11:51:28 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-44cbec92bbbsm3698514fac.10.2026.07.02.11.51.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Jul 2026 11:51:28 -0700 (PDT) Date: Thu, 2 Jul 2026 13:51:26 -0500 From: Nathan Bossart To: pgsql-hackers@postgresql.org Subject: remove VersionedQuery support from psql tab completion Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="m8LJOl54+zCjPq94" Content-Disposition: inline List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --m8LJOl54+zCjPq94 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline This infrastructure was added by commit 722408bcd1 and was only ever used for publications and subscriptions. Since we just bumped psql's minimum supported version to v10, it's no longer used by anything. Furthermore, a quick glance indicates there's nothing else that should use it. So, IMHO we might as well remove it. -- nathan --m8LJOl54+zCjPq94 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0001-remove-VersionedQuery-support-from-psql-tab-compl.patch From e0fe2acf32bc2c72146258c48a1ccfe24dadca04 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 2 Jul 2026 13:39:51 -0500 Subject: [PATCH v1 1/1] remove VersionedQuery support from psql tab completion --- src/bin/psql/tab-complete.in.c | 150 ++++++++++----------------------- 1 file changed, 45 insertions(+), 105 deletions(-) diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index e4722c06664..c238d466e29 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -92,24 +92,6 @@ */ PQExpBuffer tab_completion_query_buf = NULL; -/* - * In some situations, the query to find out what names are available to - * complete with must vary depending on server version. We handle this by - * storing a list of queries, each tagged with the minimum server version - * it will work for. Each list must be stored in descending server version - * order, so that the first satisfactory query is the one to use. - * - * When the query string is otherwise constant, an array of VersionedQuery - * suffices. Terminate the array with an entry having min_server_version = 0. - * That entry's query string can be a query that works in all supported older - * server versions, or NULL to give up and do no completion. - */ -typedef struct VersionedQuery -{ - int min_server_version; - const char *query; -} VersionedQuery; - /* * This struct is used to define "schema queries", which are custom-built * to obtain possibly-schema-qualified names of database objects. There is @@ -123,8 +105,7 @@ typedef struct VersionedQuery * objects we're completing might not have a schema of their own, but the * reference object almost always does (passed in completion_ref_schema). * - * As with VersionedQuery, we can use an array of these if the query details - * must vary across versions. + * We can use an array of these if the query details must vary across versions. */ typedef struct SchemaQuery { @@ -225,7 +206,6 @@ static int completion_max_records; static char completion_last_char; /* last char of input word */ static const char *completion_charp; /* to pass a string */ static const char *const *completion_charpp; /* to pass a list of strings */ -static const VersionedQuery *completion_vquery; /* to pass a VersionedQuery */ static const SchemaQuery *completion_squery; /* to pass a SchemaQuery */ static char *completion_ref_object; /* name of reference object */ static char *completion_ref_schema; /* schema name of reference object */ @@ -237,7 +217,6 @@ static bool completion_force_quote; /* true to force-quote filenames */ * A few macros to ease typing. You can use these to complete the given * string with * 1) The result from a query you pass it. (Perhaps one of those below?) - * We support both simple and versioned queries. * 2) The result from a schema query you pass it. * We support both simple and versioned schema queries. * 3) The items from a null-pointer-terminated list (with or without @@ -288,23 +267,6 @@ do { \ COMPLETE_WITH_QUERY_VERBATIM_LIST(query, list); \ } while (0) -#define COMPLETE_WITH_VERSIONED_QUERY(query) \ - COMPLETE_WITH_VERSIONED_QUERY_LIST(query, NULL) - -#define COMPLETE_WITH_VERSIONED_QUERY_LIST(query, list) \ -do { \ - completion_vquery = query; \ - completion_charpp = list; \ - completion_verbatim = false; \ - matches = rl_completion_matches(text, complete_from_versioned_query); \ -} while (0) - -#define COMPLETE_WITH_VERSIONED_QUERY_PLUS(query, ...) \ -do { \ - static const char *const list[] = { __VA_ARGS__, NULL }; \ - COMPLETE_WITH_VERSIONED_QUERY_LIST(query, list); \ -} while (0) - #define COMPLETE_WITH_SCHEMA_QUERY(query) \ COMPLETE_WITH_SCHEMA_QUERY_LIST(query, NULL) @@ -1278,9 +1240,8 @@ static const char *const sql_commands[] = { typedef struct { const char *name; - /* Provide at most one of these three types of query: */ + /* Provide at most one of these two types of query: */ const char *query; /* simple query, or NULL */ - const VersionedQuery *vquery; /* versioned query, or NULL */ const SchemaQuery *squery; /* schema query, or NULL */ const char *const *keywords; /* keywords to be offered as well */ const uint32 flags; /* visibility flags, see below */ @@ -1298,68 +1259,68 @@ static const char *const Keywords_for_user_thing[] = { }; static const pgsql_thing_t words_after_create[] = { - {"ACCESS METHOD", NULL, NULL, NULL, NULL, THING_NO_ALTER}, - {"AGGREGATE", NULL, NULL, Query_for_list_of_aggregates}, - {"CAST", NULL, NULL, NULL}, /* Casts have complex structures for names, so + {"ACCESS METHOD", NULL, NULL, NULL, THING_NO_ALTER}, + {"AGGREGATE", NULL, Query_for_list_of_aggregates}, + {"CAST", NULL, NULL}, /* Casts have complex structures for names, so * skip it */ - {"COLLATION", NULL, NULL, &Query_for_list_of_collations}, + {"COLLATION", NULL, &Query_for_list_of_collations}, /* * CREATE CONSTRAINT TRIGGER is not supported here because it is designed * to be used only by pg_dump. */ - {"CONFIGURATION", NULL, NULL, &Query_for_list_of_ts_configurations, NULL, THING_NO_SHOW}, + {"CONFIGURATION", NULL, &Query_for_list_of_ts_configurations, NULL, THING_NO_SHOW}, {"CONVERSION", "SELECT conname FROM pg_catalog.pg_conversion WHERE conname LIKE '%s'"}, {"DATABASE", Query_for_list_of_databases}, - {"DEFAULT PRIVILEGES", NULL, NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP}, - {"DICTIONARY", NULL, NULL, &Query_for_list_of_ts_dictionaries, NULL, THING_NO_SHOW}, - {"DOMAIN", NULL, NULL, &Query_for_list_of_domains}, - {"EVENT TRIGGER", NULL, NULL, NULL}, + {"DEFAULT PRIVILEGES", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP}, + {"DICTIONARY", NULL, &Query_for_list_of_ts_dictionaries, NULL, THING_NO_SHOW}, + {"DOMAIN", NULL, &Query_for_list_of_domains}, + {"EVENT TRIGGER", NULL, NULL}, {"EXTENSION", Query_for_list_of_extensions}, - {"FOREIGN DATA WRAPPER", NULL, NULL, NULL}, - {"FOREIGN TABLE", NULL, NULL, NULL}, - {"FUNCTION", NULL, NULL, Query_for_list_of_functions}, + {"FOREIGN DATA WRAPPER", NULL, NULL}, + {"FOREIGN TABLE", NULL, NULL}, + {"FUNCTION", NULL, Query_for_list_of_functions}, {"GROUP", Query_for_list_of_roles}, - {"INDEX", NULL, NULL, &Query_for_list_of_indexes}, + {"INDEX", NULL, &Query_for_list_of_indexes}, {"LANGUAGE", Query_for_list_of_languages}, - {"LARGE OBJECT", NULL, NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP}, - {"MATERIALIZED VIEW", NULL, NULL, &Query_for_list_of_matviews}, - {"OPERATOR", NULL, NULL, NULL}, /* Querying for this is probably not such - * a good idea. */ - {"OR REPLACE", NULL, NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, - {"OWNED", NULL, NULL, NULL, NULL, THING_NO_CREATE | THING_NO_ALTER}, /* for DROP OWNED BY ... */ - {"PARSER", NULL, NULL, &Query_for_list_of_ts_parsers, NULL, THING_NO_SHOW}, - {"POLICY", NULL, NULL, NULL}, - {"PROCEDURE", NULL, NULL, Query_for_list_of_procedures}, - {"PROPERTY GRAPH", NULL, NULL, &Query_for_list_of_propgraphs}, + {"LARGE OBJECT", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP}, + {"MATERIALIZED VIEW", NULL, &Query_for_list_of_matviews}, + {"OPERATOR", NULL, NULL}, /* Querying for this is probably not such a + * good idea. */ + {"OR REPLACE", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, + {"OWNED", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_ALTER}, /* for DROP OWNED BY ... */ + {"PARSER", NULL, &Query_for_list_of_ts_parsers, NULL, THING_NO_SHOW}, + {"POLICY", NULL, NULL}, + {"PROCEDURE", NULL, Query_for_list_of_procedures}, + {"PROPERTY GRAPH", NULL, &Query_for_list_of_propgraphs}, {"PUBLICATION", Query_for_list_of_publications}, {"ROLE", Query_for_list_of_roles}, - {"ROUTINE", NULL, NULL, &Query_for_list_of_routines, NULL, THING_NO_CREATE}, + {"ROUTINE", NULL, &Query_for_list_of_routines, NULL, THING_NO_CREATE}, {"RULE", "SELECT rulename FROM pg_catalog.pg_rules WHERE rulename LIKE '%s'"}, {"SCHEMA", Query_for_list_of_schemas}, - {"SEQUENCE", NULL, NULL, &Query_for_list_of_sequences}, + {"SEQUENCE", NULL, &Query_for_list_of_sequences}, {"SERVER", Query_for_list_of_servers}, - {"STATISTICS", NULL, NULL, &Query_for_list_of_statistics}, + {"STATISTICS", NULL, &Query_for_list_of_statistics}, {"SUBSCRIPTION", Query_for_list_of_subscriptions}, - {"SYSTEM", NULL, NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP}, - {"TABLE", NULL, NULL, &Query_for_list_of_tables}, + {"SYSTEM", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP}, + {"TABLE", NULL, &Query_for_list_of_tables}, {"TABLESPACE", Query_for_list_of_tablespaces}, - {"TEMP", NULL, NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMP TABLE - * ... */ - {"TEMPLATE", NULL, NULL, &Query_for_list_of_ts_templates, NULL, THING_NO_SHOW}, - {"TEMPORARY", NULL, NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMPORARY - * TABLE ... */ - {"TEXT SEARCH", NULL, NULL, NULL}, - {"TRANSFORM", NULL, NULL, NULL, NULL, THING_NO_ALTER}, + {"TEMP", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMP TABLE + * ... */ + {"TEMPLATE", NULL, &Query_for_list_of_ts_templates, NULL, THING_NO_SHOW}, + {"TEMPORARY", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMPORARY + * TABLE ... */ + {"TEXT SEARCH", NULL, NULL}, + {"TRANSFORM", NULL, NULL, NULL, THING_NO_ALTER}, {"TRIGGER", "SELECT tgname FROM pg_catalog.pg_trigger WHERE tgname LIKE '%s' AND NOT tgisinternal"}, - {"TYPE", NULL, NULL, &Query_for_list_of_datatypes}, - {"UNIQUE", NULL, NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNIQUE - * INDEX ... */ - {"UNLOGGED", NULL, NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNLOGGED - * TABLE ... */ - {"USER", Query_for_list_of_roles, NULL, NULL, Keywords_for_user_thing}, - {"USER MAPPING FOR", NULL, NULL, NULL}, - {"VIEW", NULL, NULL, &Query_for_list_of_views}, + {"TYPE", NULL, &Query_for_list_of_datatypes}, + {"UNIQUE", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNIQUE + * INDEX ... */ + {"UNLOGGED", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNLOGGED + * TABLE ... */ + {"USER", Query_for_list_of_roles, NULL, Keywords_for_user_thing}, + {"USER MAPPING FOR", NULL, NULL}, + {"VIEW", NULL, &Query_for_list_of_views}, {NULL} /* end of list */ }; @@ -1475,7 +1436,6 @@ static char *create_command_generator(const char *text, int state); static char *drop_command_generator(const char *text, int state); static char *alter_command_generator(const char *text, int state); static char *complete_from_query(const char *text, int state); -static char *complete_from_versioned_query(const char *text, int state); static char *complete_from_schema_query(const char *text, int state); static char *complete_from_versioned_schema_query(const char *text, int state); static char *_complete_from_query(const char *simple_query, @@ -1967,7 +1927,6 @@ psql_completion(const char *text, int start, int end) /* Clear a few things. */ completion_charp = NULL; completion_charpp = NULL; - completion_vquery = NULL; completion_squery = NULL; completion_ref_object = NULL; completion_ref_schema = NULL; @@ -2098,9 +2057,6 @@ psql_completion(const char *text, int start, int end) if (wac->query) COMPLETE_WITH_QUERY_LIST(wac->query, wac->keywords); - else if (wac->vquery) - COMPLETE_WITH_VERSIONED_QUERY_LIST(wac->vquery, - wac->keywords); else if (wac->squery) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY_LIST(wac->squery, wac->keywords); @@ -5928,22 +5884,6 @@ complete_from_query(const char *text, int state) completion_verbatim, text, state); } -static char * -complete_from_versioned_query(const char *text, int state) -{ - const VersionedQuery *vquery = completion_vquery; - - /* Find appropriate array element */ - while (pset.sversion < vquery->min_server_version) - vquery++; - /* Fail completion if server is too old */ - if (vquery->query == NULL) - return NULL; - - return _complete_from_query(vquery->query, NULL, completion_charpp, - completion_verbatim, text, state); -} - static char * complete_from_schema_query(const char *text, int state) { -- 2.50.1 (Apple Git-155) --m8LJOl54+zCjPq94--