Skip to content

Fix REE JSON decoder nullability (#10478) - #10485

Open
Vam-si-krish wants to merge 1 commit into
apache:mainfrom
Vam-si-krish:fix/json-ree-nonnullable-values
Open

Fix REE JSON decoder nullability (#10478)#10485
Vam-si-krish wants to merge 1 commit into
apache:mainfrom
Vam-si-krish:fix/json-ree-nonnullable-values

Conversation

@Vam-si-krish

Copy link
Copy Markdown

AI-generated contribution disclosure: I used OpenAI Codex to help prepare the implementation and regression test. I reviewed and understand the changes, verified them against the issue, and ran the project checks below. The generated portions are the decoder nullability guard, constructor wiring, and regression test.

Summary

  • Decode run-end encoded values according to the values field's own nullability instead of inheriting nullability from the parent field.
  • Reject explicit nulls and missing object fields when the REE values field is non-nullable, while still allowing a nullable REE parent.
  • Add regression coverage for both invalid inputs.

This intentionally tightens schema enforcement as described in the issue.

Closes #10478

Testing

  • cargo test -p arrow-json test_read_run_end_encoded_nulls_in_non_nullable_values
  • cargo clippy -p arrow-json --all-targets -- -D warnings
  • cargo fmt --all

@github-actions github-actions Bot added the arrow Changes to the arrow crate label Jul 30, 2026
DataType::BinaryView => Ok(Box::new(BinaryViewDecoder::default())),
DataType::Map(_, _) => Ok(Box::new(MapArrayDecoder::new(ctx, data_type, is_nullable)?)),
DataType::RunEndEncoded(ref r, _) => match r.data_type() {
DataType::Int16 => Ok(Box::new(RunEndEncodedArrayDecoder::<Int16Type>::new(ctx, data_type, is_nullable)?)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this ignoring of the passed in is_nullable seems significant; is it safe to do this? 🤔

cant help but feel this could lead to another edge case

@mzabaluev mzabaluev Jul 30, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes; the declared nullability of the REE-typed field has no bearing on whether the values array is allowed to carry nulls. That's determined by the schema of the "values" field.

@mzabaluev

Copy link
Copy Markdown
Contributor

Here's the full test case from my unsubmitted branch (so you may want to adjust the error strings here or in your code). Disclaimier: written by Claude.

    #[test]
    fn test_read_run_end_encoded_nulls_in_non_nullable_values() {
        // A `RunArray` has no validity buffer of its own, so unlike a struct child
        // there is no parent-level mask that could make these nulls representable.
        // Declaring the enclosing field nullable does not change that.
        let ree_type = DataType::RunEndEncoded(
            Arc::new(Field::new("run_ends", DataType::Int32, false)),
            Arc::new(Field::new("values", DataType::Utf8, false)),
        );

        for outer_nullable in [false, true] {
            let schema = Arc::new(Schema::new(vec![Field::new(
                "a",
                ree_type.clone(),
                outer_nullable,
            )]));

            // An explicit null, and a missing field, are both rejected.
            for buf in [
                r#"
                {"a": "x"}
                {"a": null}
                {"a": "y"}
                "#,
                r#"
                {"a": "x"}
                {}
                {"a": "y"}
                "#,
            ] {
                let mut decoder = ReaderBuilder::new(schema.clone()).build_decoder().unwrap();
                let err = decoder
                    .decode(buf.as_bytes())
                    .and_then(|_| decoder.flush())
                    .expect_err("nulls in non-nullable REE values field");
                assert!(
                    err.to_string()
                        .contains("Encountered nulls in non-nullable values of RunEndEncoded"),
                    "unexpected error: {err}"
                );
            }
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrow Changes to the arrow crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JSON decoder for RunEndEncoded accepts nulls even though the values field is non-nullable

3 participants