-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[improvement](orc-reader) Implements ORC lazy materialization #18615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
| _init_search_argument(_colname_to_value_range); | ||
| _row_reader_options.include(_read_cols); | ||
| if (_lazy_read_ctx.can_lazy_read) { | ||
| _row_reader_options.filter(_lazy_read_ctx.predicate_columns.first); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: no member named 'filter' in 'orc::RowReaderOptions' [clang-diagnostic-error]
_row_reader_options.filter(_lazy_read_ctx.predicate_columns.first);
^| _orc_filter = std::unique_ptr<ORCFilterImpl>(new ORCFilterImpl(this)); | ||
| } | ||
| try { | ||
| _row_reader = _reader->createRowReader(_row_reader_options, _orc_filter.get()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: no matching member function for call to 'createRowReader' [clang-diagnostic-error]
_row_reader = _reader->createRowReader(_row_reader_options, _orc_filter.get());
^be/src/apache-orc/c++/include/orc/Reader.hh:532: candidate function not viable: requires single argument 'options', but 2 arguments were provided
virtual std::unique_ptr<RowReader> createRowReader(const RowReaderOptions& options) const = 0;
^be/src/apache-orc/c++/include/orc/Reader.hh:525: candidate function not viable: requires 0 arguments, but 2 were provided
virtual std::unique_ptr<RowReader> createRowReader() const = 0;
^| // call resize because the first column of _src_block_ptr may not be filled by reader, | ||
| // so _src_block_ptr->rows() may return wrong result, cause the column created by `ctx->execute()` | ||
| // has only one row. | ||
| std::move(*block->get_by_position(result_column_id).column).mutate()->resize(rows); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: std::move of the const expression has no effect; remove std::move() [performance-move-const-arg]
| std::move(*block->get_by_position(result_column_id).column).mutate()->resize(rows); | |
| *block->get_by_position(result_column_id).column.mutate()->resize(rows); |
| SCOPED_RAW_TIMER(&_statistics.get_batch_time); | ||
| // reset decimal_scale_params_index; | ||
| _decimal_scale_params_index = 0; | ||
| rr = _row_reader->next(*_batch, block); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: too many arguments to function call, expected single argument 'data', have 2 arguments [clang-diagnostic-error]
rr = _row_reader->next(*_batch, block);
^be/src/apache-orc/c++/include/orc/Reader.hh:626: 'next' declared here
virtual bool next(ColumnVectorBatch& data) = 0;
^| SCOPED_RAW_TIMER(&_statistics.get_batch_time); | ||
| // reset decimal_scale_params_index; | ||
| _decimal_scale_params_index = 0; | ||
| rr = _row_reader->next(*_batch, block); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: too many arguments to function call, expected single argument 'data', have 2 arguments [clang-diagnostic-error]
rr = _row_reader->next(*_batch, block);
^be/src/apache-orc/c++/include/orc/Reader.hh:626: 'next' declared here
virtual bool next(ColumnVectorBatch& data) = 0;
^| size_t count = filter_size - simd::count_zero_num((int8_t*)filter.data(), filter_size); | ||
| if (count == 0) { | ||
| for (auto& col : columns_to_filter) { | ||
| std::move(*block->get_by_position(col).column).assume_mutable()->clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: std::move of the const expression has no effect; remove std::move() [performance-move-const-arg]
| std::move(*block->get_by_position(col).column).assume_mutable()->clear(); | |
| *block->get_by_position(col).column.assume_mutable()->clear(); |
| RETURN_IF_ERROR(_execute_conjuncts(ctxs, block, &result_filter, &can_filter_all)); | ||
| if (can_filter_all) { | ||
| for (auto& col : columns_to_filter) { | ||
| std::move(*block->get_by_position(col).column).assume_mutable()->clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: std::move of the const expression has no effect; remove std::move() [performance-move-const-arg]
| std::move(*block->get_by_position(col).column).assume_mutable()->clear(); | |
| *block->get_by_position(col).column.assume_mutable()->clear(); |
| RuntimeProfile::Counter* decode_null_map_time; | ||
| }; | ||
|
|
||
| class ORCFilterImpl : public orc::ORCFilter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: expected class name [clang-diagnostic-error]
class ORCFilterImpl : public orc::ORCFilter {
^| class ORCFilterImpl : public orc::ORCFilter { | ||
| public: | ||
| ORCFilterImpl(OrcReader* orcReader) : orcReader(orcReader) {} | ||
| ~ORCFilterImpl() override = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: only virtual member functions can be marked 'override' [clang-diagnostic-error]
| ~ORCFilterImpl() override = default; | |
| ~ORCFilterImpl() = default; |
| ORCFilterImpl(OrcReader* orcReader) : orcReader(orcReader) {} | ||
| ~ORCFilterImpl() override = default; | ||
| void filter(orc::ColumnVectorBatch& data, uint16_t* sel, uint16_t size, | ||
| void* arg) const override { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: only virtual member functions can be marked 'override' [clang-diagnostic-error]
| void* arg) const override { | |
| void* arg) const { |
31984dc to
2389574
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
| SCOPED_RAW_TIMER(&_statistics.get_batch_time); | ||
| // reset decimal_scale_params_index; | ||
| _decimal_scale_params_index = 0; | ||
| rr = _row_reader->nextBatch(*_batch, block); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: no member named 'nextBatch' in 'orc::RowReader' [clang-diagnostic-error]
rr = _row_reader->nextBatch(*_batch, block);
^2389574 to
ab2d217
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
| SCOPED_RAW_TIMER(&_statistics.get_batch_time); | ||
| // reset decimal_scale_params_index; | ||
| _decimal_scale_params_index = 0; | ||
| rr = _row_reader->nextBatch(*_batch, block); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: no member named 'nextBatch' in 'orc::RowReader' [clang-diagnostic-error]
rr = _row_reader->nextBatch(*_batch, block);
^ab2d217 to
95b8e06
Compare
|
be/CMakeLists.txt
Outdated
| ${GPERFTOOLS_HOME}/include | ||
| ) | ||
| include_directories($ENV{JAVA_HOME}/include) | ||
| include_directories(/mnt/datadisk0/chenqi/jdk1.8.0_131/include) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix it
build.sh
Outdated
| fi | ||
|
|
||
| if [[ ! -f "${DORIS_HOME}/be/src/apache-orc/README.md" ]]; then | ||
| if [[ ! -f "${DORIS_HOME}/be/src/apache-orc/README.md " ]]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if [[ ! -f "${DORIS_HOME}/be/src/apache-orc/README.md " ]]; then | |
| if [[ ! -f "${DORIS_HOME}/be/src/apache-orc/README.md" ]]; then |
95b8e06 to
c9a9bf1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
| RETURN_IF_ERROR(execute_conjuncts(ctxs, filters, block, &result_filter, &can_filter_all)); | ||
| if (can_filter_all) { | ||
| for (auto& col : columns_to_filter) { | ||
| std::move(*block->get_by_position(col).column).assume_mutable()->clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: std::move of the const expression has no effect; remove std::move() [performance-move-const-arg]
| std::move(*block->get_by_position(col).column).assume_mutable()->clear(); | |
| *block->get_by_position(col).column.assume_mutable()->clear(); |
c9a9bf1 to
4b60822
Compare
morningman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
PR approved by at least one committer and no changes requested. |
|
PR approved by anyone and no changes requested. |
|
run buildall |
|
TeamCity pipeline, clickbench performance test result: |
- Implements ORC lazy materialization, integrate with the implementation of apache/doris-thirdparty#56 and apache/doris-thirdparty#62. - Refactor code: Move `execute_conjuncts()` and `execute_conjuncts_and_filter_block()` in `parquet_group_reader `to `VExprContext`, used by parquet reader and orc reader. - Add session variable `enable_parquet_lazy_materialization` and `enable_orc_lazy_materialization` to control whether enable lazy materialization.
4b60822 to
e1bd70d
Compare
|
clang-tidy review says "All clean, LGTM! 👍" |
|
clang-tidy review says "All clean, LGTM! 👍" |
|
run buildall |
|
clang-tidy review says "All clean, LGTM! 👍" |
|
run buildall |
|
clang-tidy review says "All clean, LGTM! 👍" |
morningman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…#18615) - Implements ORC lazy materialization, integrate with the implementation of apache/doris-thirdparty#56 and apache/doris-thirdparty#62. - Refactor code: Move `execute_conjuncts()` and `execute_conjuncts_and_filter_block()` in `parquet_group_reader `to `VExprContext`, used by parquet reader and orc reader. - Add session variables `enable_parquet_lazy_materialization` and `enable_orc_lazy_materialization` to control whether enable lazy materialization. - Modify `build.sh` to update apache-orc submodule or download package every time.
…#18615) - Implements ORC lazy materialization, integrate with the implementation of apache/doris-thirdparty#56 and apache/doris-thirdparty#62. - Refactor code: Move `execute_conjuncts()` and `execute_conjuncts_and_filter_block()` in `parquet_group_reader `to `VExprContext`, used by parquet reader and orc reader. - Add session variables `enable_parquet_lazy_materialization` and `enable_orc_lazy_materialization` to control whether enable lazy materialization. - Modify `build.sh` to update apache-orc submodule or download package every time.
Fix some bugs of orc lazy materialization(#18615) - Fix issue causing column size to continuously increase after `execute_conjuncts()` by calling `Block::erase_useless_column()`. - Fix partition issues of orc lazy materialization. - Fix lazy materialization will not be used when the predicate column is inconsistent with the orc file.
Fix some bugs of orc lazy materialization(#18615) - Fix issue causing column size to continuously increase after `execute_conjuncts()` by calling `Block::erase_useless_column()`. - Fix partition issues of orc lazy materialization. - Fix lazy materialization will not be used when the predicate column is inconsistent with the orc file.
…of List or Map (#50136) ### What problem does this PR solve? Related PR: #18615 Problem Summary: The problem is like apache/doris-thirdparty#256 When performing late materialization for LIST or MAP types, filters should not be applied directly to their child fields. These complex types rely on offsets to correctly map parent-child relationships within the columnar storage layout (e.g., in ORC or Parquet files). If filters are applied to the children of a LIST or MAP field, it may cause inconsistencies in the offset alignment, leading to incorrect data being read—such as mismatched elements, missing values, or even runtime errors. This breaks the structural integrity of the nested data and can produce incorrect query results. ```text mysql> select * from complex_data_orc; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 1 | {"a":1, "b":2} | ["a", "b"] | | 2 | {"b":3, "c":4} | ["b"] | | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 10 rows in set (0.02 sec) !!!WRONG RESULT: mysql> select * from complex_data_orc where id > 2; +------+--------------------------+----------------+ | id | m | l | +------+--------------------------+----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "":11} | ["a"] | | 6 | {"":12, "":13} | ["c"] | | 7 | {"":15} | ["a", ""] | | 8 | {"":17} | ["", ""] | | 9 | {"":19} | ["", ""] | | 10 | {"a":20, "b":21, "c":22} | ["", "b", "c"] | +------+--------------------------+----------------+ 8 rows in set (0.02 sec) ``` To ensure correctness, filters should only be applied at the top level of the LIST or MAP, and their children should be read in full when late materialization occurs. After this pr: ```text mysql> select * from complex_data_orc where id > 2; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 8 rows in set (1.41 sec) ```
…of List or Map (apache#50136) Related PR: apache#18615 Problem Summary: The problem is like apache/doris-thirdparty#256 When performing late materialization for LIST or MAP types, filters should not be applied directly to their child fields. These complex types rely on offsets to correctly map parent-child relationships within the columnar storage layout (e.g., in ORC or Parquet files). If filters are applied to the children of a LIST or MAP field, it may cause inconsistencies in the offset alignment, leading to incorrect data being read—such as mismatched elements, missing values, or even runtime errors. This breaks the structural integrity of the nested data and can produce incorrect query results. ```text mysql> select * from complex_data_orc; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 1 | {"a":1, "b":2} | ["a", "b"] | | 2 | {"b":3, "c":4} | ["b"] | | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 10 rows in set (0.02 sec) !!!WRONG RESULT: mysql> select * from complex_data_orc where id > 2; +------+--------------------------+----------------+ | id | m | l | +------+--------------------------+----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "":11} | ["a"] | | 6 | {"":12, "":13} | ["c"] | | 7 | {"":15} | ["a", ""] | | 8 | {"":17} | ["", ""] | | 9 | {"":19} | ["", ""] | | 10 | {"a":20, "b":21, "c":22} | ["", "b", "c"] | +------+--------------------------+----------------+ 8 rows in set (0.02 sec) ``` To ensure correctness, filters should only be applied at the top level of the LIST or MAP, and their children should be read in full when late materialization occurs. After this pr: ```text mysql> select * from complex_data_orc where id > 2; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 8 rows in set (1.41 sec) ```
…of List or Map (apache#50136) Related PR: apache#18615 Problem Summary: The problem is like apache/doris-thirdparty#256 When performing late materialization for LIST or MAP types, filters should not be applied directly to their child fields. These complex types rely on offsets to correctly map parent-child relationships within the columnar storage layout (e.g., in ORC or Parquet files). If filters are applied to the children of a LIST or MAP field, it may cause inconsistencies in the offset alignment, leading to incorrect data being read—such as mismatched elements, missing values, or even runtime errors. This breaks the structural integrity of the nested data and can produce incorrect query results. ```text mysql> select * from complex_data_orc; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 1 | {"a":1, "b":2} | ["a", "b"] | | 2 | {"b":3, "c":4} | ["b"] | | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 10 rows in set (0.02 sec) !!!WRONG RESULT: mysql> select * from complex_data_orc where id > 2; +------+--------------------------+----------------+ | id | m | l | +------+--------------------------+----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "":11} | ["a"] | | 6 | {"":12, "":13} | ["c"] | | 7 | {"":15} | ["a", ""] | | 8 | {"":17} | ["", ""] | | 9 | {"":19} | ["", ""] | | 10 | {"a":20, "b":21, "c":22} | ["", "b", "c"] | +------+--------------------------+----------------+ 8 rows in set (0.02 sec) ``` To ensure correctness, filters should only be applied at the top level of the LIST or MAP, and their children should be read in full when late materialization occurs. After this pr: ```text mysql> select * from complex_data_orc where id > 2; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 8 rows in set (1.41 sec) ```
…of List or Map (apache#50136) Related PR: apache#18615 Problem Summary: The problem is like apache/doris-thirdparty#256 When performing late materialization for LIST or MAP types, filters should not be applied directly to their child fields. These complex types rely on offsets to correctly map parent-child relationships within the columnar storage layout (e.g., in ORC or Parquet files). If filters are applied to the children of a LIST or MAP field, it may cause inconsistencies in the offset alignment, leading to incorrect data being read—such as mismatched elements, missing values, or even runtime errors. This breaks the structural integrity of the nested data and can produce incorrect query results. ```text mysql> select * from complex_data_orc; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 1 | {"a":1, "b":2} | ["a", "b"] | | 2 | {"b":3, "c":4} | ["b"] | | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 10 rows in set (0.02 sec) !!!WRONG RESULT: mysql> select * from complex_data_orc where id > 2; +------+--------------------------+----------------+ | id | m | l | +------+--------------------------+----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "":11} | ["a"] | | 6 | {"":12, "":13} | ["c"] | | 7 | {"":15} | ["a", ""] | | 8 | {"":17} | ["", ""] | | 9 | {"":19} | ["", ""] | | 10 | {"a":20, "b":21, "c":22} | ["", "b", "c"] | +------+--------------------------+----------------+ 8 rows in set (0.02 sec) ``` To ensure correctness, filters should only be applied at the top level of the LIST or MAP, and their children should be read in full when late materialization occurs. After this pr: ```text mysql> select * from complex_data_orc where id > 2; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 8 rows in set (1.41 sec) ```
…of List or Map (apache#50136) Related PR: apache#18615 Problem Summary: The problem is like apache/doris-thirdparty#256 When performing late materialization for LIST or MAP types, filters should not be applied directly to their child fields. These complex types rely on offsets to correctly map parent-child relationships within the columnar storage layout (e.g., in ORC or Parquet files). If filters are applied to the children of a LIST or MAP field, it may cause inconsistencies in the offset alignment, leading to incorrect data being read—such as mismatched elements, missing values, or even runtime errors. This breaks the structural integrity of the nested data and can produce incorrect query results. ```text mysql> select * from complex_data_orc; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 1 | {"a":1, "b":2} | ["a", "b"] | | 2 | {"b":3, "c":4} | ["b"] | | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 10 rows in set (0.02 sec) !!!WRONG RESULT: mysql> select * from complex_data_orc where id > 2; +------+--------------------------+----------------+ | id | m | l | +------+--------------------------+----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "":11} | ["a"] | | 6 | {"":12, "":13} | ["c"] | | 7 | {"":15} | ["a", ""] | | 8 | {"":17} | ["", ""] | | 9 | {"":19} | ["", ""] | | 10 | {"a":20, "b":21, "c":22} | ["", "b", "c"] | +------+--------------------------+----------------+ 8 rows in set (0.02 sec) ``` To ensure correctness, filters should only be applied at the top level of the LIST or MAP, and their children should be read in full when late materialization occurs. After this pr: ```text mysql> select * from complex_data_orc where id > 2; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 8 rows in set (1.41 sec) ```
…of List or Map (apache#50136) Related PR: apache#18615 Problem Summary: The problem is like apache/doris-thirdparty#256 When performing late materialization for LIST or MAP types, filters should not be applied directly to their child fields. These complex types rely on offsets to correctly map parent-child relationships within the columnar storage layout (e.g., in ORC or Parquet files). If filters are applied to the children of a LIST or MAP field, it may cause inconsistencies in the offset alignment, leading to incorrect data being read—such as mismatched elements, missing values, or even runtime errors. This breaks the structural integrity of the nested data and can produce incorrect query results. ```text mysql> select * from complex_data_orc; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 1 | {"a":1, "b":2} | ["a", "b"] | | 2 | {"b":3, "c":4} | ["b"] | | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 10 rows in set (0.02 sec) !!!WRONG RESULT: mysql> select * from complex_data_orc where id > 2; +------+--------------------------+----------------+ | id | m | l | +------+--------------------------+----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "":11} | ["a"] | | 6 | {"":12, "":13} | ["c"] | | 7 | {"":15} | ["a", ""] | | 8 | {"":17} | ["", ""] | | 9 | {"":19} | ["", ""] | | 10 | {"a":20, "b":21, "c":22} | ["", "b", "c"] | +------+--------------------------+----------------+ 8 rows in set (0.02 sec) ``` To ensure correctness, filters should only be applied at the top level of the LIST or MAP, and their children should be read in full when late materialization occurs. After this pr: ```text mysql> select * from complex_data_orc where id > 2; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 8 rows in set (1.41 sec) ```
…of List or Map (apache#50136) ### What problem does this PR solve? Related PR: apache#18615 Problem Summary: The problem is like apache/doris-thirdparty#256 When performing late materialization for LIST or MAP types, filters should not be applied directly to their child fields. These complex types rely on offsets to correctly map parent-child relationships within the columnar storage layout (e.g., in ORC or Parquet files). If filters are applied to the children of a LIST or MAP field, it may cause inconsistencies in the offset alignment, leading to incorrect data being read—such as mismatched elements, missing values, or even runtime errors. This breaks the structural integrity of the nested data and can produce incorrect query results. ```text mysql> select * from complex_data_orc; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 1 | {"a":1, "b":2} | ["a", "b"] | | 2 | {"b":3, "c":4} | ["b"] | | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 10 rows in set (0.02 sec) !!!WRONG RESULT: mysql> select * from complex_data_orc where id > 2; +------+--------------------------+----------------+ | id | m | l | +------+--------------------------+----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "":11} | ["a"] | | 6 | {"":12, "":13} | ["c"] | | 7 | {"":15} | ["a", ""] | | 8 | {"":17} | ["", ""] | | 9 | {"":19} | ["", ""] | | 10 | {"a":20, "b":21, "c":22} | ["", "b", "c"] | +------+--------------------------+----------------+ 8 rows in set (0.02 sec) ``` To ensure correctness, filters should only be applied at the top level of the LIST or MAP, and their children should be read in full when late materialization occurs. After this pr: ```text mysql> select * from complex_data_orc where id > 2; +------+--------------------------+-----------------+ | id | m | l | +------+--------------------------+-----------------+ | 3 | {"c":5, "a":6, "b":7} | ["c", "a"] | | 4 | {"a":8, "c":9} | ["b", "c"] | | 5 | {"b":10, "a":11} | ["a"] | | 6 | {"c":12, "b":13} | ["c"] | | 7 | {"a":15} | ["a", "a"] | | 8 | {"b":17} | ["b", "b"] | | 9 | {"c":19} | ["c", "c"] | | 10 | {"a":20, "b":21, "c":22} | ["a", "b", "c"] | +------+--------------------------+-----------------+ 8 rows in set (1.41 sec) ```
Proposed changes
Problem summary
execute_conjuncts()andexecute_conjuncts_and_filter_block()inparquet_group_readertoVExprContext, used by parquet reader and orc reader.enable_parquet_lazy_materializationandenable_orc_lazy_materializationto control whether enable lazy materialization.build.shto update apache-orc submodule or download package every time.Performance test results
select type_col1, type_col2 from tables where filter. The filter will returns 1400 records.Checklist(Required)
Further comments