Re: [PATCH] Avoid internal error for invalid interval typmods

From: Haibo Yan <tristan(dot)yim(at)gmail(dot)com>
To: Feng Wu <wufengwufengwufeng(at)gmail(dot)com>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: [PATCH] Avoid internal error for invalid interval typmods
Date: 2026-06-30 18:08:54
Message-ID: CABXr29FSGzcYvTEP9z-gGDOHgCM7Y12H-rtjjWxzou36prAckQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Jun 29, 2026 at 9:26 PM Feng Wu <wufengwufengwufeng(at)gmail(dot)com> wrote:
>
> Hi,
>
> While fuzzing PostgreSQL, I noticed that the interval length-coercion
> function can report an internal error for user-supplied input:
>
> SELECT pg_catalog.interval(interval '1 day', 1539);
>
> Currently this fails with:
>
> ERROR: unrecognized interval typmod: 1539
>
> The error is raised with elog(ERROR) in AdjustIntervalForTypmod(), so it
> is reported as SQLSTATE XX000. Since pg_catalog.interval(interval, int4)
> is callable from SQL, arbitrary typmod values can reach this path.
>
> The patch below changes that case to report
> ERRCODE_INVALID_PARAMETER_VALUE instead, matching the nearby precision
> validation in the same function. It also adds a regression test that
> catches the error as invalid_parameter_value.
>

I wonder whether AdjustIntervalForTypmod() should be changed too.
pg_catalog.interval(interval, int4) is SQL-callable, so users can pass
arbitrary typmod values directly. If such an invalid typmod reaches
AdjustIntervalForTypmod(), reporting XX000 seems inappropriate, since
it is not really an internal error but invalid user input.

> Tested with the interval regression test.
>

Could we use ERRCODE_INVALID_PARAMETER_VALUE for this case and add a
regression test covering a direct call to
pg_catalog.interval(interval, int4) with an invalid typmod?

> Regards,
> Feng
>
> ---
> src/backend/utils/adt/timestamp.c | 4 +++-
> src/test/regress/expected/interval.out | 10 ++++++++++
> src/test/regress/sql/interval.sql | 9 +++++++++
> 3 files changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/src/backend/utils/adt/timestamp.c
> b/src/backend/utils/adt/timestamp.c
> index a20e7ea1..01b9ed52 100644
> --- a/src/backend/utils/adt/timestamp.c
> +++ b/src/backend/utils/adt/timestamp.c
> @@ -1489,7 +1489,9 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod,
> /* fractional-second rounding will be dealt with below */
> }
> else
> - elog(ERROR, "unrecognized interval typmod: %d", typmod);
> + ereturn(escontext, false,
> + (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
> + errmsg("unrecognized interval typmod: %d", typmod)));
>
> /* Need to adjust sub-second precision? */
> if (precision != INTERVAL_FULL_PRECISION)
> diff --git a/src/test/regress/expected/interval.out
> b/src/test/regress/expected/interval.out
> index a16e3ccd..c5e10482 100644
> --- a/src/test/regress/expected/interval.out
> +++ b/src/test/regress/expected/interval.out
> @@ -857,6 +857,16 @@ SELECT interval(2) '1 day 01:23:45.6789';
> 1 day 01:23:45.68
> (1 row)
>
> +-- invalid typmods passed to the length-coercion function are user errors,
> +-- not internal errors
> +DO $$
> +BEGIN
> + PERFORM pg_catalog.interval(interval '1 day', 1539);
> +EXCEPTION WHEN invalid_parameter_value THEN
> + RAISE NOTICE 'invalid interval typmod rejected';
> +END
> +$$;
> +NOTICE: invalid interval typmod rejected
> SELECT interval '12:34.5678' minute to second(2); -- per SQL spec
> interval
> -------------
> diff --git a/src/test/regress/sql/interval.sql
> b/src/test/regress/sql/interval.sql
> index 43bc7939..88794c21 100644
> --- a/src/test/regress/sql/interval.sql
> +++ b/src/test/regress/sql/interval.sql
> @@ -257,6 +257,15 @@ SELECT interval '123 2:03 -2:04'; -- not ok,
> redundant hh:mm fields
> -- test syntaxes for restricted precision
> SELECT interval(0) '1 day 01:23:45.6789';
> SELECT interval(2) '1 day 01:23:45.6789';
> +-- invalid typmods passed to the length-coercion function are user errors,
> +-- not internal errors
> +DO $$
> +BEGIN
> + PERFORM pg_catalog.interval(interval '1 day', 1539);
> +EXCEPTION WHEN invalid_parameter_value THEN
> + RAISE NOTICE 'invalid interval typmod rejected';
> +END
> +$$;
> SELECT interval '12:34.5678' minute to second(2); -- per SQL spec
> SELECT interval '1.234' second;
> SELECT interval '1.234' second(2);
> --
> 2.50.1 (Apple Git-155)
>
>

Regards
Haibo

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Masahiko Sawada 2026-06-30 18:16:54 Re: Add MIN/MAX aggregate support for uuid
Previous Message Haibo Yan 2026-06-30 18:03:44 Re: Optimize UUID parse using SIMD