yujun777 opened a new pull request, #66380: URL: https://github.com/apache/doris/pull/66380
## Problem After an outer join, `IS NULL` on a physical `NOT NULL` column (e.g. the right-side dimension column of a `LEFT JOIN`) crashes the BE: ``` [E-7412] Check failed: is_column_nullable(*dst) ``` Core stack: ``` doris::segment_v2::FileColumnIterator::read_by_rowids column_reader.cpp doris::segment_v2::SegmentIterator::_read_columns_by_rowids segment_iterator.cpp doris::segment_v2::SegmentIterator::_next_batch_internal segment_iterator.cpp:2997 ``` `doris_main.cpp:518` logs `Failed to initialize JNI` / SIGABRT with the same `Check failed` when the query runs. ## Root cause Introduced by #62304 (commit `85ede0bafba0`, "[opt](nereids) Optimize I/O operations for the IS NULL predicate"). That PR makes `col IS NULL` generate a `col.NULL` access path so BE reads only the null map (`NULL_MAP_ONLY` mode), saving I/O. The premise is that the column is physically nullable (has a null bitmap). The bug: the rule only checks expression nullability (`arg.nullable()`). A `LEFT JOIN` makes the right-side `NOT NULL` column's output slot nullable, so `arg.nullable() == true` and a `[col, NULL]` access path is generated even though the physical column has no null bitmap. BE then reads the null map by rowids on a NOT NULL column and hits the `is_column_nullable(*dst)` check — the backend aborts, failing the user's base-table query. This is unrelated to the IVM branch that first surfaced it: any ordinary base-table `LEFT JOIN` query with `enable_prune_nested_column = true` (default) reproduces the crash. ## Fix In `AccessPathExpressionCollector.visitIsNull`, skip the NULL-only access path generation when the `SlotReference`'s physical column is `NOT NULL` (only made nullable by the outer join). The join output stays nullable and IS NULL is evaluated on the regular data path; no access info is sent to BE for the whole-column read (`shouldSkipAccessInfo` drops the single `[col]` path). Also merged the existing sub-column-path early return into the same guard. ## Verification - `PruneNestedColumnTest.testIsNullOnNotNullColumnAfterLeftJoin`: asserts no `[segment, NULL]` access path is generated after LEFT JOIN (50 tests, all pass) - Regression `left_join_not_null_column.groovy`: LEFT JOIN aggregate query returns correct result, BE stays alive; `explain` asserts no `segment.NULL` in the plan - Before the fix, the same regression crashes the BE with the exact stack above (reproduced locally with a 3-row fact table) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
