Skip to content

Commit e44ef91

Browse files
ahrzbclaude
authored andcommitted
fix(tests): cbrt oracle parity is <=1 ulp — DuckDB's own wheels disagree 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>
1 parent 473c567 commit e44ef91

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

docs/superpowers/specs/2026-07-26-wave1-builtin-pins.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ are binder errors — no implicit cast):
4545
- `Sqrt`: TRAP on any negative incl. -inf ("cannot take square root of a
4646
negative number"); sqrt(-0.0) = -0.0 (not a trap — IEEE).
4747
- `Cbrt`: TOTAL; cbrt(-8) = -2.0 exactly (NOT pow(x,1/3) which is NaN).
48+
CI-discovered addendum: DuckDB's own wheels disagree with each other on
49+
cbrt by one ulp across platforms (Windows wheel == Rust/ucrt bit-exact;
50+
Linux wheel's bundled std::cbrt returns e.g. 3.0000000000000004 for
51+
cbrt(27)). The engine stays deterministic (Rust cbrt); oracle parity for
52+
cbrt is pinned to <= 1 ulp, not repr-exact — the only such exception.
4853
- `SinF64/CosF64/TanF64`: TRAP on ±inf ("Out of Range Error: input value
4954
inf is out of range for numeric function"); NaN passes through
5055
BIT-EXACTLY (payload+sign preserved — check is_nan() BEFORE calling

tests/test_duckdb_interpreter.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,9 +894,46 @@ def test_sqrt_non_negative_domain():
894894
)
895895

896896

897+
def duck_check_ulp(sql, row_schema, row_rows, max_ulp=1):
898+
"""duck_check with a float ulp tolerance, POSITIONAL compare (no joins).
899+
900+
Exists for exactly one reason so far: DuckDB's own wheels disagree with
901+
each other on cbrt by one ulp across platforms (Windows wheel matches
902+
Rust/ucrt bit-exactly; the Linux wheel's bundled std::cbrt is one ulp
903+
off on e.g. cbrt(27)) — CI-discovered 2026-07-26. The oracle itself is
904+
platform-inconsistent here, so repr-exact parity is unpinnable.
905+
"""
906+
import math
907+
import struct
908+
909+
model = _row_model(row_schema)
910+
fn = DuckDBInferFn(sql, row_tables={"__THIS__": model}, static_tables={})
911+
inputs = [model(**r) for r in row_rows]
912+
got = [r.model_dump() for r in fn.infer({"__THIS__": inputs})]
913+
914+
con = duckdb.connect()
915+
con.register("__arrow_this", static(row_schema, row_rows))
916+
con.execute("CREATE TABLE __THIS__ AS SELECT * FROM __arrow_this")
917+
want = con.execute(sql).to_arrow_table().to_pylist()
918+
919+
def close(a, b):
920+
if isinstance(a, float) and isinstance(b, float):
921+
if math.isnan(a) and math.isnan(b):
922+
return True
923+
ia = struct.unpack("<q", struct.pack("<d", a))[0]
924+
ib = struct.unpack("<q", struct.pack("<d", b))[0]
925+
return abs(ia - ib) <= max_ulp
926+
return repr(a) == repr(b)
927+
928+
assert len(got) == len(want)
929+
for g, w in zip(got, want, strict=True):
930+
for k in g:
931+
assert close(g[k], w[k]), f"{k}: {g[k]!r} vs {w[k]!r} (> {max_ulp} ulp)"
932+
933+
897934
def test_sqrt_cbrt_bigint():
898935
xs = [4, 0, 27, 9223372036854775807, 9007199254740992, 9007199254740993, None]
899-
duck_check(
936+
duck_check_ulp(
900937
"SELECT sqrt(x) AS s, cbrt(x) AS c FROM __THIS__",
901938
{"x": "int?"},
902939
[{"x": x} for x in xs],
@@ -905,8 +942,9 @@ def test_sqrt_cbrt_bigint():
905942

906943
def test_cbrt_total_function():
907944
# cbrt has NO domain restriction: negatives, -inf, -0.0 all flow through.
945+
# ulp-tolerant: the oracle's own wheels disagree cross-platform on cbrt.
908946
xs = [8.0, -8.0, 27.0, 2.0, 0.0, -0.0, INF, -INF, NAN, None, 5e-324, -1.0]
909-
duck_check(
947+
duck_check_ulp(
910948
"SELECT cbrt(x) AS c FROM __THIS__", {"x": "float?"}, [{"x": x} for x in xs]
911949
)
912950

0 commit comments

Comments
 (0)