Documentation
¶
Overview ¶
Package oracle is the optimization-invariance differential harness (#287): every corpus query runs with all registered optimizations enabled (baseline), then once per optswitch toggle with just that optimization disabled, then with all of them disabled — and every configuration must produce identical results. An optimization that changes answers is a bug by definition; a divergence names the toggle, which is the defect localization.
The harness is corpus-agnostic: callers supply the queries and a RunFunc, so the TPC-H and ClickBench suites (and later a query generator) plug in the same way.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RunDifferential ¶
RunDifferential drives the oracle. It temporarily forces every registered toggle on for the baseline (host env notwithstanding, so a stray kill switch can't silently weaken the oracle), restores prior state on return, and reports each divergence as a failed subtest named after the disabled toggle.
Types ¶
type Canon ¶
type Canon struct {
// contains filtered or unexported fields
}
Canon is a result in canonical comparable form. Exported so other differential harnesses (the standalone-vs-distributed oracle, #288) share the same comparison semantics as the kill-switch oracle.
Rows are rendered at two float precisions. Rounding floats can land a value exactly on a rounding boundary, where one ULP of accumulation- order noise between two CORRECT runs flips the rendered digit (observed: SUM at 14903.55 rendering 14903.5 vs 14903.6). A divergence therefore only counts when it survives BOTH precisions — real bugs (missing rows, nulls, dropped limits, wrong groups) differ at every precision, while a boundary hit at two independent quanta simultaneously is vanishingly rare. The cost: a float-only error smaller than the coarse quantum (~1e-4 relative) is absorbed; row-membership and integer errors are unaffected.
func Canonicalize ¶
Canonicalize renders every row to a stable string: cells in Columns order, floats at 6 significant digits so accumulation-order noise between two correct runs doesn't register as divergence.
type Query ¶
type Query struct {
Name string
SQL string
// CountOnly relaxes the comparison to row counts within Tolerance.
// Reserved for queries whose row MEMBERSHIP legitimately shifts with
// float accumulation order (threshold comparisons over float
// aggregates, the TPC-H Q02/Q22 class) — cell-exact comparison would
// flake on borderline rows even between two correct runs.
CountOnly bool
Tolerance int
}
Query is one corpus entry.
func ExpandLimits ¶
ExpandLimits rewrites each LIMIT-ed query into two oracle entries: the stripped form (full-multiset compare — strictly stronger and tie-immune, same rationale as the DuckDB gate's stripLimit) and the verbatim form compared by row count only. At the LIMIT boundary any member of a tie group is admissible, so two correct runs can return different limited rows — but the row COUNT is deterministic, and running the verbatim query keeps LIMIT-dependent optimizations (top-N late materialization) exercised under the oracle. Queries already marked CountOnly keep that relaxation on the stripped form too.