Skip to content

fix(spec): reject reserved system field names at create and alter time - #641

Open
jackylee-ch wants to merge 1 commit into
apache:mainfrom
jackylee-ch:fix/reserved-field-names-at-create
Open

fix(spec): reject reserved system field names at create and alter time#641
jackylee-ch wants to merge 1 commit into
apache:mainfrom
jackylee-ch:fix/reserved-field-names-at-create

Conversation

@jackylee-ch

Copy link
Copy Markdown
Contributor

TableSchema::validate_no_reserved_fields already rejects the five Java
SpecialFields.SYSTEM_FIELD_NAMES (_SEQUENCE_NUMBER, _VALUE_KIND, _LEVEL,
rowkind, _ROW_ID) and the _KEY_ prefix — but it is only reachable from
validate_resolved_structure, which runs when loading an externally-supplied
schema. Neither Schema::new nor TableSchema::apply_changes checked names, so
CREATE TABLE with a column named _ROW_ID was accepted and persisted through
every catalog path (including DataFusion DDL), and that column was then silently
shadowed by the system value on read.

Fix: split the name half into a free
validate_no_reserved_field_names(&[DataField]) and call it from both schema
paths plus the existing resolved-structure check. The field-id half is unchanged.

pk_hybrid_table_with_reserved_column deliberately builds a schema carrying
_ROW_ID to exercise the read-side guard, so it now deserializes that schema from
JSON instead of going through Schema::builder — which is precisely the case the
read guard exists for: metadata written by another engine.

`TableSchema::validate_no_reserved_fields` already rejects the five Java
`SpecialFields.SYSTEM_FIELD_NAMES` and the `_KEY_` prefix, but it is only
reachable from `validate_resolved_structure`, which runs when loading an
externally-supplied schema. Neither `Schema::new` nor `TableSchema::apply_changes`
checked names, so `CREATE TABLE` with a column named `_ROW_ID`, `rowkind`, or
`_KEY_id` was accepted and persisted through every catalog path, and the column
was then silently shadowed by the system value on read.

Split the name half into a free `validate_no_reserved_field_names(&[DataField])`
and call it from both schema paths as well as the existing resolved-structure
check. The field-id half is unchanged.

`pk_hybrid_table_with_reserved_column` deliberately builds a schema carrying
`_ROW_ID` to exercise the read-side guard, so it now deserializes that schema
from JSON instead of going through `Schema::builder`, which is what the guard is
for: metadata written by another engine.
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