Skip to content

Conversation

@kaka11chen
Copy link
Contributor

@kaka11chen kaka11chen commented Apr 13, 2023

Proposed changes

Problem summary

Performance test results

  • 100 million rows of random data.
  • SQL: select type_col1, type_col2 from tables where filter. The filter will returns 1400 records.
  • Single thread test.
  orc-snappy-lazy orc-snappy-no-lazy
tinyint 2.26 2.83
smallint 2.30 2.86
int 2.07 2.32
bigint 2.38 3.21
boolean 2.29 3.15
float 2.30 3.34
double 2.55 3.69
string 3.97 11.22
binary 3.79 10.28
timestamp 2.46 24.38
decimal 2.61 7.00
char 2.71 8.29
varchar 2.87 5.80
date 2.36 21.82

Checklist(Required)

  • Does it affect the original behavior
  • Has unit tests been added
  • Has document been added or modified
  • Does it need to update dependencies
  • Is this PR support rollback (If NO, please explain WHY)

Further comments

Copy link
Contributor

@github-actions github-actions bot left a 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);
Copy link
Contributor

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());
Copy link
Contributor

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);
Copy link
Contributor

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]

Suggested change
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);
Copy link
Contributor

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);
Copy link
Contributor

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();
Copy link
Contributor

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]

Suggested change
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();
Copy link
Contributor

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]

Suggested change
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 {
Copy link
Contributor

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;
Copy link
Contributor

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]

Suggested change
~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 {
Copy link
Contributor

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]

Suggested change
void* arg) const override {
void* arg) const {

@kaka11chen kaka11chen force-pushed the orc_lazy_materialization branch from 31984dc to 2389574 Compare April 13, 2023 08:30
Copy link
Contributor

@github-actions github-actions bot left a 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);
Copy link
Contributor

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);
                              ^

@kaka11chen kaka11chen force-pushed the orc_lazy_materialization branch from 2389574 to ab2d217 Compare April 13, 2023 08:52
Copy link
Contributor

@github-actions github-actions bot left a 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);
Copy link
Contributor

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);
                              ^

@kaka11chen kaka11chen force-pushed the orc_lazy_materialization branch from ab2d217 to 95b8e06 Compare April 17, 2023 06:17
@github-actions
Copy link
Contributor

sh-checker report

To get the full details, please check in the job output.

shellcheck errors

'shellcheck ' returned error 1 finding the following syntactical issues:

----------

In build.sh line 253:
    if [ $? -ne 0 ]; then
       ^----------^ SC2292 (style): Prefer [[ ]] over [ ] for tests in Bash/Ksh.
         ^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.

Did you mean: 
    if [[ $? -ne 0 ]]; then


In build.sh line 255:
      mkdir -p ${DORIS_HOME}/be/src/apache-orc
               ^-----------^ SC2086 (info): Double quote to prevent globbing and word splitting.

Did you mean: 
      mkdir -p "${DORIS_HOME}"/be/src/apache-orc


In build.sh line 256:
      curl -L https://github.com/apache/doris-thirdparty/archive/refs/heads/orc.zip | tar -xz -C ${DORIS_HOME}/be/src/apache-orc
                                                                                                 ^-----------^ SC2086 (info): Double quote to prevent globbing and word splitting.

Did you mean: 
      curl -L https://github.com/apache/doris-thirdparty/archive/refs/heads/orc.zip | tar -xz -C "${DORIS_HOME}"/be/src/apache-orc

For more information:
  https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
  https://www.shellcheck.net/wiki/SC2181 -- Check exit code directly with e.g...
  https://www.shellcheck.net/wiki/SC2292 -- Prefer [[ ]] over [ ] for tests i...
----------

You can address the above issues in one of three ways:
1. Manually correct the issue in the offending shell script;
2. Disable specific issues by adding the comment:
  # shellcheck disable=NNNN
above the line that contains the issue, where NNNN is the error code;
3. Add '-e NNNN' to the SHELLCHECK_OPTS setting in your .yml action file.



shfmt errors

'shfmt ' returned error 1 finding the following formatting issues:

----------
--- build.sh.orig
+++ build.sh
@@ -251,9 +251,9 @@
     echo "apache-orc not exists, need to update submodules ..."
     git submodule update --init --recursive
     if [ $? -ne 0 ]; then
-      wget https://github.com/apache/doris-thirdparty/archive/refs/heads/orc.zip
-      mkdir -p ${DORIS_HOME}/be/src/apache-orc
-      curl -L https://github.com/apache/doris-thirdparty/archive/refs/heads/orc.zip | tar -xz -C ${DORIS_HOME}/be/src/apache-orc
+        wget https://github.com/apache/doris-thirdparty/archive/refs/heads/orc.zip
+        mkdir -p ${DORIS_HOME}/be/src/apache-orc
+        curl -L https://github.com/apache/doris-thirdparty/archive/refs/heads/orc.zip | tar -xz -C ${DORIS_HOME}/be/src/apache-orc
     fi
 fi
 
----------

You can reformat the above files to meet shfmt's requirements by typing:

  shfmt  -w filename


${GPERFTOOLS_HOME}/include
)
include_directories($ENV{JAVA_HOME}/include)
include_directories(/mnt/datadisk0/chenqi/jdk1.8.0_131/include)
Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if [[ ! -f "${DORIS_HOME}/be/src/apache-orc/README.md " ]]; then
if [[ ! -f "${DORIS_HOME}/be/src/apache-orc/README.md" ]]; then

@kaka11chen kaka11chen force-pushed the orc_lazy_materialization branch from 95b8e06 to c9a9bf1 Compare April 27, 2023 11:38
Copy link
Contributor

@github-actions github-actions bot left a 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();
Copy link
Contributor

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]

Suggested change
std::move(*block->get_by_position(col).column).assume_mutable()->clear();
*block->get_by_position(col).column.assume_mutable()->clear();

@kaka11chen kaka11chen force-pushed the orc_lazy_materialization branch from c9a9bf1 to 4b60822 Compare April 27, 2023 12:49
@kaka11chen kaka11chen marked this pull request as ready for review April 27, 2023 13:11
morningman
morningman previously approved these changes Apr 27, 2023
Copy link
Contributor

@morningman morningman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@github-actions github-actions bot added the approved Indicates a PR has been approved by one committer. label Apr 27, 2023
@github-actions
Copy link
Contributor

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

@github-actions
Copy link
Contributor

PR approved by anyone and no changes requested.

@kaka11chen
Copy link
Contributor Author

run buildall

@hello-stephen
Copy link
Contributor

hello-stephen commented Apr 27, 2023

TeamCity pipeline, clickbench performance test result:
the sum of best hot time: 33.72 seconds
stream load tsv: 428 seconds loaded 74807831229 Bytes, about 166 MB/s
stream load json: 23 seconds loaded 2358488459 Bytes, about 97 MB/s
stream load orc: 59 seconds loaded 1101869774 Bytes, about 17 MB/s
stream load parquet: 30 seconds loaded 861443392 Bytes, about 27 MB/s
https://doris-community-test-1308700295.cos.ap-hongkong.myqcloud.com/tmp/20230509024009_clickbench_pr_140565.html

@kaka11chen kaka11chen marked this pull request as draft May 3, 2023 12:43
- 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.
@kaka11chen kaka11chen force-pushed the orc_lazy_materialization branch from 4b60822 to e1bd70d Compare May 7, 2023 02:21
@github-actions github-actions bot added kind/docs Categorizes issue or PR as related to documentation. and removed approved Indicates a PR has been approved by one committer. labels May 7, 2023
@github-actions
Copy link
Contributor

github-actions bot commented May 7, 2023

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Contributor

github-actions bot commented May 7, 2023

clang-tidy review says "All clean, LGTM! 👍"

@kaka11chen
Copy link
Contributor Author

run buildall

@kaka11chen kaka11chen marked this pull request as ready for review May 7, 2023 05:04
@github-actions
Copy link
Contributor

github-actions bot commented May 7, 2023

clang-tidy review says "All clean, LGTM! 👍"

@kaka11chen
Copy link
Contributor Author

run buildall

@github-actions
Copy link
Contributor

github-actions bot commented May 9, 2023

clang-tidy review says "All clean, LGTM! 👍"

@morningman morningman changed the title [Feature](orc-reader) Implements ORC lazy materialization. (improvement)(fix)(orc-reader) Implements ORC lazy materialization and fix known issue May 9, 2023
@kaka11chen kaka11chen changed the title (improvement)(fix)(orc-reader) Implements ORC lazy materialization and fix known issue [improvement](orc-reader) Implements ORC lazy materialization May 9, 2023
Copy link
Contributor

@morningman morningman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@morningman morningman merged commit 096aa25 into apache:master May 9, 2023
Reminiscent pushed a commit to Reminiscent/doris that referenced this pull request May 15, 2023
…#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.
Reminiscent pushed a commit to Reminiscent/doris that referenced this pull request May 15, 2023
…#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.
morningman pushed a commit that referenced this pull request Jun 9, 2023
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.
xiaokang pushed a commit that referenced this pull request Jun 9, 2023
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.
morningman pushed a commit that referenced this pull request Apr 18, 2025
…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)
```
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Apr 23, 2025
…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)
```
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Apr 23, 2025
…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)
```
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Apr 24, 2025
…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)
```
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Apr 24, 2025
…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)
```
suxiaogang223 added a commit to suxiaogang223/doris that referenced this pull request Apr 24, 2025
…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)
```
koarz pushed a commit to koarz/doris that referenced this pull request Jun 4, 2025
…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)
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/vectorization kind/docs Categorizes issue or PR as related to documentation. reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants