Problem with ST_NRings
Marco Boeringa
marco at boeringa.demon.nl
Tue Dec 2 21:14:13 PST 2025
Op 3-12-2025 om 04:38 schreef Regina Obe:
>> On 2025-12-02 20:19 +0100, Marco Boeringa wrote:
>>> If I change the CREATE MATERIALIZED VIEW to CREATE TABLE, exactly the
>>> same SQL statement succeeds... Both modes used to work. My current
>>> setup is PostgreSQL 18.1 / PostGIS 3.6.1.
>>>
>>> Op 2-12-2025 om 19:57 schreef Marco Boeringa:
>>>> As part of a larger workflow, I am using a custom PostgreSQL
>>>> function that depends on ST_NRings, and is used to create a
>> MATERIALIZED VIEW.
>>>> This has worked flawlessly until recently. I now ran into an issue
>>>> with the error message below. Going over my own code calling the
>>>> custom function that includes the ST_NRings call, I just cannot see
>>>> any recent code change made by myself explaining this sudden error.
>>>> This part of the code has been stable for quite a while.
>>>>
>>>> As input to the custom function, WGS1984 OpenStreetMap data is used,
>>>> stored as 'geometry' type. There are actually explicit type casts
>>>> in the code as well, so even that part of the error message I cannot
>>>> explain for now.
>>>>
>>>> My question: has there been any change to ST_NRings in a recent
>>>> update of PostGIS (3.6.0 or 3.6.1?), that might explain this error?
>>>> E.g. should the 'public' be in this error message at all, I would
>>>> have expected
>>>> "ERROR: function st_nrings(geometry) does not exist"?
>>>>
>>>> ERROR: function st_nrings(public.geometry) does not exist LINE 8:
>>>> WHEN ST_NRings($1) = 1 THEN $1
>>>> ^
>>>> HINT: No function matches the given name and argument types. You
>>>> might need to add explicit type casts.
>> Postgres runs REFRESH MATERIALIZED VIEW (and other maintenance
>> commands) with a safe search_path since version 17 [1]. That also explains
>> why you see type public.geometry instead of just geometry in the error
>> message.
>>
>> You need to use the qualified function name public.ST_NRings in your custom
>> function. Or change the search_path config of that function so that it no
>> longer depends on the session search_path, e.g.:
>>
>> CREATE FUNCTION my_func(public.geometry)
>> RETURNS int
>> SET search_path = public, pg_catalog, pg_temp
>> AS $$ SELECT ST_NRings($1); $$ LANGUAGE sql;
>>
>> [1] https://www.postgresql.org/docs/17/release-17.html#RELEASE-17-
>> MIGRATION
>>
>> --
>> Erik Wienhold
> It would be better if you used the fully qualified name.
> Using search_path in a function crushes query performance.
>
> CREATE FUNCTION my_func(public.geometry)
> RETURNS int
> AS $$ SELECT public.ST_NRings($1); $$ LANGUAGE sql;
Hi Regina,
Thanks for that important warning about the performance aspect. However,
do you possibly have any real world figures of how much of a difference
this makes? Just doing an internet search on 'search_path' and
'performance' doesn't turn up much of relevant results for something
that might be critical. I can see how a custom search path loaded with
objects might turn a 'search' into a heavy operation, but I would expect
PostgreSQL to at least cache some reference to the main functions and
objects of system 'public', 'pg_catalog' and 'pg_temp' schema's, but
maybe I am just naive here?
Although I could change the code, having to add 'public' before each
PostGIS function or class, would make my Python code assembling queries
a lot less readable. Or is the performance issue you express concerns
about mainly related to function definitions like in CREATE FUNCTION,
which would make adjustment much more straightforward, as it would only
require modifying the function definitions themselves, not all uses in SQL?
Marco
More information about the postgis-users
mailing list