agora inbox for pgsql-hackers@postgresql.org
help / color / mirror / Atom feed[PATCH v1 1/1] remove VersionedQuery support from psql tab completion
5+ messages / 4 participants
[nested] [flat]
* [PATCH v1 1/1] remove VersionedQuery support from psql tab completion
@ 2026-07-02 18:39 Nathan Bossart <nathan@postgresql.org>
0 siblings, 0 replies; 5+ messages in thread
From: Nathan Bossart @ 2026-07-02 18:39 UTC (permalink / raw)
---
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--
^ permalink raw reply [nested|flat] 5+ messages in thread
* remove VersionedQuery support from psql tab completion
@ 2026-07-02 18:51 Nathan Bossart <nathandbossart@gmail.com>
0 siblings, 2 replies; 5+ messages in thread
From: Nathan Bossart @ 2026-07-02 18:51 UTC (permalink / raw)
To: pgsql-hackers
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
From e0fe2acf32bc2c72146258c48a1ccfe24dadca04 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
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)
Attachments:
[text/plain] v1-0001-remove-VersionedQuery-support-from-psql-tab-compl.patch (12.1K, ../../akazLuA2V2_auKiN@nathan/2-v1-0001-remove-VersionedQuery-support-from-psql-tab-compl.patch)
download | inline diff:
From e0fe2acf32bc2c72146258c48a1ccfe24dadca04 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
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)
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: remove VersionedQuery support from psql tab completion
@ 2026-07-02 19:44 Ayush Tiwari <ayushtiwari.slg01@gmail.com>
parent: Nathan Bossart <nathandbossart@gmail.com>
1 sibling, 0 replies; 5+ messages in thread
From: Ayush Tiwari @ 2026-07-02 19:44 UTC (permalink / raw)
To: Nathan Bossart <nathandbossart@gmail.com>; +Cc: pgsql-hackers
Hi,
On Fri, 3 Jul 2026 at 00:21, Nathan Bossart <nathandbossart@gmail.com>
wrote:
> 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.
>
Thanks for the patch!
Doing a grep on VersionedQuery I could find one instance missing
in your patch in 010_tab_completion.pl file there's a test block
# check VersionedQuery infrastructure
check_completion(
"DROP PUBLIC\t \t\t",
qr/DROP PUBLICATION\s+some_publication /,
"check VersionedQuery");
I think the test case is fine, but the comment + label needs to be
updated or case drop if it's redundant.
Rest, LGTM.
Regards,
Ayush
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: remove VersionedQuery support from psql tab completion
@ 2026-07-02 22:17 Tom Lane <tgl@sss.pgh.pa.us>
parent: Nathan Bossart <nathandbossart@gmail.com>
1 sibling, 1 reply; 5+ messages in thread
From: Tom Lane @ 2026-07-02 22:17 UTC (permalink / raw)
To: Nathan Bossart <nathandbossart@gmail.com>; +Cc: pgsql-hackers
Nathan Bossart <nathandbossart@gmail.com> writes:
> 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.
This seems a little short-sighted. Do you think we'll never again
make any catalog changes that affect tab completion? Admittedly,
maybe all such cases will fall under what SchemaQuery is good for.
But that's significantly harder to use, so I'm not really in a
hurry to make that tradeoff.
regards, tom lane
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: remove VersionedQuery support from psql tab completion
@ 2026-07-06 14:12 Nathan Bossart <nathandbossart@gmail.com>
parent: Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 0 replies; 5+ messages in thread
From: Nathan Bossart @ 2026-07-06 14:12 UTC (permalink / raw)
To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: pgsql-hackers
On Thu, Jul 02, 2026 at 06:17:38PM -0400, Tom Lane wrote:
> Nathan Bossart <nathandbossart@gmail.com> writes:
>> 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.
>
> This seems a little short-sighted. Do you think we'll never again
> make any catalog changes that affect tab completion? Admittedly,
> maybe all such cases will fall under what SchemaQuery is good for.
> But that's significantly harder to use, so I'm not really in a
> hurry to make that tradeoff.
That's what I thought at first, but given we didn't accumulate any other
uses in the ~8 years it was around, I think there's a reasonably good
chance it goes unused for quite a while longer. This was just a small bit
of cleanup; I'm fine with leaving it around if you want.
--
nathan
^ permalink raw reply [nested|flat] 5+ messages in thread
end of thread, other threads:[~2026-07-06 14:12 UTC | newest]
Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-07-02 18:39 [PATCH v1 1/1] remove VersionedQuery support from psql tab completion Nathan Bossart <nathan@postgresql.org>
2026-07-02 18:51 remove VersionedQuery support from psql tab completion Nathan Bossart <nathandbossart@gmail.com>
2026-07-02 19:44 ` Ayush Tiwari <ayushtiwari.slg01@gmail.com>
2026-07-02 22:17 ` Tom Lane <tgl@sss.pgh.pa.us>
2026-07-06 14:12 ` Nathan Bossart <nathandbossart@gmail.com>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox