Repository navigation
GH-47417: [C++] Fix JSON parser losing nulls in a null-typed list - #51108
advitrocks9 wants to merge 5 commits into
Conversation
|
|
There was a problem hiding this comment.
Pull request overview
Fixes a long-standing JSON parsing bug in the C++ BlockParser where null elements could be silently dropped (or trigger DCHECKs in debug) when appending nulls to a null-typed list, by ensuring the inline null-count state in BuilderPtr is updated in-place.
Changes:
- Change
RawBuilderSet::AppendNullto take aBuilderPtr*so increments to the inline null-count forKind::kNullpersist to the caller. - Update all
AppendNullcall sites to pass builder pointers accordingly (including nested object-field null propagation). - Add a regression test covering nulls inside lists (null-only and promoted-from-null cases).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cpp/src/arrow/json/parser.cc | Fixes null appends by mutating the BuilderPtr in-place, preventing lost null counts in null-typed list builders. |
| cpp/src/arrow/json/parser_test.cc | Adds a regression test to ensure nulls inside lists are preserved and don’t break list offsets. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
There was a problem hiding this comment.
🟢 Approval recommended
The fix is narrowly scoped, updates all relevant call sites, and adds targeted regression tests exercising both the all-null and promotion scenarios described.
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
|
@pitrou mind taking a look? the current red CI is from an existing known repowide issue |
# Conflicts: # cpp/src/arrow/json/parser.cc # cpp/src/arrow/json/parser_test.cc
|
|
|
Merged main to fix the conflict with the simdjson rewrite. The fix itself is unchanged. |
|
@Reranko05 @taepper Since you both recently worked on the JSON reader, would you like to review this? |
|
@advitrocks9 Thank you for the contribution! Would you mind filling out the AI disclosure section of the PR template? |
Reranko05
left a comment
There was a problem hiding this comment.
Does it make sense to also test a null struct with a null-typed child, like {"a": [{"b": null}, null]}? Existing tests don't cover the kNull case inside the recursive kObject branch of AppendNull.
|
|
|
@taepper @Reranko05 thanks for the review! I've gone ahead and addressed your concerns, and updated the PR body (: |
| @@ -966,7 +972,7 @@ class ParseImpl : public BlockParser { | |||
| if (ARROW_PREDICT_FALSE(!field_builder.nullable)) { | |||
| return ParseError("a required field was absent"); | |||
| } | |||
There was a problem hiding this comment.
We could use
if (ARROW_PREDICT_FALSE(!Cast<Kind::kObject>(parent)->field_builder(i).nullable)) {
return ParseError("a required field was absent");
}
to avoid the variable field_builder
| ARROW_ASSIGN_OR_RAISE(builder_, | ||
| builder_set_.AppendNull(builder_stack_.back(), field_index_)); | ||
| return Status::OK(); |

Rationale for this change
{"a": [null, 1]}silently parses to[[1]]in release builds, and aborts in debug.This was introduced in
b7054c21aab(0.14.0).What changes are included in this PR?
AppendNulllooks up its child from the parent and returns the updatedBuilderPtr, instead of taking a copy from the caller.Null()writes it back tobuilder_, sobuilder_no longer drifts from the parent's copy.Are these changes tested?
Two new tests,
BlockParser.NullsInList(inferred schema) andBlockParserWithSchema.NullsInList(explicit schema), parse lists of nulls, including{"a": [{"b": null}, null]}. Both fail in debug without the fix.Are there any user-facing changes?
{"a": [null, 1]}now parses to[[null, 1]].This PR contains a "Critical Fix". Well-formed JSON silently loses list elements.
Was AI used for this PR?
In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.
PR code and description written by:
Reviewed before submission by: