Specializer SQL support wave 2: LIKE/ILIKE + dynamic-table alias — corpus 240 → 265 (TASK-48) - #33
Merged
claude-agent-ahrzb[bot] merged 3 commits intoJul 26, 2026
Conversation
…in) created In Progress Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nal name (TASK-48) Measured: DuckDB makes qualified refs through the ORIGINAL name binder errors once aliased; making the alias the binder's this_name reproduces that scoping for qualified binds, star expansion, and messages with a three-line change. AS/bare identical; column-renaming alias t(a,b) rejects by name. Census note in the ticket: the comma-join rewrite was DROPPED from wave scope — the corpus cases are self-joins of the dynamic table, so the planned rewrite would flip ~0 cases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… (TASK-48) Byte-based matcher with codepoint _, leftmost-first two-pointer backtracking: identical booleans AND identical error rows to DuckDB — including the data-dependent dangling-escape (plain false when the string is exhausted, per-row SyntaxException only when the matcher examines it with bytes remaining) — at O(n*m) where DuckDB's own column-pattern path is naive-recursive (measured 23s on one pathological row). ESCAPE: any single byte, doubled = literal, the escape char never matches itself unescaped, '' = none, NULL = NULL, multi-byte operand traps with DuckDB's message. ILIKE folds both sides with the measured simple casemap (== DuckDB lower(), exhaustive sweep). The corpus replay caught a genuine oracle divergence: ILIKE on NUL-containing rows is COLUMN-STATISTICS-dependent in DuckDB (sibling rows change the result) — irreproducible row-locally, now the repo's first documented divergence with the measurement attached. SIMILAR TO rejects by name (binds to regexp_full_match in DuckDB). Corpus: 240 -> 265 of 678, zero FAILs; gate green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ahrzb
approved these changes
Jul 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wave 2, pins-first throughout (
pins-wave1/pins_like.json, ~50 measured pin rows).Shipped
_(pinned against bytes, UTF-16 units, and graphemes), no normalization, backslash literal (no implicit escape — unlike Postgres). ESCAPE: any single byte, doubled = literal, the escape char never matches itself unescaped,''= none,NULL= NULL, multi-byte operand traps with DuckDB's message. The data-dependent dangling-escape is reproduced exactly: plainfalsewhen the string is exhausted, a per-row SyntaxException only when the matcher examines it with bytes remaining. Our matcher is O(n·m) two-pointer restart — identical booleans and identical error rows to DuckDB's naive-recursive path (measured at 23s/row there on pathological patterns).lower()over an exhaustive all-codepoint sweep) then LIKE.this_namereproduces the scoping in three lines. Column-renaming aliases reject by name.SIMILAR TOrejects by name: DuckDB binds it toregexp_full_match(RE2), not SQL wildcards — mapping it as wildcards would be silently wrong.The find of the wave
The corpus replay caught a live oracle divergence: DuckDB's ILIKE result for a NUL-containing row depends on its sibling rows — column statistics select an ASCII kernel (NUL-safe → TRUE) or the generic kernel (NUL-truncating fold → FALSE) for the identical row value. Statistics-dependent semantics are irreproducible by a row-at-a-time engine even in principle; this is now the repo's first documented oracle divergence (
_KNOWN_DIVERGENT_SOURCESin the corpus replay, measurement attached in the pins).Verification
_, control chars, data-dependent error rows, vectorized column patterns); Slike fuzz-covered in the 500-seed differential.🤖 Generated with Claude Code