This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 343a6dc29d [improvement](hash join) Return result early if probe side
has no data (#23044)
343a6dc29d is described below
commit 343a6dc29de2566d86e2caccc015df683cc61d75
Author: TengJianPing <[email protected]>
AuthorDate: Thu Aug 17 09:17:09 2023 +0800
[improvement](hash join) Return result early if probe side has no data
(#23044)
---
be/src/runtime/runtime_state.h | 5 +
be/src/vec/exec/join/vhash_join_node.cpp | 52 ++-
be/src/vec/exec/join/vhash_join_node.h | 8 +
be/src/vec/exec/join/vjoin_node_base.h | 2 +-
.../java/org/apache/doris/qe/SessionVariable.java | 8 +
gensrc/thrift/PaloInternalService.thrift | 2 +
.../join/test_hash_join_probe_early_eos.out | 93 +++++
.../join/test_hash_join_probe_early_eos.groovy | 397 +++++++++++++++++++++
8 files changed, 565 insertions(+), 2 deletions(-)
diff --git a/be/src/runtime/runtime_state.h b/be/src/runtime/runtime_state.h
index 1f35f6c1b8..73c6f1938c 100644
--- a/be/src/runtime/runtime_state.h
+++ b/be/src/runtime/runtime_state.h
@@ -394,6 +394,11 @@ public:
_query_options.enable_share_hash_table_for_broadcast_join;
}
+ bool enable_hash_join_early_start_probe() const {
+ return _query_options.__isset.enable_hash_join_early_start_probe &&
+ _query_options.enable_hash_join_early_start_probe;
+ }
+
int repeat_max_num() const {
#ifndef BE_TEST
if (!_query_options.__isset.repeat_max_num) {
diff --git a/be/src/vec/exec/join/vhash_join_node.cpp
b/be/src/vec/exec/join/vhash_join_node.cpp
index 807c63ef5c..4494ec80d2 100644
--- a/be/src/vec/exec/join/vhash_join_node.cpp
+++ b/be/src/vec/exec/join/vhash_join_node.cpp
@@ -678,6 +678,11 @@ Status HashJoinNode::push(RuntimeState* /*state*/,
vectorized::Block* input_bloc
Status HashJoinNode::get_next(RuntimeState* state, Block* output_block, bool*
eos) {
SCOPED_TIMER(_runtime_profile->total_time_counter());
+ if (_is_hash_join_early_start_probe_eos(state)) {
+ *eos = true;
+ return Status::OK();
+ }
+
if (_short_circuit_for_probe) {
// If we use a short-circuit strategy, should return empty block
directly.
*eos = true;
@@ -761,6 +766,50 @@ void HashJoinNode::_prepare_probe_block() {
release_block_memory(_probe_block);
}
+bool HashJoinNode::_enable_hash_join_early_start_probe(RuntimeState* state)
const {
+ return state->enable_hash_join_early_start_probe() &&
+ (_join_op == TJoinOp::INNER_JOIN || _join_op ==
TJoinOp::LEFT_OUTER_JOIN ||
+ _join_op == TJoinOp::LEFT_SEMI_JOIN || _join_op ==
TJoinOp::LEFT_ANTI_JOIN);
+}
+
+bool HashJoinNode::_is_hash_join_early_start_probe_eos(RuntimeState* state)
const {
+ return _enable_hash_join_early_start_probe(state) && _probe_block.rows()
== 0;
+}
+
+void HashJoinNode::_probe_side_open_thread(RuntimeState* state,
std::promise<Status>* promise) {
+ Defer defer {[&]() { _probe_open_finish = true; }};
+
+ SCOPED_ATTACH_TASK(state);
+ auto st = child(0)->open(state);
+ if (!st.ok()) {
+ promise->set_value(st);
+ return;
+ }
+ if (_enable_hash_join_early_start_probe(state)) {
+ while (need_more_input_data()) {
+ prepare_for_next();
+ SCOPED_TIMER(_probe_next_timer);
+ st = child(0)->get_next_after_projects(
+ state, &_probe_block, &_probe_eos,
+ std::bind((Status(ExecNode::*)(RuntimeState*,
vectorized::Block*, bool*)) &
+ ExecNode::get_next,
+ _children[0], std::placeholders::_1,
std::placeholders::_2,
+ std::placeholders::_3));
+ if (!st.ok()) {
+ promise->set_value(st);
+ return;
+ }
+
+ st = push(state, &_probe_block, _probe_eos);
+ if (!st.ok()) {
+ promise->set_value(st);
+ return;
+ }
+ }
+ }
+ promise->set_value(Status::OK());
+}
+
Status HashJoinNode::open(RuntimeState* state) {
SCOPED_TIMER(_runtime_profile->total_time_counter());
SCOPED_TIMER(_open_timer);
@@ -800,7 +849,8 @@ Status HashJoinNode::_materialize_build_side(RuntimeState*
state) {
Block block;
// If eos or have already met a null value using short-circuit
strategy, we do not need to pull
// data from data.
- while (!eos && !_short_circuit_for_null_in_probe_side) {
+ while (!eos && !_short_circuit_for_null_in_probe_side &&
+ (!_probe_open_finish ||
!_is_hash_join_early_start_probe_eos(state))) {
block.clear_column_data();
RETURN_IF_CANCELLED(state);
{
diff --git a/be/src/vec/exec/join/vhash_join_node.h
b/be/src/vec/exec/join/vhash_join_node.h
index 096a9148cc..85e53dbdab 100644
--- a/be/src/vec/exec/join/vhash_join_node.h
+++ b/be/src/vec/exec/join/vhash_join_node.h
@@ -21,6 +21,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <atomic>
#include <iosfwd>
#include <memory>
#include <string>
@@ -261,6 +262,9 @@ public:
return _runtime_filter_slots->ready_finish_publish();
}
+protected:
+ void _probe_side_open_thread(RuntimeState* state, std::promise<Status>*
status) override;
+
private:
void _init_short_circuit_for_probe() override {
_short_circuit_for_probe =
@@ -273,6 +277,9 @@ private:
(_build_blocks->empty() && _join_op ==
TJoinOp::RIGHT_ANTI_JOIN);
}
+ bool _enable_hash_join_early_start_probe(RuntimeState* state) const;
+ bool _is_hash_join_early_start_probe_eos(RuntimeState* state) const;
+
// probe expr
VExprContextSPtrs _probe_expr_ctxs;
// build expr
@@ -409,6 +416,7 @@ private:
std::vector<IRuntimeFilter*> _runtime_filters;
size_t _build_bf_cardinality = 0;
+ std::atomic_bool _probe_open_finish = false;
};
} // namespace vectorized
} // namespace doris
diff --git a/be/src/vec/exec/join/vjoin_node_base.h
b/be/src/vec/exec/join/vjoin_node_base.h
index 120e77785e..7ebbd692e4 100644
--- a/be/src/vec/exec/join/vjoin_node_base.h
+++ b/be/src/vec/exec/join/vjoin_node_base.h
@@ -82,7 +82,7 @@ protected:
// columns from probe side to a nullable column.
Status _build_output_block(Block* origin_block, Block* output_block, bool
keep_origin = true);
// Open probe side asynchronously.
- void _probe_side_open_thread(RuntimeState* state, std::promise<Status>*
status);
+ virtual void _probe_side_open_thread(RuntimeState* state,
std::promise<Status>* status);
// Initialize the join operation.
void _init_join_op();
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
index ae3f638d99..1f4885d9fc 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
@@ -297,6 +297,9 @@ public class SessionVariable implements Serializable,
Writable {
public static final String ENABLE_SHARE_HASH_TABLE_FOR_BROADCAST_JOIN
= "enable_share_hash_table_for_broadcast_join";
+ // Optimize when probe side has no data for some hash join types
+ public static final String ENABLE_HASH_JOIN_EARLY_START_PROBE =
"enable_hash_join_early_start_probe";
+
// support unicode in label, table, column, common name check
public static final String ENABLE_UNICODE_NAME_SUPPORT =
"enable_unicode_name_support";
@@ -935,6 +938,9 @@ public class SessionVariable implements Serializable,
Writable {
@VariableMgr.VarAttr(name = ENABLE_SHARE_HASH_TABLE_FOR_BROADCAST_JOIN,
fuzzy = true)
public boolean enableShareHashTableForBroadcastJoin = true;
+ @VariableMgr.VarAttr(name = ENABLE_HASH_JOIN_EARLY_START_PROBE, fuzzy =
true)
+ public boolean enableHashJoinEarlyStartProbe = false;
+
@VariableMgr.VarAttr(name = ENABLE_UNICODE_NAME_SUPPORT)
public boolean enableUnicodeNameSupport = false;
@@ -1116,6 +1122,7 @@ public class SessionVariable implements Serializable,
Writable {
this.partitionedHashJoinRowsThreshold = random.nextBoolean() ? 8 :
1048576;
this.partitionedHashAggRowsThreshold = random.nextBoolean() ? 8 :
1048576;
this.enableShareHashTableForBroadcastJoin = random.nextBoolean();
+ this.enableHashJoinEarlyStartProbe = random.nextBoolean();
int randomInt = random.nextInt(4);
if (randomInt % 2 == 0) {
this.rewriteOrToInPredicateThreshold = 100000;
@@ -2116,6 +2123,7 @@ public class SessionVariable implements Serializable,
Writable {
tResult.setReturnObjectDataAsBinary(returnObjectDataAsBinary);
tResult.setTrimTailingSpacesForExternalTableQuery(trimTailingSpacesForExternalTableQuery);
tResult.setEnableShareHashTableForBroadcastJoin(enableShareHashTableForBroadcastJoin);
+
tResult.setEnableHashJoinEarlyStartProbe(enableHashJoinEarlyStartProbe);
tResult.setBatchSize(batchSize);
tResult.setDisableStreamPreaggregations(disableStreamPreaggregations);
diff --git a/gensrc/thrift/PaloInternalService.thrift
b/gensrc/thrift/PaloInternalService.thrift
index 8928d78438..e78b64d33b 100644
--- a/gensrc/thrift/PaloInternalService.thrift
+++ b/gensrc/thrift/PaloInternalService.thrift
@@ -229,6 +229,8 @@ struct TQueryOptions {
76: optional bool enable_inverted_index_query = true;
77: optional bool truncate_char_or_varchar_columns = false
+
+ 78: optional bool enable_hash_join_early_start_probe = false
}
diff --git
a/regression-test/data/query_p0/join/test_hash_join_probe_early_eos.out
b/regression-test/data/query_p0/join/test_hash_join_probe_early_eos.out
new file mode 100644
index 0000000000..6d4312aba7
--- /dev/null
+++ b/regression-test/data/query_p0/join/test_hash_join_probe_early_eos.out
@@ -0,0 +1,93 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !sanity_check0 --
+1 a
+2 b
+3 c
+4 d
+5 e
+
+-- !sanity_check1 --
+1 a
+2 b
+3 c
+
+-- !sanity_check2 --
+
+-- !sanity_check3 --
+6 f
+7 g
+
+-- !sanity_check4 --
+
+-- !inner_join0 --
+
+-- !inner_join1 --
+
+-- !inner_join2 --
+
+-- !left_join0 --
+
+-- !left_join1 --
+1 a \N \N \N \N
+2 b \N \N \N \N
+3 c \N \N \N \N
+4 d \N \N \N \N
+5 e \N \N \N \N
+
+-- !left_join2 --
+
+-- !left_join3 --
+
+-- !left_semi_join0 --
+
+-- !left_semi_join1 --
+
+-- !left_semi_join2 --
+
+-- !left_anti_join0 --
+
+-- !left_anti_join1 --
+1 a
+2 b
+3 c
+4 d
+5 e
+
+-- !left_anti_join2 --
+
+-- !inner_join_probe_eos0 --
+
+-- !inner_join_join_probe_eos1 --
+
+-- !inner_join_join_probe_eos2 --
+
+-- !left_join_join_probe_eos0 --
+
+-- !left_join_join_probe_eos1 --
+1 a \N \N \N \N
+2 b \N \N \N \N
+3 c \N \N \N \N
+4 d \N \N \N \N
+5 e \N \N \N \N
+
+-- !left_join_join_probe_eos2 --
+
+-- !left_join_join_probe_eos3 --
+
+-- !left_semi_join_join_probe_eos0 --
+
+-- !left_semi_join_join_probe_eos1 --
+
+-- !left_semi_join_join_probe_eos2 --
+
+-- !left_anti_join_join_probe_eos0 --
+
+-- !left_anti_join_join_probe_eos1 --
+1 a
+2 b
+3 c
+4 d
+5 e
+
+-- !left_anti_join_join_probe_eos2 --
+
diff --git
a/regression-test/suites/query_p0/join/test_hash_join_probe_early_eos.groovy
b/regression-test/suites/query_p0/join/test_hash_join_probe_early_eos.groovy
new file mode 100644
index 0000000000..963de0f949
--- /dev/null
+++ b/regression-test/suites/query_p0/join/test_hash_join_probe_early_eos.groovy
@@ -0,0 +1,397 @@
+// 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_hash_join_probe_early_eos", "query") {
+
+ sql """ DROP TABLE IF EXISTS test_hash_join_probe_early_eos_t0 """
+ sql """ DROP TABLE IF EXISTS test_hash_join_probe_early_eos_t1 """
+ sql """ DROP TABLE IF EXISTS test_hash_join_probe_early_eos_t2 """
+ sql """ DROP TABLE IF EXISTS test_hash_join_probe_early_eos_t3 """
+
+ // t0
+ sql """
+ CREATE TABLE test_hash_join_probe_early_eos_t0 (
+ `t0_k0` int,
+ `t0_v0` varchar(10)
+ ) ENGINE=OLAP
+ DISTRIBUTED BY HASH(`t0_k0`) BUCKETS 10
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+ );
+ """
+ sql """insert into test_hash_join_probe_early_eos_t0 values
(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');"""
+
+ // t1
+ sql """
+ CREATE TABLE test_hash_join_probe_early_eos_t1 (
+ `t1_k0` int,
+ `t1_v0` varchar(10)
+ ) ENGINE=OLAP
+ DISTRIBUTED BY HASH(`t1_k0`) BUCKETS 10
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+ );
+ """
+ sql """insert into test_hash_join_probe_early_eos_t1 values
(1,'a'),(2,'b'),(3,'c');"""
+
+ // t2
+ sql """
+ CREATE TABLE test_hash_join_probe_early_eos_t2 (
+ `t2_k0` int,
+ `t2_v0` varchar(10)
+ ) ENGINE=OLAP
+ DISTRIBUTED BY HASH(`t2_k0`) BUCKETS 10
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+ );
+ """
+
+ // t3
+ sql """
+ CREATE TABLE test_hash_join_probe_early_eos_t3 (
+ `t3_k0` int,
+ `t3_v0` varchar(10)
+ ) ENGINE=OLAP
+ DISTRIBUTED BY HASH(`t3_k0`) BUCKETS 10
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+ );
+ """
+ sql """insert into test_hash_join_probe_early_eos_t3 values
(6,'f'),(7,'g');"""
+
+ sql """ set disable_join_reorder = true; """
+ // test not probe early eos
+ sql """ set enable_hash_join_early_start_probe = false; """
+
+ qt_sanity_check0 """
+ select * from test_hash_join_probe_early_eos_t0 order by t0_k0;
+ """
+ qt_sanity_check1 """
+ select * from test_hash_join_probe_early_eos_t1 order by t1_k0;
+ """
+ qt_sanity_check2 """
+ select * from test_hash_join_probe_early_eos_t2 order by t2_k0;
+ """
+ qt_sanity_check3 """
+ select * from test_hash_join_probe_early_eos_t3 order by t3_k0;
+ """
+ qt_sanity_check4 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t1
+ inner join test_hash_join_probe_early_eos_t3 on t1_k0 = t3_k0
+ """
+
+ qt_inner_join0 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ inner join test_hash_join_probe_early_eos_t1 on t2_k0 = t1_k0
+ """
+ qt_inner_join1 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t0
+ inner join (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ inner join test_hash_join_probe_early_eos_t1 on t2_k0 =
t1_k0
+ ) tmp0 on t0_k0 = t1_k0;
+ """
+ qt_inner_join2 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t1
+ inner join test_hash_join_probe_early_eos_t3 on t1_k0 =
t3_k0
+ ) tmp0 inner join test_hash_join_probe_early_eos_t0 on t1_k0 =
t0_k0;
+ """
+
+ qt_left_join0 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left join test_hash_join_probe_early_eos_t1 on t2_k0 = t1_k0
+ order by t2_k0, t1_k0;
+ """
+ qt_left_join1 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t0
+ left join (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left join test_hash_join_probe_early_eos_t1 on t2_k0 =
t1_k0
+ ) tmp0 on t0_k0 = t1_k0
+ order by t0_k0;
+ """
+ qt_left_join2 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left join test_hash_join_probe_early_eos_t1 on t2_k0 =
t1_k0
+ ) tmp0 left join test_hash_join_probe_early_eos_t0 on t1_k0 =
t0_k0;
+ """
+ qt_left_join3 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t1
+ inner join test_hash_join_probe_early_eos_t3 on t1_k0 =
t3_k0
+ ) tmp0 left join test_hash_join_probe_early_eos_t0 on t1_k0 =
t0_k0;
+
+ """
+
+ qt_left_semi_join0 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left semi join test_hash_join_probe_early_eos_t1 on t2_k0 = t1_k0
+ """
+ qt_left_semi_join1 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t0
+ left semi join (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left semi join test_hash_join_probe_early_eos_t1 on t2_k0
= t1_k0
+ ) tmp0 on t0_k0 = t2_k0;
+ """
+ qt_left_semi_join2 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left semi join test_hash_join_probe_early_eos_t1 on t2_k0
= t1_k0
+ ) tmp0 left semi join test_hash_join_probe_early_eos_t0 on t2_k0 =
t0_k0;
+ """
+
+ qt_left_anti_join0 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left anti join test_hash_join_probe_early_eos_t1 on t2_k0 = t1_k0
+ """
+ qt_left_anti_join1 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t0
+ left anti join (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left anti join test_hash_join_probe_early_eos_t1 on t2_k0
= t1_k0
+ ) tmp0 on t0_k0 = t2_k0
+ order by t0_k0;
+ """
+ qt_left_anti_join2 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left anti join test_hash_join_probe_early_eos_t1 on t2_k0
= t1_k0
+ ) tmp0 left anti join test_hash_join_probe_early_eos_t0 on t2_k0 =
t0_k0;
+ """
+
+ // test not probe early eos
+ sql """ set enable_hash_join_early_start_probe = true; """
+ qt_inner_join_probe_eos0 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ inner join test_hash_join_probe_early_eos_t1 on t2_k0 = t1_k0
+ """
+ qt_inner_join_join_probe_eos1 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t0
+ inner join (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ inner join test_hash_join_probe_early_eos_t1 on t2_k0 =
t1_k0
+ ) tmp0 on t0_k0 = t1_k0
+ order by t0_k0;
+ """
+ qt_inner_join_join_probe_eos2 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t1
+ inner join test_hash_join_probe_early_eos_t3 on t1_k0 =
t3_k0
+ ) tmp0 inner join test_hash_join_probe_early_eos_t0 on t1_k0 =
t0_k0;
+ """
+
+ qt_left_join_join_probe_eos0 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left join test_hash_join_probe_early_eos_t1 on t2_k0 = t1_k0
+ """
+ qt_left_join_join_probe_eos1 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t0
+ left join (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left join test_hash_join_probe_early_eos_t1 on t2_k0 =
t1_k0
+ ) tmp0 on t0_k0 = t1_k0
+ order by t0_k0;
+ """
+ qt_left_join_join_probe_eos2 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left join test_hash_join_probe_early_eos_t1 on t2_k0 =
t1_k0
+ ) tmp0 left join test_hash_join_probe_early_eos_t0 on t1_k0 =
t0_k0;
+ """
+ qt_left_join_join_probe_eos3 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t1
+ inner join test_hash_join_probe_early_eos_t3 on t1_k0 =
t3_k0
+ ) tmp0 left join test_hash_join_probe_early_eos_t0 on t1_k0 =
t0_k0;
+
+ """
+
+ qt_left_semi_join_join_probe_eos0 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left semi join test_hash_join_probe_early_eos_t1 on t2_k0 = t1_k0
+ """
+ qt_left_semi_join_join_probe_eos1 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t0
+ left semi join (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left semi join test_hash_join_probe_early_eos_t1 on t2_k0
= t1_k0
+ ) tmp0 on t0_k0 = t2_k0;
+ """
+ qt_left_semi_join_join_probe_eos2 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left semi join test_hash_join_probe_early_eos_t1 on t2_k0
= t1_k0
+ ) tmp0 left semi join test_hash_join_probe_early_eos_t0 on t2_k0 =
t0_k0;
+ """
+
+ qt_left_anti_join_join_probe_eos0 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left anti join test_hash_join_probe_early_eos_t1 on t2_k0 = t1_k0
+ """
+ qt_left_anti_join_join_probe_eos1 """
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t0
+ left anti join (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left anti join test_hash_join_probe_early_eos_t1 on t2_k0
= t1_k0
+ ) tmp0 on t0_k0 = t2_k0
+ order by t0_k0;
+ """
+ qt_left_anti_join_join_probe_eos2 """
+ select
+ *
+ from
+ (
+ select
+ *
+ from
+ test_hash_join_probe_early_eos_t2
+ left anti join test_hash_join_probe_early_eos_t1 on t2_k0
= t1_k0
+ ) tmp0 left anti join test_hash_join_probe_early_eos_t0 on t2_k0 =
t0_k0;
+ """
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]