PL/pgSQL: fix validation of anycompatiblemultirange
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
This thread has been committed, so CI has stopped here. Anything below is the last result it produced.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t254392psql -h localhost -U postgresBuilt from patchset v1 (message #1), October 26, 2026 at 01:20 PM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t254392_1 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t254392_1 && git checkout t254392_1Patchset v1 (message #1) is on t254392_1
Hi,
When validating a PL/pgSQL function with polymorphic arguments or result
type,
we substitute a plausible concrete type for each polymorphic type. This is
done in two places, cfunc_resolve_polymorphic_argtypes() in funccache.c for
arguments and plpgsql_compile_callback() in pl_comp.c for the result type.
Both handle anycompatiblerange and anymultirange, but neither handles
anycompatiblemultirange. This appears to have been missed when multiranges
were added in 6df7a9698bb (v14), which added the anymultirange case to both
places but did not add any PL/pgSQL test for anycompatiblemultirange.
This has two visible effects. First, with check_function_bodies = ON,
creating
a function with an anycompatiblemultirange argument fails:
CREATE FUNCTION f1(x anycompatiblemultirange)
RETURNS anycompatiblemultirange AS $$
BEGIN RETURN x; END $$ LANGUAGE plpgsql;
ERROR: PL/pgSQL functions cannot accept type anycompatiblemultirange
The same function can be created with check_function_bodies = off, and then
works, so only the validation path is wrong.
Second, a function that only returns anycompatiblemultirange is compiled by
the validator with an int4 result type. The function cache key does not
include the result type, so a later call in the same session with the same
argument types the validator used (int4range here) reuses that entry, and
fails:
CREATE FUNCTION f1(x anycompatiblerange)
RETURNS anycompatiblemultirange AS $$
BEGIN RETURN multirange(x); END $$ LANGUAGE plpgsql;
SELECT f1(int4range(42, 49));
ERROR: invalid input syntax for type integer: "{[42,49)}"
A call with other argument types, say numrange, gets its own cache entry and
works, which is why this can go unnoticed.
The attached patch maps anycompatiblemultirange to int4multirange in both
places, as is already done for anymultirange, which fixes both issues.
It also adds two regression tests to plpgsql.sql, one for each case above.
Both fail without the fix.
Since this is a plain bug fix, I think it should be back-patched to v14,
where
anycompatiblemultirange was introduced, but I'd like to hear what others
think. On branches before v18 the argument-type fix would go in pl_comp.c,
since cfunc_resolve_polymorphic_argtypes() in funccache.c is newer.
Thanks
--
*Jeevan Chalke*
*Senior Principal Engineer, Engineering Manager*
*Product Development*
enterprisedb.com <https://www.enterprisedb.com>
Hi
po 26. 10. 2026 v 14:06 odesílatel Jeevan Chalke <
jeevan.chalke@enterprisedb.com> napsal:
Hi,
When validating a PL/pgSQL function with polymorphic arguments or result
type,
we substitute a plausible concrete type for each polymorphic type. This is
done in two places, cfunc_resolve_polymorphic_argtypes() in funccache.c
for
arguments and plpgsql_compile_callback() in pl_comp.c for the result type.
Both handle anycompatiblerange and anymultirange, but neither handles
anycompatiblemultirange. This appears to have been missed when
multiranges
were added in 6df7a9698bb (v14), which added the anymultirange case to
both
places but did not add any PL/pgSQL test for anycompatiblemultirange.This has two visible effects. First, with check_function_bodies = ON,
creating
a function with an anycompatiblemultirange argument fails:CREATE FUNCTION f1(x anycompatiblemultirange)
RETURNS anycompatiblemultirange AS $$
BEGIN RETURN x; END $$ LANGUAGE plpgsql;
ERROR: PL/pgSQL functions cannot accept type anycompatiblemultirangeThe same function can be created with check_function_bodies = off, and
then
works, so only the validation path is wrong.Second, a function that only returns anycompatiblemultirange is compiled
by
the validator with an int4 result type. The function cache key does not
include the result type, so a later call in the same session with the same
argument types the validator used (int4range here) reuses that entry, and
fails:CREATE FUNCTION f1(x anycompatiblerange)
RETURNS anycompatiblemultirange AS $$
BEGIN RETURN multirange(x); END $$ LANGUAGE plpgsql;
SELECT f1(int4range(42, 49));
ERROR: invalid input syntax for type integer: "{[42,49)}"A call with other argument types, say numrange, gets its own cache entry
and
works, which is why this can go unnoticed.The attached patch maps anycompatiblemultirange to int4multirange in both
places, as is already done for anymultirange, which fixes both issues.It also adds two regression tests to plpgsql.sql, one for each case above.
Both fail without the fix.Since this is a plain bug fix, I think it should be back-patched to v14,
where
anycompatiblemultirange was introduced, but I'd like to hear what others
think. On branches before v18 the argument-type fix would go in pl_comp.c
,
since cfunc_resolve_polymorphic_argtypes() in funccache.c is newer.
+1
Pavel
Show quoted text
Thanks
--
*Jeevan Chalke*
*Senior Principal Engineer, Engineering Manager*
*Product Development*enterprisedb.com <https://www.enterprisedb.com>
Jeevan Chalke <jeevan.chalke@enterprisedb.com> writes:
When validating a PL/pgSQL function with polymorphic arguments or result
type,
we substitute a plausible concrete type for each polymorphic type. This is
done in two places, cfunc_resolve_polymorphic_argtypes() in funccache.c for
arguments and plpgsql_compile_callback() in pl_comp.c for the result type.
Both handle anycompatiblerange and anymultirange, but neither handles
anycompatiblemultirange. This appears to have been missed when multiranges
were added in 6df7a9698bb (v14), which added the anymultirange case to both
places but did not add any PL/pgSQL test for anycompatiblemultirange.
Good catch, fix pushed. I didn't bother with the test cases though,
as they seem too specific to help us catch any future problems.
regards, tom lane