From da0a1ae86c794f788612ad5b0ca07b68c08a37e0 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 22:15:52 +0000 Subject: [PATCH 1/4] tests: confirm ilike/like newline matching bug Add failing tests that demonstrate % and _ wildcards in like/ilike do not match across newline characters. --- .../db/tests/query/compiler/evaluators.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/db/tests/query/compiler/evaluators.test.ts b/packages/db/tests/query/compiler/evaluators.test.ts index 68e08d7ea..26478d04d 100644 --- a/packages/db/tests/query/compiler/evaluators.test.ts +++ b/packages/db/tests/query/compiler/evaluators.test.ts @@ -374,6 +374,23 @@ describe(`evaluators`, () => { // In 3-valued logic, ilike with undefined pattern returns UNKNOWN (null) expect(compiled({})).toBe(null) }) + + it(`like % wildcard matches across newline characters`, () => { + const func = new Func(`like`, [ + new Value(`hello\nworld`), + new Value(`%world`), + ]) + const compiled = compileExpression(func) + + expect(compiled({})).toBe(true) + }) + + it(`like _ wildcard matches a newline character`, () => { + const func = new Func(`like`, [new Value(`a\nb`), new Value(`a_b`)]) + const compiled = compileExpression(func) + + expect(compiled({})).toBe(true) + }) }) describe(`comparison operators`, () => { From d20bb60c61cc34daae280a54a28301b12dc7cb40 Mon Sep 17 00:00:00 2001 From: Laurent Direr <4263535+ldirer@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:04:16 +0100 Subject: [PATCH 2/4] tests: add ilike with newline e2e test --- .../src/fixtures/seed-data.ts | 1 + .../src/suites/predicates.suite.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/db-collection-e2e/src/fixtures/seed-data.ts b/packages/db-collection-e2e/src/fixtures/seed-data.ts index 98b979404..818f2acf2 100644 --- a/packages/db-collection-e2e/src/fixtures/seed-data.ts +++ b/packages/db-collection-e2e/src/fixtures/seed-data.ts @@ -68,6 +68,7 @@ export function generateSeedData(): SeedDataResult { `Rose ${i}`, `sam ${i}`, `Tina ${i}`, + `Ursula ${i}\nNewline`, ] const name = names[i % names.length] diff --git a/packages/db-collection-e2e/src/suites/predicates.suite.ts b/packages/db-collection-e2e/src/suites/predicates.suite.ts index 2b3a9b216..eef75f7dc 100644 --- a/packages/db-collection-e2e/src/suites/predicates.suite.ts +++ b/packages/db-collection-e2e/src/suites/predicates.suite.ts @@ -412,6 +412,27 @@ export function createPredicatesTestSuite( await query.cleanup() }) + it(`should filter with like() with wildcard pattern matching newline`, async () => { + const config = await getConfig() + const usersCollection = config.collections.onDemand.users + + const query = createLiveQueryCollection((q) => + q + .from({ user: usersCollection }) + .where(({ user }) => like(user.name, `Ursula%`)), + ) + + await query.preload() + await waitForQueryData(query, { minSize: 1 }) + + const results = Array.from(query.state.values()) + expect(results.length).toBeGreaterThan(0) + // should match names starting with "Ursula" even if it contains a newline character + assertAllItemsMatch(query, (u) => u.name.startsWith(`Ursula`)) + + await query.cleanup() + }) + it(`should filter with like() with lower() function`, async () => { const config = await getConfig() const usersCollection = config.collections.onDemand.users From f93a4786b21688c37ebf69fef20e81de5dca4ee6 Mon Sep 17 00:00:00 2001 From: Laurent Direr <4263535+ldirer@users.noreply.github.com> Date: Wed, 18 Feb 2026 10:36:52 +0100 Subject: [PATCH 3/4] fix: make like % match newline characters --- packages/db/src/query/compiler/evaluators.ts | 3 ++- packages/query-db-collection/e2e/query-filter.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/db/src/query/compiler/evaluators.ts b/packages/db/src/query/compiler/evaluators.ts index 1e2637a73..bd13aac64 100644 --- a/packages/db/src/query/compiler/evaluators.ts +++ b/packages/db/src/query/compiler/evaluators.ts @@ -516,6 +516,7 @@ function evaluateLike( regexPattern = regexPattern.replace(/%/g, `.*`) // % matches any sequence regexPattern = regexPattern.replace(/_/g, `.`) // _ matches any single char - const regex = new RegExp(`^${regexPattern}$`) + // 's' (dotAll flag) makes '.' match all characters including line terminations + const regex = new RegExp(`^${regexPattern}$`, 's') return regex.test(searchValue) } diff --git a/packages/query-db-collection/e2e/query-filter.ts b/packages/query-db-collection/e2e/query-filter.ts index 43f4d0e87..aa3de76b1 100644 --- a/packages/query-db-collection/e2e/query-filter.ts +++ b/packages/query-db-collection/e2e/query-filter.ts @@ -556,7 +556,7 @@ function evaluateLike( regexPattern = regexPattern.replace(/%/g, `.*`) // % matches any sequence regexPattern = regexPattern.replace(/_/g, `.`) // _ matches any single char - const regex = new RegExp(`^${regexPattern}$`) + const regex = new RegExp(`^${regexPattern}$`, 's') return regex.test(searchValue) } From 90eea960ae2ca8c3c3181de92e024f4bc94f8024 Mon Sep 17 00:00:00 2001 From: Laurent Direr <4263535+ldirer@users.noreply.github.com> Date: Wed, 18 Feb 2026 12:58:03 +0100 Subject: [PATCH 4/4] changeset --- .changeset/nice-months-nail.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nice-months-nail.md diff --git a/.changeset/nice-months-nail.md b/.changeset/nice-months-nail.md new file mode 100644 index 000000000..54ee79419 --- /dev/null +++ b/.changeset/nice-months-nail.md @@ -0,0 +1,5 @@ +--- +'@tanstack/db': patch +--- + +Fix like/ilike `%` and `_` not matching newline characters