Skip to content

[Feature](lance) Support nested Arrow Null types - #67921

Merged
yiguolei merged 5 commits into
apache:branch-4.1from
Gabriel39:dev/lance-nested-null-branch-4.1
Sep 15, 2026
Merged

yiguolei merged 5 commits into
apache:branch-4.1from
Gabriel39:dev/lance-nested-null-branch-4.1

Conversation

@Gabriel39

@Gabriel39 Gabriel39 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Follow-up to #67325; partially addresses #66496.

Lance columns containing Arrow Null inside lists, structs, or map values are currently reported as unsupported. This change maps nullable Null leaves recursively, including deeper list/map/struct combinations, materializes them without accessing nonexistent Arrow validity/value buffers, and preserves their logical NULL_TYPE through nested schema RPC serialization.

Array offsets, parent nullability, empty collections, and sliced inputs remain intact. Unknown extensions and non-nullable Null leaves are rejected before materialization.

Generic file() scans preserve the delegate’s reader compatibility requirements and Local schema-backend affinity during rolling upgrades.

Search TVFs retain reader compatibility requirements for deferred columns across TopN lazy materialization. Both read phases are checked without adding deferred fields back to the first-phase tuple.

Tests

  • Lazy search mixed-version translation and Lance scan tests: 19 passed in an isolated runner using cached dependencies, including both search TVFs, aliased deferred fields, and ordinary projections. Both new rejection tests failed before the fix.
  • Generic-file upgrade scheduling and external TVF tests: 13 passed in an isolated runner using cached dependencies. Both new safety tests failed before the fix.
  • FE type-conversion tests: 12 passed in an isolated runner using existing dependencies; the new nested mapping test failed before the change.
  • BE nested Null tests: 10 passed in an isolated harness using the changed routines and compatible cached dependencies. The original schema conversion, RPC type preservation, and nested read failures were reproduced.
  • All affected C++ translation units passed syntax checks against the current source headers and generated schemas.
  • FE mvn checkstyle:check, clang-format 16 checks, and git diff --check passed.
  • The canonical fixture rebuild generates and validates the nested-null dataset. Its full check passes against the committed fixture; a temporary rebuild passes with --repin (one existing HNSW discriminator changes on retraining), and the check rejects a missing nested-null dataset.
  • Added S3 TVF regression coverage and a reproducible seven-column Lance fixture, verified by PyLance round-trip reading.

Full FE Maven tests are blocked locally by a Thrift compiler/runtime version mismatch (installed compiler 0.16 versus branch dependency 0.24). The complete BE suite and S3 regression have not been run locally and require CI.

Release note

Support Arrow Null elements and fields nested in Lance arrays, structs, and map values.

@Gabriel39
Gabriel39 requested a review from yiguolei as a code owner September 14, 2026 02:19
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Selected model is at capacity. Please try a different model.
Workflow run: https://github.com/apache/doris/actions/runs/34798886484

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

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.

Requesting changes for three issues: FE schema discovery rejects deeper valid Null-bearing composites; non-nullable Null children can reach the UInt8/Boolean physical SerDe and crash BE materialization; and the canonical Lance fixture rebuild removes the new nested-null dataset.

Critical checkpoints: logical NULL protobuf round-tripping is sound; valid nullable NA slices, empty/null parents, destination-tail appends, scanner batching, and row-id materialization are aligned; recursive smooth-upgrade fencing covers catalog and TVF projections; no performance or observability regression was substantiated. Test gaps are the deeper FE shapes and non-nullable Null children, while fixture generation is not integrated into the authoritative staged rebuild. No additional user focus was provided.

This was a two-round converged static review. Per the runner contract, I did not build, run tests, or edit source files, so test claims were inspected but not independently executed.

Comment thread be/src/format_v2/lance/lance_reader_helper.cpp
Comment thread docker/thirdparties/docker-compose/iceberg/scripts/lance_build_nested_null.py Outdated
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

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.

Automated static review for 027201d

Approval opinion: no new actionable findings at this head. The three previously reported issues are statically verified fixed and duplicate-fenced.

Critical checkpoints:

  • Schema and RPC identity: nullable logical Null is preserved recursively through FE types, Thrift/protobuf, and BE reconstruction; non-nullable Null leaves are rejected; unrelated unsupported descendants still propagate as unsupported.
  • Materialization and lifecycle: Arrow NA slices append the exact logical range, nested ARRAY/MAP/STRUCT child alignment and null parents remain consistent, and no cleanup, I/O, or ownership path changed.
  • Compatibility and dispatch: catalog and TVF projections fence smooth-upgrade source BEs for Null-bearing roots; the canonical fixture builder checks and publishes the dataset at the regression URI.
  • Performance and observability: the production changes are schema-time checks plus linear default insertion, with no new I/O, cache, predicate, or observability regression identified.

Residual non-blocking test note: the SQL golden does not assert every nested descendant value end to end through lance-c, although the persisted fixture self-check and focused BE tests cover those values at adjacent layers.

No additional user review focus was provided. This was a two-round converged static review. Per the runner contract, I did not build, run tests, or edit source files; author-reported focused test and fixture-rebuild results were inspected but not independently executed.

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@Gabriel39

