[fix](variant) Recognize nullable array elements as NestedGroup types - #66196
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
run buildall |
TPC-H: Total hot run time: 29928 ms |
TPC-DS: Total hot run time: 176430 ms |
ClickBench: Total hot run time: 24.89 s |
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
|
/review |
|
PR approved by at least one committer and no changes requested. |
|
PR approved by anyone and no changes requested. |
There was a problem hiding this comment.
Request changes: the local nullable-element classification is correct, but the newly activated conflict path can silently lose regular-array values, and the added test does not exercise the production policy behavior.
Critical checkpoint conclusions:
- Goal and correctness:
Array<Nullable<Variant>>is now recognized while scalarVariantandNullable<Variant>retain their prior classifications. However, a regular mixedArray<Jsonb>merged beforeNESTED_TYPEis later defaulted during finalization; reversing the order preserves it. The PR therefore does not yet safely accomplish its merge/compaction goal. - Scope and design: the two-file, three-line production change is small and focused. The defect is in the interaction with the existing NG conflict resolver/finalizer, not in the nullable unwrapping itself.
- Concurrency and lifecycle: the helper is stateless and adds no locks, atomics, threads, static-initialization dependency, ownership cycle, or release-order concern.
- Configuration, conditions, and error handling: no new config is added. Under the existing ERROR policy, the same classifier also rejects a compatible non-scalar regular array before the intended array-cast path. No new ignored
Statuswas found. - Compatibility and persistence: there is no serialized-layout, storage-format, FE/BE protocol, EditLog, transaction-metadata, or rolling-upgrade field change.
- Parallel paths and data writes: hierarchical reconstruction and the persistent materialized writer append into an existing
ColumnVariant, making the order-dependent value loss production-reachable. The streaming writer uses a fresh chunk per append and does not independently create this cross-chunk ordering. No version/delete-bitmap protocol changes are involved. - Tests: the new unit test proves only the private predicate. No unit or regression test covers populated NG/scalar merges in both orders or
variant_nested_group_discard_scalar_on_conflict=false; the regular-array ordering defect is likewise uncovered. The author reports the focused test and 91ColumnVariantTest.*cases passing, and current CI is green. Tests were not rerun here because the review prompt prohibits builds and this worktree lacks.worktree_initializedandthirdparty/installed. - Memory, COW, performance, and observability: no ownership or tracked-allocation behavior changes. The extra type-depth walk is allocation-free O(depth). Existing exceptions include both types, but the default-policy failure silently substitutes defaults, which is the blocking observability/data-correctness concern.
- User focus: no additional focus was provided; the entire PR was reviewed.
Review completion: the authoritative two-file diff was fully reviewed, all candidates were resolved, and two convergence rounds ended with every Round 2 full/risk reviewer returning NO_NEW_VALUABLE_FINDINGS against this exact two-comment set.
| // which indicates NG-originated array<object> data. | ||
| bool is_nested_group_type(const DataTypePtr& type) { | ||
| auto base = get_base_type_of_array(type); | ||
| if (get_number_of_dimensions(*type) > 0) { |
There was a problem hiding this comment.
[P1] Preserve regular-array rows when the NG type becomes the LCT. If the destination already contains a mixed Array<Jsonb> and the source is NESTED_TYPE, this newly true result makes resolve_ng_type_conflict() select the NG type and leave the old array part in place; Subcolumn::finalize() then sees an NG/non-NG mismatch and inserts defaults for every old row. Reversing the inputs instead reaches the same-dimensional array cast at lines 392-424 and preserves the values, so hierarchical/materialized merges become order-dependent. Distinguish genuine scalar conflicts from regular arrays during resolution/finalization, and cover both input orders.
| array_subcolumn.finalize(); | ||
| } | ||
|
|
||
| TEST(ColumnVariantNestedGroupTypeTest, nullable_array_element_is_recognized) { |
There was a problem hiding this comment.
[P1] Please exercise the conflict-policy behavior, not only the helper. The reported regression is that this predicate used to bypass Subcolumn::insert_range_from/finalize, but this test would still pass if the merge kept the wrong LCT, discarded the NestedGroup row, or ignored the ERROR policy. Add a focused merge test with an actual NESTED_TYPE value and a scalar in both source/destination orders, asserting that the default policy preserves the NestedGroup value and defaults only the scalar; also cover variant_nested_group_discard_scalar_on_conflict=false throwing in both orders.
…#66196) Related PR: #63088 Problem Summary: Array elements are nullable after #63088. `get_base_type_of_array()` therefore returns `Nullable<Variant>` for the NestedGroup physical type, but `is_nested_group_type()` directly casts that wrapper to `DataTypeVariant`. The false negative bypasses the NestedGroup-specific type-conflict policy during Variant merge/compaction. This PR unwraps the nullable base type only when the input has an Array dimension. It recognizes `Array<Nullable<Variant>>` as NestedGroup while preserving the existing classifications of scalar `Variant` and `Nullable<Variant>`.
What problem does this PR solve?
Issue Number: None
Related PR: #63088
Problem Summary:
Array elements are nullable after #63088.
get_base_type_of_array()therefore returnsNullable<Variant>for the NestedGroup physical type, butis_nested_group_type()directly casts that wrapper toDataTypeVariant. The false negative bypasses the NestedGroup-specific type-conflict policy during Variant merge/compaction.This PR unwraps the nullable base type only when the input has an Array dimension. It recognizes
Array<Nullable<Variant>>as NestedGroup while preserving the existing classifications of scalarVariantandNullable<Variant>.Release note
None
Check List (For Author)
Test
GLIBC_COMPATIBILITY=OFF ./run-be-ut.sh --run --filter=ColumnVariantNestedGroupTypeTest.nullable_array_element_is_recognizedGLIBC_COMPATIBILITY=OFF ./run-be-ut.sh --run --filter='ColumnVariantTest.*'(91 tests passed)Behavior changed:
Nullable<Variant>are now recognized as NestedGroup and use its intended conflict-resolution policy.Does this need documentation?
Check List (For Reviewer who merge this PR)