public inbox for [email protected]
help / color / mirror / Atom feedFrom: Ewan Young <[email protected]>
To: PostgreSQL Hackers <[email protected]>
Cc: Michael Paquier <[email protected]>
Subject: Use ereport() instead of elog() for invalid weights in setweight()
Date: Wed, 3 Jun 2026 23:39:05 +0800
Message-ID: <CAON2xHNaeLAUzRCXL5AmXLcXaSE_gWAVjWQRmLzc_oZ=1_Vf4Q@mail.gmail.com> (raw)
Hi hackers,
I noticed that setweight() reports an internal error (SQLSTATE XX000)
when the weight argument is not one of A/a, B/b, C/c, D/d, even though
the weight comes directly from user input. The two-argument variant
also prints the weight as a raw ASCII code, which is a bit unfriendly:
=# SELECT setweight('cat:1'::tsvector, 'p');
ERROR: unrecognized weight: 112
ts_filter() in the same file (tsvector_op.c) already handles the
equivalent case with ereport() and ERRCODE_INVALID_PARAMETER_VALUE,
so the attached patch simply makes tsvector_setweight() and
tsvector_setweight_by_filter() do the same, and adds regression tests
covering the three error paths (none of which were covered before).
This seems to be in the same spirit as the earlier cleanup of
user-reachable internal error codes [1]; these two sites appear to
have been missed there.
The patch is against the master and passes make check. Please let me know
if I've missed anything -- I'd be happy to revise.
[1] https://postgr.es/m/[email protected]
Best regards,
Ewan Young
Attachments:
[application/octet-stream] v1-0001-Use-ereport-not-elog-for-invalid-weights-in-setweight.patch (4.1K, 2-v1-0001-Use-ereport-not-elog-for-invalid-weights-in-setweight.patch)
download | inline diff:
From 71f205c364404d2db244b2c6de4cc3b047fe08c8 Mon Sep 17 00:00:00 2001
From: Ewan Young <[email protected]>
Date: Thu, 4 Jun 2026 07:25:03 +0800
Subject: [PATCH] Use ereport(), not elog(), for invalid weights in
setweight().
tsvector_setweight() and tsvector_setweight_by_filter() raised an
internal error (elog, SQLSTATE XX000) when the weight argument was
not one of A/a, B/b, C/c, D/d, even though the weight comes directly
from user input. Worse, the two-argument variant printed the weight
as a raw ASCII code:
=# SELECT setweight('cat:1'::tsvector, 'p');
ERROR: unrecognized weight: 112
Convert both to ereport() with ERRCODE_INVALID_PARAMETER_VALUE,
matching what tsvector_filter() in the same file already does, and
add regression tests covering all three error paths.
---
src/backend/utils/adt/tsvector_op.c | 10 ++++++----
src/test/regress/expected/tstypes.out | 7 +++++++
src/test/regress/sql/tstypes.sql | 4 ++++
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index d8dece42b9b..9a83658b601 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -238,8 +238,9 @@ tsvector_setweight(PG_FUNCTION_ARGS)
w = 0;
break;
default:
- /* internal error */
- elog(ERROR, "unrecognized weight: %d", cw);
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized weight: \"%c\"", cw)));
}
out = (TSVector) palloc(VARSIZE(in));
@@ -304,8 +305,9 @@ tsvector_setweight_by_filter(PG_FUNCTION_ARGS)
weight = 0;
break;
default:
- /* internal error */
- elog(ERROR, "unrecognized weight: %c", char_weight);
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized weight: \"%c\"", char_weight)));
}
tsout = (TSVector) palloc(VARSIZE(tsin));
diff --git a/src/test/regress/expected/tstypes.out b/src/test/regress/expected/tstypes.out
index 4cfc3b9dc04..a9c6465021f 100644
--- a/src/test/regress/expected/tstypes.out
+++ b/src/test/regress/expected/tstypes.out
@@ -1428,6 +1428,11 @@ SELECT setweight('a asd w:5,6,12B,13A zxc'::tsvector, 'c', ARRAY['a', 'zxc', '',
'a' 'asd' 'w':5,6,12B,13A 'zxc'
(1 row)
+-- invalid weights are disallowed
+SELECT setweight('w:5A'::tsvector, 'x');
+ERROR: unrecognized weight: "x"
+SELECT setweight('w:5A'::tsvector, 'x', '{w}');
+ERROR: unrecognized weight: "x"
SELECT ts_filter('base:7A empir:17 evil:15 first:11 galact:16 hidden:6A rebel:1A spaceship:2A strike:3A victori:12 won:9'::tsvector, '{a}');
ts_filter
-------------------------------------------------------------
@@ -1442,3 +1447,5 @@ SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a}');
SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a,b,NULL}');
ERROR: weight array may not contain nulls
+SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{x}');
+ERROR: unrecognized weight: "x"
diff --git a/src/test/regress/sql/tstypes.sql b/src/test/regress/sql/tstypes.sql
index dfb7a1466e0..4261abed670 100644
--- a/src/test/regress/sql/tstypes.sql
+++ b/src/test/regress/sql/tstypes.sql
@@ -275,7 +275,11 @@ SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '
SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}');
SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a,zxc}');
SELECT setweight('a asd w:5,6,12B,13A zxc'::tsvector, 'c', ARRAY['a', 'zxc', '', NULL]);
+-- invalid weights are disallowed
+SELECT setweight('w:5A'::tsvector, 'x');
+SELECT setweight('w:5A'::tsvector, 'x', '{w}');
SELECT ts_filter('base:7A empir:17 evil:15 first:11 galact:16 hidden:6A rebel:1A spaceship:2A strike:3A victori:12 won:9'::tsvector, '{a}');
SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a}');
SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a,b,NULL}');
+SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{x}');
--
2.47.3
view thread (4+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected]
Subject: Re: Use ereport() instead of elog() for invalid weights in setweight()
In-Reply-To: <CAON2xHNaeLAUzRCXL5AmXLcXaSE_gWAVjWQRmLzc_oZ=1_Vf4Q@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox