Repository navigation
docs(parity): P46-P48, found writing the countries examples - #79
Merged
Merged
Conversation
Three divergences, all found asking countries.csv ordinary questions rather than by widening the corpus. Two are silent wrong answers. P46 - a column-to-column comparison in WHERE returns zero rows. Not one operator or one type: `WHERE region = region` matches nothing. The AST is correct, so it is the WHERE evaluator, and the same comparison projected in the SELECT list is right. Same "zero rows reads as no data" disguise as P30. P47 - MIN/MAX compare by type variant before value. DataValue derives PartialOrd, so every Float outranks every Integer for MAX (and the reverse for MIN) whatever the numbers are: MAX(area) over countries.csv answers 34.2 instead of Russia's 17098242. compare_datavalues already does this correctly, which is why ORDER BY and the batched window path agree with DuckDB. Also recorded: SQL_CLI_BATCH_WINDOW=0 changes the answer, because the row-wise window path shares the bare comparison. P48 - a comparison with a NULL operand projects false instead of NULL. The P18/P19 three-valued rule at a site the 2026-08-22 fix did not reach. Found while building P46's anchor case: the control that was meant to AGREE came back DIFFER for an unrelated reason. Corpus grows by seven cases (six DIFFER, one AGREE anchor) across tiers 01, 02 and 10; the contract holds at 188 cases, 157 AGREE. Verified against the pinned DuckDB 1.5.5. Also updated: - P40's "what works today" understated itself. CROSS JOIN a slot table and take one SPLIT_PART per slot, and a bounded explode works today with the generator running once - it sidesteps both stacked defects rather than working around them. Recorded with the SQL and its two honest costs. - P45 gains the CROSS JOIN spelling, which fails with a different message. - NEXT in the fix-order table is now P46-P48; the previous NEXT is "then". - A fourth discovery lesson: writing examples is discovery. Examples are written to be interesting rather than exhaustive, which is how they wander outside the tested envelope. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01GfDkQm9s234uEDhdX6rvmf
The Russia query hand-typed its fourteen neighbour codes into a SPLIT list. Unpack borders for every country instead: CROSS JOIN a table of slot numbers onto the rows and pull the nth code out with SPLIT_PART, which turns 250 countries into 649 border pairs and needs no per-row generator call. Same trick reused for the languages column. Nine sections on top of that, staged through #border_pairs and #edges: - most neighbours (China 16, Russia 14) - the land borders that leave their own continent - doubly landlocked - falls out as exactly Liechtenstein and Uzbekistan - border symmetry: forward and reverse keys, LEFT JOIN, IS NULL. Finds the one hole in the data - Sri Lanka lists IND, India does not list LKA - haversine from latlng with RADIANS/SIN/COS/ACOS, no geo functions needed, plus CONVERT for miles. New Zealand 18764 km from London - widest and tightest land borders, deduped to one direction per pair - currency unions, language reach, island nations with the flag emoji - ROW_NUMBER/SUM OVER with a REPEAT bar chart Two workarounds carry their reason in a comment and cite the entry: the region comparison is done in the SELECT list because of P46, and the area aggregate is CAST to FLOAT because of P47. Runs clean end to end in ~2.7s; the examples harness passes. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01GfDkQm9s234uEDhdX6rvmf
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.
Nine new sections in
examples/countries.sql, and the three divergences that writing them turned up.The examples
The Russia query hand-typed its fourteen neighbour codes into a
SPLITlist. The generic form unpacksbordersfor every country:CROSS JOINa table of slot numbers onto the rows and pull the nth code out withSPLIT_PART. 250 countries become 649 border pairs, and the generator runs once rather than per row. Same trick reused forlanguages.On top of that, staged through
#border_pairsand#edges:LEFT JOIN … IS NULL. Finds the one hole in the data: Sri Lanka listsIND, India does not listLKAlatlngwithRADIANS/SIN/COS/ACOS— no geo functions needed — plusCONVERTfor miles. New Zealand 18,764 km from LondonflagemojiROW_NUMBER/SUM OVERwith aREPEATbar chartRuns clean end to end in ~2.7s; the examples harness passes.
The findings
Two of the three are silent wrong answers, and none came from widening the corpus — they came from asking a real dataset ordinary questions.
[P46] A column-to-column comparison in
WHEREreturns zero rows. Not one operator or one type:WHERE region = regionmatches nothing. The AST is correct, and the same comparison projected in theSELECTlist is right, so it is the WHERE evaluator. Same "zero rows reads as no data" disguise that made P30 dangerous — found here only because the answer was known in advance (Russia borders China, so the result cannot be empty).[P47]
MIN/MAXcompare by type variant before value.DataValuederivesPartialOrd, so everyFloatoutranks everyIntegerforMAX(and the reverse forMIN) whatever the numbers are.MAX(area)overcountries.csvanswers 34.2 rather than Russia's 17,098,242, from aGROUP BYthat looks entirely ordinary.compare_datavaluesalready has the correctInteger↔Floatarms, which is whyORDER BYand the batched window path agree with DuckDB. Also recorded:SQL_CLI_BATCH_WINDOW=0changes the answer, because the row-wise window path carries the same bare comparison — a documented speed opt-out switching a result from right to wrong.[P48] A comparison with a NULL operand projects
falseinstead of NULL. The P18/P19 three-valued rule at a site the 2026-08-22 fix did not reach. Found while building P46's anchor case — the control that was meant to AGREE came back DIFFER for an unrelated reason.Corpus
Seven new cases across tiers 01, 02 and 10 — six
DIFFERand oneAGREEanchor, the latter being the projected comparison that localises P46 to the WHERE evaluator rather than to comparison in general. Verified against the pinned DuckDB 1.5.5; the parity contract holds at 188 cases, 157 AGREE (was 181 / 156).Also updated
CROSS JOIN range(...)spelling, which fails with a different message than theJOINform and so reads as a different bug.The two workarounds in the examples file carry their reason in a comment and cite the entry, so they do not read as arbitrary style: the region comparison goes through the
SELECTlist because of P46, and the area aggregate isCASTtoFLOATbecause of P47.No engine code changed in this PR — findings and cases only.
🤖 Generated with Claude Code
https://claude.ai/code/session_01GfDkQm9s234uEDhdX6rvmf