| From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Cc: | roji(at)roji(dot)org |
| Subject: | BUG #19778: Empty tsquery cannot roundtrip through binary input |
| Date: | 2026-10-20 19:24:37 |
| Message-ID: | 19778-1befc1fba593ab1b@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 19778
Logged by: Shay Rojansky
Email address: roji(at)roji(dot)org
PostgreSQL version: 18.4
Operating system: macOS Tahoe 26.7.1
Description:
It appears that an empty binary tsquery cannot be written to PostgreSQL.
Writing a non-empty binary tsquery works, as well as writing an empty text
tsquery.
Minimal repro:
#include <libpq-fe.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void require_row(PGresult *result)
{
if (PQresultStatus(result) != PGRES_TUPLES_OK || PQntuples(result) != 1)
{
fprintf(stderr, "Unexpected result: %s",
PQresultErrorMessage(result));
exit(1);
}
}
int main(int argc, char **argv)
{
PGconn *conn = PQconnectdb(argc > 1 ? argv[1] : "dbname=postgres");
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "%s", PQerrorMessage(conn));
PQfinish(conn);
return 1;
}
printf("libpq=%d, PostgreSQL=%d\n", PQlibVersion(),
PQserverVersion(conn));
/* Obtain both binary values from PostgreSQL, without constructing
either. */
PGresult *values = PQexecParams(
conn, "SELECT ''::tsquery, 'foo'::tsquery",
0, NULL, NULL, NULL, NULL, 1);
require_row(values);
const Oid types[] = {PQftype(values, 0)};
const char *params[] = {PQgetvalue(values, 0, 1)};
int lengths[] = {PQgetlength(values, 0, 1)};
int formats[] = {1};
PGresult *result = PQexecParams(conn, "SELECT $1", 1, types, params,
lengths, formats, 0);
require_row(result);
if (PQgetisnull(result, 0, 0) || strcmp(PQgetvalue(result, 0, 0),
"'foo'") != 0)
return 1;
printf("Binary non-empty tsquery roundtrip: %s\n", PQgetvalue(result, 0,
0));
PQclear(result);
params[0] = "";
lengths[0] = 0;
formats[0] = 0;
result = PQexecParams(conn, "SELECT $1", 1, types, params, lengths,
formats, 0);
require_row(result);
if (PQgetisnull(result, 0, 0) || PQgetlength(result, 0, 0) != 0)
return 1;
puts("Text empty tsquery roundtrip: OK");
PQclear(result);
params[0] = PQgetvalue(values, 0, 0);
lengths[0] = PQgetlength(values, 0, 0);
formats[0] = 1;
printf("Server-produced empty tsquery: type=%u, format=%d, length=%d,
hex=",
types[0], PQfformat(values, 0), lengths[0]);
for (int i = 0; i < lengths[0]; i++)
printf("%02x", (unsigned char)params[0][i]);
putchar('\n');
/* Send the server's bytes back unchanged, with the server's type OID.
*/
result = PQexecParams(conn, "SELECT $1", 1, types, params, lengths,
formats, 0);
const char *state = PQresultErrorField(result, PG_DIAG_SQLSTATE);
const char *message = PQresultErrorField(result,
PG_DIAG_MESSAGE_PRIMARY);
const char *routine = PQresultErrorField(result,
PG_DIAG_SOURCE_FUNCTION);
int reproduced = PQresultStatus(result) == PGRES_FATAL_ERROR
&& state && strcmp(state, "XX000") == 0
&& message && strcmp(message, "malformed tsquery: operand not
found") == 0
&& routine && strcmp(routine, "findoprnd_recurse") == 0;
if (reproduced)
printf("REPRODUCED: %s: %s (%s)\n", state, message, routine);
else
fprintf(stderr, "Expected server error was not reproduced: %s\n",
PQresultErrorMessage(result));
PQclear(result);
PQclear(values);
PQfinish(conn);
return reproduced ? 0 : 1;
}
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Matheus Alcantara | 2026-10-20 19:30:11 | Re: BUG #19772: ERROR: corrupt MVNDistinct entry for GROUP BY c0, ROLLUP (abs(c0)) with ndistinct statistics |
| Previous Message | Gowtham Reddy | 2026-10-20 18:52:56 | Re: BUG #19771: to_char(): NUL byte in result for formats with a trailing decimal point (regression from ec352b37d) |