This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-1.2-lts by this push:
new 05ec36455c [fix](be)the set operation node should accept both nullable
and non-nullable data from child node (#24088)
05ec36455c is described below
commit 05ec36455c52c906c1e4b5ad4f4bad42ec04c5bb
Author: TengJianPing <[email protected]>
AuthorDate: Fri Sep 8 18:43:49 2023 +0800
[fix](be)the set operation node should accept both nullable and
non-nullable data from child node (#24088)
---
be/src/vec/exec/vset_operation_node.cpp | 11 +++-
be/src/vec/exec/vset_operation_node.h | 9 ++-
.../data/correctness_p0/test_set_operation.out | 4 ++
.../correctness_p0/test_set_operation.groovy | 70 ++++++++++++++++++++++
4 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/be/src/vec/exec/vset_operation_node.cpp
b/be/src/vec/exec/vset_operation_node.cpp
index 3bd1fe9d82..103ec7a38b 100644
--- a/be/src/vec/exec/vset_operation_node.cpp
+++ b/be/src/vec/exec/vset_operation_node.cpp
@@ -143,13 +143,20 @@ Status VSetOperationNode::prepare(RuntimeState* state) {
_probe_timer = ADD_TIMER(runtime_profile(), "ProbeTime");
// Prepare result expr lists.
+ vector<bool> nullable_flags;
+ nullable_flags.resize(_child_expr_lists[0].size(), false);
for (int i = 0; i < _child_expr_lists.size(); ++i) {
+ for (int j = 0; j < _child_expr_lists[i].size(); ++j) {
+ nullable_flags[j] = nullable_flags[j] ||
_child_expr_lists[i][j]->root()->is_nullable();
+ }
RETURN_IF_ERROR(VExpr::prepare(_child_expr_lists[i], state,
child(i)->row_desc()));
}
- for (auto ctx : _child_expr_lists[0]) {
+ for (int i = 0; i < _child_expr_lists[0].size(); ++i) {
+ const auto& ctx = _child_expr_lists[0][i];
_build_not_ignore_null.push_back(ctx->root()->is_nullable());
- _left_table_data_types.push_back(ctx->root()->data_type());
+ _left_table_data_types.push_back(nullable_flags[i] ?
make_nullable(ctx->root()->data_type())
+ :
ctx->root()->data_type());
}
hash_table_init();
diff --git a/be/src/vec/exec/vset_operation_node.h
b/be/src/vec/exec/vset_operation_node.h
index d21231bf6f..299f474164 100644
--- a/be/src/vec/exec/vset_operation_node.h
+++ b/be/src/vec/exec/vset_operation_node.h
@@ -225,7 +225,14 @@ struct HashTableProbe {
auto it = value.begin();
for (auto idx = _build_col_idx.begin(); idx != _build_col_idx.end();
++idx) {
auto& column =
*_build_blocks[it->block_offset].get_by_position(idx->first).column;
- _mutable_cols[idx->second]->insert_from(column, it->row_num);
+ if (_mutable_cols[idx->second]->is_nullable() xor
column.is_nullable()) {
+ DCHECK(_mutable_cols[idx->second]->is_nullable());
+ ((ColumnNullable*)(_mutable_cols[idx->second].get()))
+ ->insert_from_not_nullable(column, it->row_num);
+
+ } else {
+ _mutable_cols[idx->second]->insert_from(column, it->row_num);
+ }
}
block_size++;
}
diff --git a/regression-test/data/correctness_p0/test_set_operation.out
b/regression-test/data/correctness_p0/test_set_operation.out
new file mode 100644
index 0000000000..095c7b2035
--- /dev/null
+++ b/regression-test/data/correctness_p0/test_set_operation.out
@@ -0,0 +1,4 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !sql --
+1
+
diff --git a/regression-test/suites/correctness_p0/test_set_operation.groovy
b/regression-test/suites/correctness_p0/test_set_operation.groovy
new file mode 100644
index 0000000000..cd366f4d2b
--- /dev/null
+++ b/regression-test/suites/correctness_p0/test_set_operation.groovy
@@ -0,0 +1,70 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite("test_set_operation") {
+
+ sql """
+ drop table if exists test_set_operation_A;
+ """
+
+ sql """
+ drop table if exists test_set_operation_B;
+ """
+
+ sql """
+ create table test_set_operation_A ( a int not null )
+ ENGINE=OLAP
+ DISTRIBUTED BY HASH(a) BUCKETS 1
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1",
+ "in_memory" = "false",
+ "storage_format" = "V2"
+ );
+ """
+
+ sql """
+ create table test_set_operation_B ( b int )
+ ENGINE=OLAP
+ DISTRIBUTED BY HASH(b) BUCKETS 1
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1",
+ "in_memory" = "false",
+ "storage_format" = "V2"
+ );
+ """
+
+ sql """
+ insert into test_set_operation_A values(1),(2),(3);
+ """
+
+ sql """
+ insert into test_set_operation_B values(1),(null);
+ """
+
+ qt_sql """
+ SELECT *
+ FROM (
+ (SELECT t0.a AS one_uid
+ FROM test_set_operation_A t0 intersect (
+ (SELECT b AS one_uid
+ FROM test_set_operation_B ) EXCEPT
+ (SELECT t0.a AS one_uid
+ FROM test_set_operation_A t0
+ WHERE a = 3 ) ) ) ) c
+ ORDER BY one_uid;
+ """
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]