Skip to content

[FEA] Per-row schema-mismatch diagnostic for read_json_with_diagnostics #4645

Description

@wjxiz1992

Background

spark-rapids-jni's from_json_to_structs (see #4536) replicates Spark's depth-1 parent-NULL policy by reading the side-channel json_reader_diagnostics.top_level_columns_with_schema_mismatch returned by read_json_with_diagnostics and applying ALL_NULL to any top-level column flagged there.

Problem

The diagnostic is column-level, not row-level. cuDF reports that column X has SOME row(s) with a schema mismatch, but not which rows. Our workaround nulls the entire column, which over-nulls valid rows in a mixed-row batch:

Input rows for schema (data: struct<c1: int, c2: array<struct<c3, c4>>>):

{"data": {"c2": [{"c3": 19, "c4": "x"}], "c1": 1}}  // valid
{"data": {"c2": [19], "c1": 2}}                       // c2 is int, schema says struct

Expected (Spark): row 1 = Row(c1=1, c2=Array(Row(19,"x"))), row 2 = null
Actual (cuDF + current spark-rapids-jni workaround): both rows null.

Proposal

Add a row-level field to json_reader_diagnostics, e.g.

struct json_reader_diagnostics {
  std::vector<std::string> top_level_columns_with_schema_mismatch;        // existing
  std::unordered_map<std::string, std::vector<cudf::size_type>>
    top_level_columns_with_schema_mismatch_rows;                          // new
};

mapping column name → sorted vector of mismatched row indices for that column.

With this, the spark-rapids-jni loop can null only the affected rows (e.g. via cudf::detail::valid_if on a boolean column-of-rows mask), matching Spark's per-row depth-1 behavior exactly.

Notes

  • Column-level diagnostic stays in place for backward compatibility.
  • Row indices are already maintained inside the JSON reader during the schema-category check; surfacing them in the diagnostic struct should be a localized change.

Affected

  • spark-rapids-jni#4536 — Spark parity workaround that this would close out.
  • Any downstream consumer that needs Spark/Jackson-style isRoot=false nested-error-to-NULL propagation.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions