Skip to content

perf(calcite): push a prefix LIKE into the scan as a string range - #558

Merged
dfa1 merged 1 commit into
mainfrom
feat/like-prefix-pushdown
Oct 18, 2026
Merged

dfa1 merged 1 commit into
mainfrom
feat/like-prefix-pushdown

Conversation

@dfa1

@dfa1 dfa1 commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Calcite matched LIKE row by row, and its interpreter compiled the pattern to a regex per row (Like.sqlToRegexLike + Pattern.compile ≈ 30% of a 2.5M-row title LIKE 'Star Wars%').

RexFilterTranslator now translates col LIKE 'prefix%' on a string column into col >= prefix AND col < successor(prefix) (last code point + 1, skipping surrogates). Code-point order is the UTF-8 byte order RowFilter compares strings in, so the range is exact: it prunes zones and the scan enforces it, so Calcite stops re-checking. Other wildcards and ESCAPE stay with Calcite; LIKE '%' is IS NOT NULL.

Raincloud imdb title (2.53M rows): count(*) where title like 'Star Wars%' 1049 → 206 ms.

Tests

  • LikePushDownTest: 10 patterns (incl. the Latin-1 boundary ÿ%, untranslated a_c%, %c, abc) equal Calcite's own LIKE over s || ''; successor edge cases.
  • vortex-jni cross-check: 6 patterns over a Rust-written file equal Calcite's answer.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WtuVGQ5h5Lk6Zn4JnkxF1K

Calcite matched LIKE row by row, and its interpreter compiled the pattern
to a regex for every row (Like.sqlToRegexLike + Pattern.compile were 30%
of a 2.5M-row title LIKE 'Star Wars%').

RexFilterTranslator now translates col LIKE 'prefix%' on a string column
into col >= prefix AND col < successor(prefix), where the successor
raises the prefix's last code point by one (skipping the surrogate block;
a trailing U+10FFFF is dropped first). Code-point order is the UTF-8 byte
order RowFilter compares strings in, so the range holds exactly the
strings starting with the prefix: it prunes zones from their string
bounds and the scan enforces it, so Calcite stops re-checking the row.
A pattern with another wildcard or an ESCAPE clause is left to Calcite;
LIKE '%' keeps every non-null row.

Raincloud imdb title (2.53M rows), best of 3:
  count(*) where title like 'Star Wars%'   1049 -> 206 ms

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WtuVGQ5h5Lk6Zn4JnkxF1K
@dfa1
dfa1 merged commit decaf94 into main Oct 18, 2026
9 checks passed
@dfa1
dfa1 deleted the feat/like-prefix-pushdown branch October 18, 2026 10:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant