Skip to content

Specializer SQL support: workload builtins & predicates wave 1 — corpus 172 → 240 (TASK-47) - #32

Merged
claude-agent-ahrzb[bot] merged 12 commits into
masterfrom
claude/specializer-builtins-wave1
Jul 26, 2026
Merged

Specializer SQL support: workload builtins & predicates wave 1 — corpus 172 → 240 (TASK-47)#32
claude-agent-ahrzb[bot] merged 12 commits into
masterfrom
claude/specializer-builtins-wave1

Conversation

@claude-agent-ahrzb

Copy link
Copy Markdown

The builtins wave, measurement-first throughout: a six-family fleet pinned DuckDB 1.5.5's exact edge semantics (300+ pin rows, committed under docs/superpowers/specs/pins-wave1/) BEFORE any implementation, and every shipped op is the pin.

Shipped

  • Predicates as exact compositions (zero IR): BETWEEN/IN → K3 desugars with whole-construct f64 unification; least/greatest → CASE + duck-order (NULL-ignoring, first-arg ties, NaN-above-inf all fall out).
  • 14 math ops + log(b,x): ln/log/log2/log10/exp/sqrt/cbrt/sin/cos/tan/floor/ceil/trunc/pow. Pins that shaped the code: 1-arg log is base 10; log(b,x) is bit-exactly log10(x)/log10(b); log family traps on x≤0 (so NULL lowering masks to op-safe constants — 0.0 is inside the trap domain — and Flogb masks under the combined flag since NULL pre-empts every domain check); trig traps on ±inf but passes NaN through bit-exactly; exp/pow/cbrt are total.
  • round/trunc with digits: DuckDB's scale factor is its own std::pow(10,k) — neither correctly-rounded nor plain ucrt — so the table is extracted from the oracle (scripts/gen_pow10.py, ulp witnesses checked at generation). Wrapping i64 round, measured round/trunc non-finite asymmetry preserved.
  • 6 string-search ops: instr/strpos/position (incl. position(n IN s)), contains, starts_with/ends_with (+aliases), length/strlen — 1-based codepoint positions, empty-needle-matches-all, NULL-strict. The corpus refuted one fleet pin (contains-NULL); re-measurement found the real overload-anchoring rule, mirrored exactly.
  • Measured rejections stay honest: ^ maps would compute the wrong tree (sqlparser binds it below *, DuckDB above) — named unsupported, pow() carries the semantics; ** doesn't parse.

Verification

  • Both backends share one semantic fn per op; the 500-seed differential covers all new ops including trap agreement; ~40 new duck_check oracle test groups (49-row IEEE pow specials, huge-arg trig fidelity, pow-table ulp witnesses only the extracted table passes).
  • Corpus: 172 → 240 match of 678, zero wrong answers (53 at start of day — 4.5×). Remaining head is structural: comma joins, dynamic-table aliases, COUNT aggregations, table functions, list types.
  • Scenario re-audit (AC ci: review PRs with Claude Code + superpowers plugin #3): 47 famous-solution features restored across the four Kaggle serving pipelines (24→31, 42→54, 41→57, 44→56 outputs) — ln(1+x) everywhere, decade buckets, Deotte cents, IN-set flags, domain parsing, sin/cos cyclical encodings — all under the standing three-way parity gate (specializer == DuckDB == handcrafted).
  • Gate green: cargo 129 / pytest 671 / 13 xfail.

Also in this PR: TASK-46 star-expansion ticket closed with final summary; TASK-47 fully checked.

🤖 Generated with Claude Code

ahrzb and others added 12 commits July 26, 2026 11:39
…easurement-first stretch plan

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t for TASK-47

Six-family measurement fleet against DuckDB 1.5.5 through the
vectorized path; full pin tables (300+ rows) in pins-wave1/*.json,
implementation-shaping decisions condensed in the spec. Headlines:
1-arg log is BASE 10; log(b,x) is bit-exactly log10(x)/log10(b);
log family traps on x<=0 while exp/pow/cbrt are total; trig traps on
+-inf but passes NaN through bit-exactly; ^ is pow with -2^2=+4 and
left associativity; least/greatest ignore NULLs with first-arg ties;
round(x,-n) wraps at i64 and needs an oracle-pinned pow10 table;
string positions are 1-based codepoints with empty-needle-matches-all;
BETWEEN and IN are exact K3 desugars.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ch 2)

Pure frontend rewrites onto the existing comparison + Kleene machinery
— zero IR/backend changes. DuckDB's whole-construct type unification is
reproduced by promoting every side to DOUBLE when any side is (CAST in
the rewritten AST, no-op on f64 sides, types NULL literals from
context); numeric-with-string/bool mixing rejects by name (exec-time
cast semantics we don't model). The pinned truth tables — NULL in every
position, NaN-above-inf, empty ranges, signed zeros, NULL list elements
(1 IN (1,NULL)=TRUE, 3 IN (1,NULL)=NULL), NOT variants — land as
duck_check oracle tests. Corpus: 172 -> 179 match; the remaining
BETWEEN corpus cases move to NAMED deeper blockers (COUNT aggregation
shapes, NULL-op-NULL typing), zero FAILs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…2/log10/exp/sqrt/cbrt/sin/cos/tan/floor/ceil/trunc/pow (TASK-47 stretch 3a)

Fourteen ops end-to-end: IR (NumOp1 + Fpow/Flogb BinOps), parser,
verifier-by-sig, interpreter closures over ONE shared semantic fn per
op, cranelift helpers delegating to those same fns (floor/ceil/trunc
inline CLIF), fuzz generator coverage (trapping ops at low weight —
trap agreement is differential signal), frontend catalogue with
int->f64 promotion and DuckDB's binder rejections, and NULL-safe
lowering: trapping unaries mask NULL payloads to op-safe constants
(1.0 for logs — the type default 0.0 is IN the trap domain), and
Flogb masks BOTH operands under the COMBINED flag because NULL
pre-empts every domain check (pinned: log(-2.0, NULL) is NULL).
1-arg log is base 10; log(b,x) is log10(x)/log10(b) bit-exactly;
trig traps on +-inf and passes NaN through untouched; pi() folds to
the pinned literal. The ^ operator stays cleanly UNSUPPORTED:
sqlparser parses it below * while DuckDB binds it above (measured
tree divergence) — pow()/power() carry the semantics; ** does not
parse. 21 oracle tests incl. 49-row IEEE pow specials and huge-arg
trig reduction fidelity; 659 pytest + 129 cargo green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ains, starts_with/ends_with (+prefix/suffix), length/strlen (TASK-47 stretch 3b)

Two IR forms (Str2 with an op enum, SLen) through parser/printer/
verifier/fuzz and both backends via shared semantic fns: 1-based
CODEPOINT positions (not bytes, not graphemes — the ZWJ-family pin),
empty needle matches everything, byte-wise comparison with zero
unicode intelligence, total and NULL-strict in every argument. The
SQL-standard position(needle IN haystack) AST form binds needle-first.
The corpus REFUTED the fleet's contains-NULL pin (mined cases execute
fine): the real rule, re-measured, is that a NULL literal needle binds
iff a NON-literal Str haystack anchors overload resolution — mirrored
exactly, all four measured combinations reproduced. Corpus: 179 -> 237
match of 678 (+58 with the math wave), zero FAILs. 663 pytest + 129
cargo green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ASK-47 stretch 3c)

No IR op: NULL-ignoring semantics, first-argument ties (pinned via
-0.0 vs 0.0), and NaN-above-inf all fall out of the CASE / IS NULL /
duck_fcmp composition, left-folded for the n-ary form. Literal NULL
args are dropped (NULL-ignoring); int/f64 unify whole-call like
coalesce; strings compare byte-wise; booleans hit the engine's
pre-existing clean comparison limit. Oracle tests cover the pinned
NULL/NaN/tie/lossy-2^53 rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nario re-audit remaining

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…able, wrapping i64 semantics (TASK-47 stretch 3d)

Round2f/Round2i through the full stack. The f64 scale factor is
DuckDB's own std::pow(10, k), extracted bit-exactly into a generated
309-entry table (scripts/gen_pow10.py, witness-checked: k=23 is one
ulp above strtod 1e23, k=126 one below ucrt pow) — never a runtime
powi/powf. Measured asymmetries preserved: round's negative-n branch
turns NaN/+-inf into +0.0 while trunc returns the input; integer
round with negative digits WRAPS at i64 (round(i64::MAX,-2) =
-9223372036854775700) and |n|>=19 collapses to 0 — zero trap
conditions in the family. Both ops fuzz-covered; oracle tests include
the pow-table ulp witnesses that only the extracted table passes.
Corpus: 237 -> 240 match of 678, zero FAILs; 671 pytest green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… via wave-1 builtins (TASK-47 AC #3)

Titanic 24->31, Ames 42->54, IEEE-CIS fraud 41->57, Rossmann 44->56
output features, all parity-gated (specializer == DuckDB == handcrafted
on 300 seeded rows, cranelift asserted). The compromises the original
scenario designs recorded are now real features: ln(1+x) skew
transforms everywhere, decade buckets via round(x,-1) and floor,
Deotte cents, IN-set membership flags (rare titles, suspicious
domains, PUD classes, holiday codes), starts_with/ends_with/instr
domain parsing, sin/cos cyclical hour/day/month encodings with pi(),
least/greatest clamps and NULL-ignoring join-miss handling. Three
store_sales compromise expressions rewrote to their natural builtin
forms with identical values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ture

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ree cross-platform (CI)

CI (Linux) failed the two cbrt tests by exactly one ulp: the Linux
DuckDB wheel's bundled std::cbrt returns 3.0000000000000004 for
cbrt(27) while the Windows wheel (and Rust on both platforms) return
3.0. The oracle itself is platform-inconsistent for this one function,
so repr-exact parity is unpinnable: duck_check_ulp compares floats
within 1 ulp (positional, no joins), signed zeros still enforced, and
the pins spec records the exception — the only one in the wave.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude-agent-ahrzb
claude-agent-ahrzb Bot merged commit e44ef91 into master Jul 26, 2026
1 check passed
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