hi.
Some of the regexp* function error messages seem not very helpful, I think.
like:
ereport(ERROR,
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
"start", start));
so I added a errhint, errhint would be better than refactoring existing errmsg.
for the above example, I've add:
+ errhint("\"%s\" must be an integer value greater than zero", "start")));
--
jian
https://www.enterprisedb.com
From ba2bccb45066ff688c55a6351f69f85e11cd5442 Mon Sep 17 00:00:00 2001
From: jian he <[email protected]>
Date: Sun, 7 Dec 2025 16:43:45 +0800
Subject: [PATCH v1 1/1] regex function add errhint
discussion: https://postgr.es/m/
---
src/backend/utils/adt/regexp.c | 31 ++++++++++++++++++---------
src/test/regress/expected/strings.out | 18 +++++++++++++---
2 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c
index b0cdef9b19f..c169d14f9b8 100644
--- a/src/backend/utils/adt/regexp.c
+++ b/src/backend/utils/adt/regexp.c
@@ -714,7 +714,8 @@ textregexreplace_extended(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "start", start)));
+ "start", start),
+ errhint("\"%s\" must be an integer value greater than zero", "start")));
}
if (PG_NARGS() > 4)
{
@@ -723,7 +724,8 @@ textregexreplace_extended(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "n", n)));
+ "N", n),
+ errhint("\"%s\" must be an integer value greater than or equal to zero", "N")));
}
/* Determine options */
@@ -1149,7 +1151,8 @@ regexp_count(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "start", start)));
+ "start", start)),
+ errhint("\"%s\" must be an integer value greater than zero", "start"));
}
/* Determine options */
@@ -1213,7 +1216,8 @@ regexp_instr(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "start", start)));
+ "start", start),
+ errhint("\"%s\" must be an integer value greater than zero", "start")));
}
if (PG_NARGS() > 3)
{
@@ -1222,7 +1226,8 @@ regexp_instr(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "n", n)));
+ "N", n)),
+ errhint("\"%s\" must be an integer value greater than zero", "N"));
}
if (PG_NARGS() > 4)
{
@@ -1231,7 +1236,8 @@ regexp_instr(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "endoption", endoption)));
+ "endoption", endoption),
+ errhint("\"%s\" must be an integer value of 1 or 0", "endoption")));
}
if (PG_NARGS() > 6)
{
@@ -1240,7 +1246,8 @@ regexp_instr(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "subexpr", subexpr)));
+ "subexpr", subexpr),
+ errhint("\"%s\" must be an integer value greater than or equal to zero", "subexpr")));
}
/* Determine options */
@@ -1920,7 +1927,8 @@ regexp_substr(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "start", start)));
+ "start", start)),
+ errhint("\"%s\" must be an integer value greater than zero", "start"));
}
if (PG_NARGS() > 3)
{
@@ -1929,7 +1937,9 @@ regexp_substr(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "n", n)));
+ "N", n)),
+ errhint("\"%s\" must be an integer value greater than zero", "N"));
+
}
if (PG_NARGS() > 5)
{
@@ -1938,7 +1948,8 @@ regexp_substr(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": %d",
- "subexpr", subexpr)));
+ "subexpr", subexpr),
+ errhint("\"%s\" must be an integer value greater than or equal to zero", "subexpr")));
}
/* Determine options */
diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out
index 727304f60e7..157b19d51a7 100644
--- a/src/test/regress/expected/strings.out
+++ b/src/test/regress/expected/strings.out
@@ -866,8 +866,10 @@ SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 1, 'g');
-- errors
SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', -1, 0, 'i');
ERROR: invalid value for parameter "start": -1
+HINT: "start" must be an integer value greater than zero
SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, -1, 'i');
-ERROR: invalid value for parameter "n": -1
+ERROR: invalid value for parameter "N": -1
+HINT: "N" must be an integer value greater than or equal to zero
-- erroneous invocation of non-extended form
SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', '1');
ERROR: invalid regular expression option: "1"
@@ -912,8 +914,10 @@ SELECT regexp_count('ABCABCABCABC', 'Abc', 1, 'i');
-- errors
SELECT regexp_count('123123123123', '123', 0);
ERROR: invalid value for parameter "start": 0
+HINT: "start" must be an integer value greater than zero
SELECT regexp_count('123123123123', '123', -3);
ERROR: invalid value for parameter "start": -3
+HINT: "start" must be an integer value greater than zero
-- regexp_like tests
SELECT regexp_like('Steven', '^Ste(v|ph)en$');
regexp_like
@@ -1066,16 +1070,21 @@ SELECT regexp_instr('foo', 'foo(bar)?', 1, 1, 0, '', 1);
-- errors
SELECT regexp_instr('abcabcabc', 'a.c', 0, 1);
ERROR: invalid value for parameter "start": 0
+HINT: "start" must be an integer value greater than zero
SELECT regexp_instr('abcabcabc', 'a.c', 1, 0);
-ERROR: invalid value for parameter "n": 0
+ERROR: invalid value for parameter "N": 0
+HINT: "N" must be an integer value greater than zero
SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, -1);
ERROR: invalid value for parameter "endoption": -1
+HINT: "endoption" must be an integer value of 1 or 0
SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 2);
ERROR: invalid value for parameter "endoption": 2
+HINT: "endoption" must be an integer value of 1 or 0
SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 0, 'g');
ERROR: regexp_instr() does not support the "global" option
SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 0, '', -1);
ERROR: invalid value for parameter "subexpr": -1
+HINT: "subexpr" must be an integer value greater than or equal to zero
-- regexp_substr tests
SELECT regexp_substr('abcdefghi', 'd.f');
regexp_substr
@@ -1165,12 +1174,15 @@ SELECT regexp_substr('foo', 'foo(bar)?', 1, 1, '', 1) IS NULL AS t;
-- errors
SELECT regexp_substr('abcabcabc', 'a.c', 0, 1);
ERROR: invalid value for parameter "start": 0
+HINT: "start" must be an integer value greater than zero
SELECT regexp_substr('abcabcabc', 'a.c', 1, 0);
-ERROR: invalid value for parameter "n": 0
+ERROR: invalid value for parameter "N": 0
+HINT: "N" must be an integer value greater than zero
SELECT regexp_substr('abcabcabc', 'a.c', 1, 1, 'g');
ERROR: regexp_substr() does not support the "global" option
SELECT regexp_substr('abcabcabc', 'a.c', 1, 1, '', -1);
ERROR: invalid value for parameter "subexpr": -1
+HINT: "subexpr" must be an integer value greater than or equal to zero
-- set so we can tell NULL from empty string
\pset null '\\N'
-- return all matches from regexp
--
2.34.1