Thread
-
Re: Remaining dependency on setlocale()
Jeff Davis <pgsql@j-davis.com> — 2025-12-16T20:04:54Z
On Tue, 2025-12-16 at 09:32 +0800, Chao Li wrote: > I have re-reviewed 0003-0005 last week, they all look good to me. > > I have no comment on backport 0003. Committed 0003 and backported to 14. Committing 0004 also. For the archives, the bug in that case is: -- generate some randomly-cased non-ASCII data CREATE DATABASE i TEMPLATE template0 LOCALE 'C' LOCALE_PROVIDER 'icu' ICU_LOCALE 'en'; \c i CREATE EXTENSION ltree; CREATE TABLE test(path ltree); CREATE FUNCTION gen() RETURNS TEXT LANGUAGE plpgsql AS $$ declare s TEXT; begin s := ''; for i in 1..5 loop s := s || case when random() > 0.5 then lower(U&'\00C1') else U&'\00C1' end; s := s || case when random() > 0.5 then lower(U&'\00C9') else U&'\00C9' end; s := s || case when random() > 0.5 then lower(U&'\00CD') else U&'\00CD' end; s := s || case when random() > 0.5 then lower(U&'\00D3') else U&'\00D3' end; s := s || case when random() > 0.5 then lower(U&'\00DA') else U&'\00DA' end; end loop; return s; end; $$; INSERT INTO test select ('a.'||gen()||'.z')::ltree FROM generate_series(1,10000); CREATE INDEX test_idx ON test USING gist (path); -- returns 10000 SET enable_seqscan = true; SET enable_indexscan = false; SET enable_bitmapscan = false; SELECT COUNT(*) FROM test WHERE path ~ U&'a.áéíóúáéíóúáéíóúáéíóúáéíóú@.z'::lquery; -- returns fewer tuples when using index scan SET enable_seqscan = false; SET enable_indexscan = true; SET enable_bitmapscan = true; SELECT COUNT(*) FROM test WHERE path ~ U&'a.áéíóúáéíóúáéíóúáéíóúáéíóú@.z'::lquery; Probably a smaller case would do, but I think it requires page splits to hit the bug. 0004 fixes the bug. > The old code didn’t create a locale object and store in result, thus > it didn’t have a logic to free the created locale. This patch now > dose that, but I don’t see where the created locale object is free- > ed. I suppose newlocale() will allocate memory from the OS, so I > guess the memory should be free-ed somewhere. The pg_locale_t objects are cached for the life of the backend, and never freed. We may want to change that eventually, but in practice it's not much of a problem. Regards, Jeff Davis