Skip to content

fix(parity): close P10/P6/P12 + make history test reliable cross-platform#38

Merged
TimelordUK merged 2 commits into
mainfrom
fix/parity-p10-p6-p12-and-test-reliability
Jul 25, 2026
Merged

fix(parity): close P10/P6/P12 + make history test reliable cross-platform#38
TimelordUK merged 2 commits into
mainfrom
fix/parity-p10-p6-p12-and-test-reliability

Conversation

@TimelordUK

Copy link
Copy Markdown
Owner

Summary

Clears three DuckDB-parity gaps and fixes a long-standing flaky test. Parity board moves 72 → 76 AGREE, 10 → 6 GAP; each fixed case has its corpus expect dropped so the --check gate now locks the gain.

Two logically separate commits:

1. fix(parity) — P10, P6, P12

P Gap Fix
P10 HAVING NOT (…) errored (Unsupported expression type … Not) Added a Not arm to ArithmeticEvaluator::evaluate, negating via the existing to_bool helper with SQL three-valued logic on the NULL edge (NOT NULL → NULL).
P6 INTERSECT / EXCEPT unimplemented (return Err stubs) Implemented both in the set-op loop. DISTINCT-by-default, filtering the materialized left table against the right using the same Debug row-key apply_distinct uses for UNION, deduping inline.
P12 WITH rejected in expression position parse_subquery already dispatched a leading WITH to the CTE parser; widened the subquery-detection guards from Token::Select to Token::Select | Token::With in primary.rs (scalar + tuple IN) and comparison.rs (IN / NOT IN). Retires previously-unreachable CTEHoister arms.

Corpus note: the except case threshold moved 2000 → 3000 — every region has a sale > 2000, so the original form was trivially empty and would have AGREEd for the wrong reason; > 3000 leaves {Oceania}, a genuine left-minus-right difference.

docs/SQL_PARITY.md entries flipped to 🟢 FIXED with rationale.

2. test(history) — reliable cross-platform

history_protection_integration sandboxed the history dir by redirecting HOME/APPDATA, but dirs::data_dir() on Windows resolves via the Win32 known-folder API and ignores those env vars, so the test silently read the developer's real history and failed. Env-var redirection is also process-global, so #[serial] (which only serializes serial-tagged tests) couldn't stop a concurrent test from writing into the sandbox and tripping the history-protection guard — hence pass-alone / fail-in-suite flakiness.

Fix: added CommandHistory::with_history_file(path) and had new() delegate to it. The test now builds against an explicit tempdir file — no env var, no #[serial], no cross-test races. Also added a SQL_CLI_DATA_DIR override to AppPaths (honored directly, so it works on every platform) as a legitimate way to relocate/sandbox app data.

Testing

  • Parity harness: 76 AGREE / 1 DIFFER / 6 GAP, contract holds (83 cases).
  • cargo test --lib: 687 passed, 0 failed.
  • cargo test --test integration: 407 passed, 0 failed — verified green across three repeated full runs (previously flaky).
  • cargo fmt clean.

🤖 Generated with Claude Code

TimelordUK and others added 2 commits July 25, 2026 11:22
… in expr)

Three DuckDB-parity gaps, each now AGREEs and is locked by the --check gate
(corpus expectations dropped, SQL_PARITY.md entries flipped to FIXED). Board
goes 72->76 AGREE, 10->6 GAP.

P10 — HAVING NOT (...): added a `Not` arm to ArithmeticEvaluator::evaluate that
negates via the existing to_bool helper, with SQL three-valued logic on the NULL
edge (NOT NULL -> NULL). Was erroring "Unsupported expression type ... Not".

P6 — INTERSECT / EXCEPT: filled the two return-Err stubs in the set-op loop.
Both DISTINCT-by-default, filtering the materialized left table against the
right using the same Debug row-key apply_distinct uses for UNION, deduping
inline. The `except` corpus case threshold moved 2000 -> 3000 so it yields a
real {Oceania} difference instead of a trivially-empty result.

P12 — WITH in expression position: parse_subquery already dispatched a leading
WITH to the CTE parser; widened the subquery-detection guards from Token::Select
to Token::Select | Token::With in primary.rs (scalar + tuple IN) and
comparison.rs (IN / NOT IN). Retires previously-unreachable CTEHoister arms.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…tform

The test sandboxed the history dir by redirecting HOME/APPDATA, but
dirs::data_dir() on Windows resolves via the Win32 known-folder API and ignores
those env vars, so the test silently read the developer's real history and
failed. Env-var redirection is also process-global, so #[serial] (which only
serializes serial-tagged tests) couldn't stop a concurrent test from writing
into the sandbox and tripping the history-protection guard — hence pass-alone /
fail-in-suite flakiness.

Decouple the test from global state: add CommandHistory::with_history_file(path)
and have new() delegate to it. The test now builds against an explicit tempdir
file — no env var, no #[serial], no cross-test races. Verified green across
repeated full `cargo test --test integration` runs.

Also add a SQL_CLI_DATA_DIR override to AppPaths (honored directly, so it works
on every platform unlike the dirs-based env vars) — a legitimate way to
relocate/sandbox app data.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@TimelordUK
TimelordUK merged commit 29af185 into main Jul 25, 2026
8 checks 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