fix(sql): raise 42703 for unknown column references instead of folding to NULL - #299
Closed
EnRaiha wants to merge 1 commit into
Closed
fix(sql): raise 42703 for unknown column references instead of folding to NULL#299EnRaiha wants to merge 1 commit into
EnRaiha wants to merge 1 commit into
Conversation
…g to NULL A column reference that names nothing in scope planned as a field lookup and evaluated to NULL on every row. On collections whose row shape is known at plan time that is silent misbehavior: projection returned NULL-filled rows, WHERE matched nothing (IS NULL matched everything), ORDER BY no-oped, and UPDATE/DELETE predicates touched zero rows — no error anywhere. The function-existence gate already raised for undefined functions; column resolution had no counterpart. Closed-schema collections now validate every reference at plan time and raise SQLSTATE 42703 (undefined_column): - document_strict, kv, columnar, timeseries and spatial are closed by construction. - document (schemaless) is closed when the user declared columns on it; a collection carrying only the auto-injected id stays open, so dynamic fields that appear only in the data keep resolving (the NULL fold remains the documented behavior there). The gate covers the single-table SELECT path (projection, WHERE, GROUP BY, HAVING, ORDER BY) and the UPDATE/DELETE target path (SET targets and predicates). Qualified references validate against the collection they name. Schemaless writes stay open: INSERT column lists may still carry undeclared dynamic fields. The error is typed end to end: SqlError::UnknownColumn maps to a new crate::Error::UndefinedColumn, to the public NodeDbError code 1206 with msgpack tag 79, and to SQLSTATE 42703 on pgwire and the native protocol — mirroring the undefined_function path added for the same folding class. Out of scope (pre-existing folds, tracked separately): JOIN/derived/lateral paths, aggregate ORDER BY, UPDATE ... FROM predicates, and INSERT ... SELECT. Fixes NodeDB-Lab#292
EnRaiha
force-pushed
the
fix/issue292-unknown-column-42703
branch
from
September 6, 2026 22:48
14701a0 to
d17c3c4
Compare
Member
|
Superseded by #304, merged as #304 threads a The two differ on one point, worth recording for anyone reading back. This PR closes a schemaless collection once it declares columns. #304 keeps #304 was written independently and did not draw on this PR. |
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.
fix(sql): raise 42703 for unknown column references instead of folding to NULL
Fixes #292
Problem
A column reference that names nothing in scope planned as a field lookup and evaluated to NULL on every row. On collections whose row shape is known at plan time that is silent misbehavior: projection returned NULL-filled rows, WHERE matched nothing (IS NULL matched everything), ORDER BY no-oped, and UPDATE/DELETE predicates touched zero rows — no error anywhere. This is the same folding class as the undefined-function and division-by-zero paths that now raise (see the #226 fix), on the column-resolution side, which still folded.
Fix
Closed-schema collections validate every column reference at plan time and raise SQLSTATE 42703 (undefined_column):
document_strict,kv,columnar,timeseriesandspatialare closed by construction.document(schemaless) is closed when the collection declares columns. The open/closed line is the declared column count, not a name: the catalog adapter always prepends the synthesized primary-key column (the declared PK name or the built-inid), so a one-column list means nothing was declared and dynamic fields keep resolving — the NULL fold stays the documented behavior there. Declared fields close the set even though schemaless ColumnInfo carriesraw_type: None.The gate covers the single-table SELECT path (projection, WHERE, GROUP BY, HAVING, ORDER BY) and the UPDATE/DELETE target path (SET targets and predicates). Qualified references validate against the collection they name.
The error is typed end to end:
SqlError::UnknownColumnmaps to a newcrate::Error::UndefinedColumn, to the publicNodeDbErrorcode 1206 (msgpack tag 79), and to SQLSTATE 42703 on pgwire and the native protocol — mirroring theundefined_functionpath added for the same folding class.Out of scope
Pre-existing folds, tracked separately: JOIN/lateral/derived paths, aggregate ORDER BY, UPDATE ... FROM predicates, INSERT ... SELECT.
Verified
SELECT ghostWHERE ghost = 1/IS NULLORDER BY ghostUPDATE/DELETE ... WHERE ghostSELECT dyn_fieldcargo nextest run -p nodedb-sql --lib— 875 passed (11 validator tests: every clause, closed/open/renamed-PK, function-arg walk, GROUP BY alias, sort-key ordinals)cargo nextest run -p nodedb-types --lib— 688 passedundefined_column_42703): 4 passed — all six clause shapes on the default-declared engine; strict/kv/columnar; open fold incl. renamed-PK carve-outengine_surface_document_schemaless,sql_json_path_ops,ddl_numeric_width_schemaless,sql_typeguard_defaults— 49 passedcargo fmt --all -- --checkclean; clippy-D warningsclean on nodedb-sql, nodedb-types, nodedbHow to test