-- test/sql/match_early_exit.sql -- -- The k=0 recheck asks TRE for no submatch offsets (nmatch=0) so the -- exact matcher stops at the first match instead of scanning the whole -- value for the leftmost-longest one (4.6.1). This must not change any -- result: boolean %~~ / tre_amatch, the edit cost, and -- crucially -- -- tre_amatch_detail's offsets (which DO request offsets, so the early -- exit must not apply there). CREATE EXTENSION IF NOT EXISTS pg_tre; \set VERBOSITY terse SET client_min_messages = warning; -- boolean recheck unchanged, including repeated/overlapping matches where -- "first match" differs from "leftmost-longest". SELECT 'abcabcabc' %~~ tre_pattern('abc', 0) AS b1, -- t 'xxsuuuyy' %~~ tre_pattern('su{3}', 0) AS b2, -- t 'nope' %~~ tre_pattern('abc', 0) AS b3, -- f 'aXbXc' %~~ tre_pattern('a.b.c', 0) AS b4; -- t -- tre_amatch_detail still returns correct offsets at k=0 (it requests -- offsets, so the early exit is disabled for it). Match 'bcd' inside -- 'abcde': bytes [1,4). SELECT match_start, match_end FROM tre_amatch_detail('abcde', 'bcd', 0); -- the edit cost is unchanged at k=0 (always 0 for an exact match) and the -- boolean agrees with a forced sequential scan on a small table. DROP TABLE IF EXISTS mee; CREATE TABLE mee (id int, s text); INSERT INTO mee VALUES (1,'the quick brown fox'), (2,'suuu here'), (3,'has su and uuu apart: su ... uuu'), (4,'aabcb match'), (5,'aa then bc then cb, not contiguous'), (6,'plain'); INSERT INTO mee SELECT g, 'filler '||g||' quick' FROM generate_series(100,300) g; CREATE INDEX mee_tre ON mee USING tre (s); ANALYZE mee; CREATE FUNCTION mee_agree(pat text) RETURNS boolean LANGUAGE plpgsql AS $$ DECLARE a int[]; b int[]; BEGIN PERFORM set_config('enable_seqscan','off',true); PERFORM set_config('enable_bitmapscan','on',true); PERFORM set_config('enable_indexscan','off',true); EXECUTE 'SELECT array_agg(id ORDER BY id) FROM mee WHERE s %~~ tre_pattern($1,0)' INTO a USING pat; PERFORM set_config('enable_seqscan','on',true); PERFORM set_config('enable_bitmapscan','off',true); EXECUTE 'SELECT array_agg(id ORDER BY id) FROM mee WHERE tre_amatch(s,$1,0)' INTO b USING pat; RETURN a IS NOT DISTINCT FROM b; END $$; SELECT bool_and(mee_agree(p)) AS index_eq_seq_at_k0 FROM (VALUES ('quick'),('su{3}'),('aa[bc]c[b-d]'),('a.b'),('o.*x')) v(p); DROP TABLE mee; DROP FUNCTION mee_agree(text);