Fix/temp table qualified and join coercion - #21
Merged
Conversation
resolve_select_columns did a qualified-only lookup using the raw table alias and no fallback, so a bare qualified column in the projection (`SELECT f.region FROM #tmp f` or `... FROM data f`) failed with "Table 'f' may not support qualified column names" whenever the source was a single base or temp table — whose columns carry no qualified_name. WHERE and computed-expression clauses already resolve this via ExecutionContext::resolve_column_index (qualified, then unqualified fallback). Align the projection resolver: try the qualified name first (JOIN/CTE columns carry one), then fall back to an unqualified case-insensitive lookup before erroring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Equi-joins indexed keys in a HashMap<DataValue, _>, which keys on the
exact DataValue variant. String("220") and Integer(220) therefore never
collided, so a join between a string column (e.g. a value pulled from a
JSON blob via SUBSTR) and an integer column silently produced no matches
— even though WHERE a = b coerces and matches them. InternedString vs
String had the same problem.
Add canonical_join_key(), which folds keys to a canonical form before
hashing/comparing: numeric-looking strings become numbers, interned
strings collapse to plain strings, and whole floats collapse to integers
(so 220.0 matches 220). Apply it on both the build and probe sides of the
hash-join paths and in the nested-loop equality comparator so JOIN
equality is consistent with WHERE equality.
Adds unit tests for canonical_join_key and end-to-end regression tests
(also covering the aliased-projection fix) via the real SELECT INTO path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tring) The first pass coerced every numeric-looking string, so two string keys like "007" and "7" also matched. Make coercion conditional: only when the two join columns hold different value *kinds* (a string column vs a numeric column) do string keys get parsed to numbers. Two string columns join on exact text, so casting both sides with TO_STRING(...) is a deliberate opt-out of numeric matching. The kind is sampled from each column's first non-null value rather than its declared data_type, because a materialized temp table does not carry reliable column types (a column of integers can still be typed String) — relying on data_type regressed the real string-vs-integer case to zero matches. Whole floats still always fold to integers so int/float numeric columns join. The nested-loop path defers to value_comparisons so its equality already matches WHERE semantics pairwise. Adds a regression test that two string keys are not coerced. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
No description provided.