Copy link
Copy Markdown
Contributor Author

Fixed the new external regression failure in 68cf7d8. The nested_null_projection golden expected uppercase NULL array elements, but complex-value serialization returns lowercase null. Updated the expectation and verified all three projection rows against the recorded CI output. Schema checks and nested_null_values completed before this mismatch. No production code changed.

@github-actions github-actions Bot left a comment

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.

Requesting changes for two distinct rolling-upgrade safety gaps in generic file() Lance scans: the S3-compatible delegate loses its projected-column current-reader capability, while the Local delegate loses its schema-backend execution affinity. Either route can send a newly supported nested Null-bearing root to a smooth-upgrade source BE whose old nullable SerDe can dereference a failed Arrow Boolean cast. The three earlier inline issues are fixed at this head and remain duplicate-fenced.

Critical checkpoints: recursive FE/BE schema identity, non-nullable Null rejection, Arrow NA range/materialization alignment, row-ID phase-two state, direct catalog/S3/search compatibility fencing, direct Local pinning, fixture staging/promotion, committed binary identity, MinIO publication, SQL oracles, lifecycle, performance, and observability were all inspected. No additional defect was substantiated outside the two generic-wrapper contracts.

This was a three-round converged static review. Per the review contract, I did not build, run tests, regenerate fixtures, or edit source files; author/CI test claims were inspected but not independently executed.

Comment thread be/src/core/data_type/data_type.h
@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (22/22) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.45% (31443/42234)
Line Coverage 58.69% (350384/597055)
Region Coverage 55.41% (292411/527728)
Branch Coverage 56.22% (131849/234505)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 25.00% (4/16) 🎉
Increment coverage report
Complete coverage report

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

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.

One blocking rolling-upgrade issue remains: TopN lazy materialization for vector_search() and full_text_search() can prune a projected nested-Null root before the current-reader compatibility check, then route phase-two take_rows back to the old source BE. The inline finding details the resulting crash path.

Critical checkpoints:

  • Schema and materialization: recursive LIST/MAP/STRUCT mapping, nullable versus rejected Null leaves, sliced parent offsets/null maps, and Arrow NA ranges were traced; no additional defect was found.
  • RPC and type identity: nested NULL_TYPE protobuf nodes preserve preorder shape and nullability without reclassifying BOOLEAN or DataTypeNothing; existing old consumers understand the stable enum.
  • Scheduling and lifecycle: direct S3, generic file(), and Local schema-backend affinity are otherwise consistent, and existing resolved threads were duplicate-fenced.
  • External compatibility and tests: the pinned external-writer fixture, staged rebuild/promotion, MinIO publication path, and C++/FE/regression coverage are aligned; the missing mixed-version lazy-search case is the blocking gap.
  • Performance and observability: no distinct regression was substantiated in the changed paths.

No additional user review focus was provided. This review completed after two convergence rounds. It was static only: per the task contract I did not run builds or tests, so author/CI execution claims were inspected but not independently verified.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (16/16) 🎉
Increment coverage report
Complete coverage report

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

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.

Requesting changes for one distinct fixture-integrity issue: the standalone nested-Null generator bypasses the pinned-writer and assertions-enabled safeguards required by the canonical fixture workflow, so it can self-certify a candidate binary fixture that other supported Lance readers cannot open or omit the schema/value equality check under optimized Python.

Critical checkpoints:

  • Schema and materialization: recursive LIST/MAP/STRUCT logical-NULL identity, required-Null rejection, Arrow NA range/default insertion, nested offsets/null maps, sliced parents, and row-ID materialization are consistent.
  • Scheduling and compatibility: direct and generic S3/Local TVFs preserve current-reader metadata or backend affinity, while lazy vector/full-text phase two carries deferred source names into the phase-one backend fence.
  • Fixture lifecycle and tests: the canonical pinned staged rebuild, pre/post-promotion validation, complete-prefix upload, committed binary layout, and BE/FE/SQL coverage are aligned; only the helper's separate CLI lacks those guards.
  • Lifecycle, performance, and observability: no additional correctness, cleanup, I/O, distribution, performance, or observability regression was substantiated.

All six earlier inline issues are statically verified fixed at this exact head and were treated as hard duplicate fences. No additional user review focus was provided. This was a two-round converged static review. Per the review contract, I did not build, run tests, regenerate fixtures, or edit source files; author/CI execution claims were inspected but not independently verified.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 93.10% (27/29) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 100.00% (22/22) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 59.88% (26004/43428)
Line Coverage 44.60% (268585/602195)
Region Coverage 40.47% (213203/526829)
Branch Coverage 41.93% (98531/234968)

@yiguolei
yiguolei merged commit be96287 into apache:branch-4.1 Sep 15, 2026
42 of 46 checks passed
@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (22/22) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.42% (31444/42253)
Line Coverage 58.68% (350581/597405)
Region Coverage 55.49% (293017/528027)
Branch Coverage 56.25% (132020/234708)

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Sep 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 63.89% (23/36) 🎉
Increment coverage report
Complete coverage report

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

Labels

approved Indicates a PR has been approved by one committer.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants