From 4f1c3facf9545916ec6d204b8cf77e9917f2b253 Mon Sep 17 00:00:00 2001 From: Shihao Date: Sun, 4 Oct 2026 14:55:26 -0400 Subject: [PATCH v2] Add planner support function to two-argument regexp_like() With no flags, regexp_like() is the same test as the ~ operator, but it had no planner support function, so it got no index condition from a pattern with a fixed prefix. Point it at textregexeq_support(), which already handles a FuncExpr. The three-argument form is left alone, since some flags make prefix extraction unsound. Discussion: https://postgr.es/m/CAGRkXqQZA-LX2UGewj9jHEmUE94U49i8XJjauDiUxZ34Tv1S-g@mail.gmail.com --- src/include/catalog/pg_proc.dat | 3 ++- src/test/regress/expected/btree_index.out | 17 +++++++++++++++++ src/test/regress/sql/btree_index.sql | 11 +++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f46427258e3..08d30bc7aba 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3856,7 +3856,8 @@ proargnames => '{string, pattern, start, N, endoption, flags, subexpr}', prosrc => 'regexp_instr' }, { oid => '6263', descr => 'test for regexp match', - proname => 'regexp_like', prorettype => 'bool', proargtypes => 'text text', + proname => 'regexp_like', prosupport => 'textregexeq_support', + prorettype => 'bool', proargtypes => 'text text', proargnames => '{string, pattern}', prosrc => 'regexp_like_no_flags' }, { oid => '6264', descr => 'test for regexp match', proname => 'regexp_like', prorettype => 'bool', diff --git a/src/test/regress/expected/btree_index.out b/src/test/regress/expected/btree_index.out index 3a83e9a0534..70c6eb75e24 100644 --- a/src/test/regress/expected/btree_index.out +++ b/src/test/regress/expected/btree_index.out @@ -767,6 +767,23 @@ select * from btree_bpchar where f1::bpchar like 'foo%'; -- get test coverage for "single value" deduplication strategy: insert into btree_bpchar select 'foo' from generate_series(1,1500); +-- Check that the two-argument form of regexp_like() has a planner support +-- function attached, so it gets an index condition like the ~ operator. +create temp table btree_regexp_like (f1 text collate "C"); +create index on btree_regexp_like(f1); +set enable_seqscan to false; +set enable_bitmapscan to false; +explain (costs off) +select * from btree_regexp_like where regexp_like(f1, '^item999'); + QUERY PLAN +--------------------------------------------------------------------- + Index Only Scan using btree_regexp_like_f1_idx on btree_regexp_like + Index Cond: ((f1 >= 'item999'::text) AND (f1 < 'item99:'::text)) + Filter: regexp_like(f1, '^item999'::text) +(3 rows) + +reset enable_seqscan; +reset enable_bitmapscan; -- -- Perform unique checking, with and without the use of deduplication -- diff --git a/src/test/regress/sql/btree_index.sql b/src/test/regress/sql/btree_index.sql index a08bb101c20..f2196fddf04 100644 --- a/src/test/regress/sql/btree_index.sql +++ b/src/test/regress/sql/btree_index.sql @@ -414,6 +414,17 @@ select * from btree_bpchar where f1::bpchar like 'foo%'; -- get test coverage for "single value" deduplication strategy: insert into btree_bpchar select 'foo' from generate_series(1,1500); +-- Check that the two-argument form of regexp_like() has a planner support +-- function attached, so it gets an index condition like the ~ operator. +create temp table btree_regexp_like (f1 text collate "C"); +create index on btree_regexp_like(f1); +set enable_seqscan to false; +set enable_bitmapscan to false; +explain (costs off) +select * from btree_regexp_like where regexp_like(f1, '^item999'); +reset enable_seqscan; +reset enable_bitmapscan; + -- -- Perform unique checking, with and without the use of deduplication -- -- 2.37.1 (Apple Git-137.1)