From 9f05528bff812d60057078f634fa4e184e1e248a Mon Sep 17 00:00:00 2001 From: shihao zhong Date: Tue, 13 Oct 2026 00:08:02 -0400 Subject: [PATCH v1] psql: Don't send hidden query labels the server could reject. The labels are translated, and the translation is in the encoding of the message locale. When that differs from client_encoding the server rejects the query. In that case send the query without the label if the label is not plain ASCII. The -E output still shows it. --- src/bin/psql/command.c | 4 ++-- src/bin/psql/common.c | 29 ++++++++++++++++++++++++++++- src/bin/psql/common.h | 1 + 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 2fc34b83a5a..5902ab36cc8 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -6246,7 +6246,7 @@ lookup_object_oid(EditableObjectType obj_type, const char *desc, destroyPQExpBuffer(query); return false; } - res = PQexec(pset.db, query->data); + res = PQexec(pset.db, skip_nonascii_label(query->data)); if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1) *obj_oid = atooid(PQgetvalue(res, 0, 0)); else @@ -6314,7 +6314,7 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid, destroyPQExpBuffer(query); return false; } - res = PQexec(pset.db, query->data); + res = PQexec(pset.db, skip_nonascii_label(query->data)); if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1) { resetPQExpBuffer(buf); diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index f220344daaf..f6464083675 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -643,6 +643,33 @@ PrintTiming(double elapsed_msec) } +/* + * skip_nonascii_label + * + * A hidden query can start with a translated label in a comment. The + * translation is in the encoding of the locale. If that is not the client + * encoding and the label is not plain ASCII, the server could reject it, so + * the query must be sent without the label. Returns the place in "query" to + * send from. + */ +const char * +skip_nonascii_label(const char *query) +{ + if (strncmp(query, "/* ", 3) == 0 && + pset.encoding != pg_get_encoding_from_locale(NULL, false)) + { + const char *end = strstr(query, " */\n"); + + for (const char *p = query; end != NULL && p < end; p++) + { + if (IS_HIGHBIT_SET(*p)) + return end + 4; + } + } + + return query; +} + /* * PSQLexec * @@ -687,7 +714,7 @@ PSQLexec(const char *query) SetCancelConn(pset.db); - res = PQexec(pset.db, query); + res = PQexec(pset.db, skip_nonascii_label(query)); ResetCancelConn(); diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index d4b99b42331..352a843eec7 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -31,6 +31,7 @@ extern void psql_setup_cancel_handler(void); extern void SetShellResultVariables(int wait_result); +extern const char *skip_nonascii_label(const char *query); extern PGresult *PSQLexec(const char *query); extern int PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout, int min_rows); -- 2.37.1 (Apple Git-137.1)