Repository navigation
[Kernel] Fix schema validation for new nullable structs with non-nullable fields - #6434
Open
c-kaustubh wants to merge 3 commits into
Open
c-kaustubh wants to merge 3 commits into
c-kaustubh wants to merge 3 commits into
Conversation
…able fields Schema evolution validation incorrectly rejects adding a new nullable struct that contains non-nullable inner fields. This happens because struct children have their own unique column mapping IDs (unlike array/map synthetic children which share the parent's field ID), so the validator sees the inner non-nullable field and rejects it even though the entire containing struct is new. Fix: In validateUpdatedSchemaCompatibility, build a descendantFieldIds set by walking each added field's DataType tree. Fields in this set skip the nullability check since they are descendants of entirely new containers. The fieldId <= maxFieldId constraint is still enforced for all fields. Closes delta-io#6428 Signed-off-by: Kaustubh Chaturvedi <kchaturvedi@confluent.io>
This branch has not been deployed
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.
Which Delta project/connector is this regarding?
Description
Schema evolution validation incorrectly rejects adding a new nullable struct
that contains non-nullable inner fields, throwing:
KernelException: "Cannot add non-nullable field <fieldname>"This happens because
computeSchemaChangesByIduses post-order traversal viaSchemaIterable, and struct children are recorded independently inaddedFields(each with their own column mapping ID via
getNearestStructFieldAncestor()returning self for
StructSchemaZipper). The validator then sees the innernon-nullable field and rejects it, even though the entire containing struct is
new and nullable -- no existing data could violate the constraint.
This already works correctly for arrays and maps because their synthetic children
(key/value/element) share the parent's field ID via
getNearestStructFieldAncestor()walking up to the parent struct field. Only struct children are affected.
Example that fails before this fix:
Fix: In
validateUpdatedSchemaCompatibility, before checking nullability ofadded fields, build a
descendantFieldIdsset by walking each added field'sDataType tree via a new
collectDescendantFieldIdsmethod. Fields whose ID is inthis set have their nullability check skipped -- they are descendants of entirely
new containers and their nullability only constrains future writes. The
fieldId <= maxFieldIdconstraint is still enforced unconditionally for all added fields.Only
SchemaUtils.javais modified (no changes tocomputeSchemaChangesById,SchemaIterable,SchemaChanges, orTransactionMetadataFactory).Closes #6428
How was this patch tested?
9 new unit tests in
SchemaUtilsSuite.scalacovering:fieldId constraint still enforced for descendants
3 new integration tests in
DeltaTableSchemaEvolutionSuite.scalacovering:1 existing integration test updated: "Adding non-nullable field fails" was
asserting the buggy behavior (rejecting a valid schema evolution). Updated to
assert success and verify the non-nullable property is preserved.
All tests pass across SchemaUtilsSuite (68) and DeltaTableSchemaEvolution* (98). No regressions.
Does this PR introduce any user-facing changes?
Yes. Schema evolution via Delta Kernel now correctly accepts adding a new nullable
struct (or array/map) that contains non-nullable inner fields. Previously this was
rejected with
"Cannot add non-nullable field <name>".This aligns with the behavior already supported for arrays and maps (where inner
struct fields with non-nullable constraints are accepted when the container is new),
and is consistent with Delta Spark's behavior.
No existing valid rejections are affected:
allowNewRequiredFields=truebypasses thecheck before the skipSet is consulted)