This is an automated email from the ASF dual-hosted git repository.

BiteTheDDDDt 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 d232caa5330 [fix](be) Preserve agg hash shuffle after non-hash 
exchange (#63766)
d232caa5330 is described below

commit d232caa533054d0234d677f5aa891c5c9ca6de97
Author: Pxl <[email protected]>
AuthorDate: Thu May 28 21:04:33 2026 +0800

    [fix](be) Preserve agg hash shuffle after non-hash exchange (#63766)
    
    Related PR: #63529, #62438
    
    Problem Summary: `enable_local_exchange_before_agg=false` allows
    first-phase aggregation to skip the local hash exchange before agg for
    performance. This is only correct when the input still preserves local
    key distribution.
    
    After #62438, nested loop join and other operators may introduce
    non-hash local exchanges such as `ADAPTIVE_PASSTHROUGH`. Those exchanges
    can split rows with the same group/distinct key across local pipeline
    tasks. If agg still skips the hash local exchange, partial aggregation
    states for the same key are built in different tasks and later
    `COUNT(DISTINCT ...)` can over-count. The reproduced query in
    `output/ddl.txt` returned wrong counts such as `18/20` instead of `10`.
    
    This PR preserves correctness while keeping the knob usable:
    
    - Aggregation operators now skip local exchange with
    `enable_local_exchange_before_agg=false` only when the child preserves
    local key distribution.
    - The shared child-distribution check is reused by `AggSinkOperatorX`,
    `StreamingAggOperatorX`, and `DistinctStreamingAggOperatorX`.
    - `Pipeline::need_to_local_exchange()` also handles the case where the
    current pipeline source is a non-hash `LocalExchangeSource` but the
    downstream target requires hash distribution, so inherited hash-ish
    pipeline state cannot incorrectly suppress the required local exchange.
    - Regression coverage is added for the nested-loop-join + distinct
    aggregation wrong-result case, and unit tests cover the agg distribution
    decisions.
---
 .../exec/exchange/local_exchange_source_operator.h |   5 +
 be/src/exec/operator/aggregation_sink_operator.h   |   3 +-
 .../distinct_streaming_aggregation_operator.h      |   4 +-
 be/src/exec/operator/operator.cpp                  |  17 +++
 be/src/exec/operator/operator.h                    |   3 +
 .../exec/operator/streaming_aggregation_operator.h |   7 +-
 be/src/exec/pipeline/pipeline.cpp                  |  10 +-
 be/test/exec/operator/agg_operator_test.cpp        |  57 +++++++++
 ...istinct_streaming_aggregation_operator_test.cpp |  15 +++
 .../exec/operator/streaming_agg_operator_test.cpp  |  14 +++
 ...t_agg_after_nested_loop_join_local_exchange.out |   3 +
 ...gg_after_nested_loop_join_local_exchange.groovy | 130 +++++++++++++++++++++
 12 files changed, 262 insertions(+), 6 deletions(-)

diff --git a/be/src/exec/exchange/local_exchange_source_operator.h 
b/be/src/exec/exchange/local_exchange_source_operator.h
index 58252b24ec2..3fdf90b50f0 100644
--- a/be/src/exec/exchange/local_exchange_source_operator.h
+++ b/be/src/exec/exchange/local_exchange_source_operator.h
@@ -82,6 +82,11 @@ public:
 
     bool is_source() const override { return true; }
 
+    DataDistribution required_data_distribution(RuntimeState* /*state*/) const 
override {
+        return {_exchange_type};
+    }
+    ExchangeType exchange_type() const { return _exchange_type; }
+
 private:
     friend class LocalExchangeSourceLocalState;
 
diff --git a/be/src/exec/operator/aggregation_sink_operator.h 
b/be/src/exec/operator/aggregation_sink_operator.h
index 605bb62a1dd..8d3273dde2a 100644
--- a/be/src/exec/operator/aggregation_sink_operator.h
+++ b/be/src/exec/operator/aggregation_sink_operator.h
@@ -163,8 +163,9 @@ public:
                            : 
DataSinkOperatorX<AggSinkLocalState>::required_data_distribution(
                                      state);
         }
+        const bool child_breaks_distribution = 
child_breaks_local_key_distribution(state);
         if (!_needs_finalize && !state->enable_local_exchange_before_agg() &&
-            !(_is_merge && _child && _child->is_serial_operator())) {
+            !child_breaks_distribution) {
             return 
DataSinkOperatorX<AggSinkLocalState>::required_data_distribution(state);
         }
         return _is_colocate && _require_bucket_distribution
diff --git a/be/src/exec/operator/distinct_streaming_aggregation_operator.h 
b/be/src/exec/operator/distinct_streaming_aggregation_operator.h
index abf42eb50cc..4ae652d498c 100644
--- a/be/src/exec/operator/distinct_streaming_aggregation_operator.h
+++ b/be/src/exec/operator/distinct_streaming_aggregation_operator.h
@@ -118,7 +118,8 @@ public:
         if (_needs_finalize && _probe_expr_ctxs.empty()) {
             return {ExchangeType::NOOP};
         }
-        if (!_needs_finalize && !state->enable_local_exchange_before_agg()) {
+        if (!_needs_finalize && !state->enable_local_exchange_before_agg() &&
+            !child_breaks_local_key_distribution(state)) {
             return 
StatefulOperatorX<DistinctStreamingAggLocalState>::required_data_distribution(
                     state);
         }
@@ -142,6 +143,7 @@ public:
 
 private:
     friend class DistinctStreamingAggLocalState;
+
     void init_make_nullable(RuntimeState* state);
     TupleId _output_tuple_id;
     TupleDescriptor* _output_tuple_desc = nullptr;
diff --git a/be/src/exec/operator/operator.cpp 
b/be/src/exec/operator/operator.cpp
index d03f75306d5..1ce7dc8727d 100644
--- a/be/src/exec/operator/operator.cpp
+++ b/be/src/exec/operator/operator.cpp
@@ -147,6 +147,23 @@ DataDistribution 
OperatorBase::required_data_distribution(RuntimeState* /*state*
                    : DataDistribution(ExchangeType::NOOP);
 }
 
+bool OperatorBase::is_hash_shuffle(ExchangeType exchange_type) {
+    return exchange_type == ExchangeType::HASH_SHUFFLE ||
+           exchange_type == ExchangeType::BUCKET_HASH_SHUFFLE;
+}
+
+bool OperatorBase::child_breaks_local_key_distribution(RuntimeState* state) 
const {
+    if (!_child) {
+        return false;
+    }
+    if (_child->is_serial_operator()) {
+        return true;
+    }
+    const auto child_distribution = _child->required_data_distribution(state);
+    return child_distribution.need_local_exchange() &&
+           !is_hash_shuffle(child_distribution.distribution_type);
+}
+
 const RowDescriptor& OperatorBase::row_desc() const {
     return _child->row_desc();
 }
diff --git a/be/src/exec/operator/operator.h b/be/src/exec/operator/operator.h
index d4b09a4aed3..ce5df951e22 100644
--- a/be/src/exec/operator/operator.h
+++ b/be/src/exec/operator/operator.h
@@ -187,6 +187,9 @@ public:
             RuntimeState* /*state*/) const;
 
 protected:
+    [[nodiscard]] static bool is_hash_shuffle(ExchangeType exchange_type);
+    [[nodiscard]] bool child_breaks_local_key_distribution(RuntimeState* 
state) const;
+
     OperatorPtr _child = nullptr;
 
     bool _is_closed;
diff --git a/be/src/exec/operator/streaming_aggregation_operator.h 
b/be/src/exec/operator/streaming_aggregation_operator.h
index 40a8de28244..007da418865 100644
--- a/be/src/exec/operator/streaming_aggregation_operator.h
+++ b/be/src/exec/operator/streaming_aggregation_operator.h
@@ -224,9 +224,10 @@ public:
     DataDistribution required_data_distribution(RuntimeState* state) const 
override {
         if (_child && _child->is_hash_join_probe() &&
             state->enable_streaming_agg_hash_join_force_passthrough()) {
-            return DataDistribution(ExchangeType::PASSTHROUGH);
+            return {ExchangeType::PASSTHROUGH};
         }
-        if (!_needs_finalize && !state->enable_local_exchange_before_agg()) {
+        if (!_needs_finalize && !state->enable_local_exchange_before_agg() &&
+            !child_breaks_local_key_distribution(state)) {
             return 
StatefulOperatorX<StreamingAggLocalState>::required_data_distribution(state);
         }
         if (_partition_exprs.empty()) {
@@ -235,7 +236,7 @@ public:
                            : 
StatefulOperatorX<StreamingAggLocalState>::required_data_distribution(
                                      state);
         }
-        return DataDistribution(ExchangeType::HASH_SHUFFLE, _partition_exprs);
+        return {ExchangeType::HASH_SHUFFLE, _partition_exprs};
     }
 
 private:
diff --git a/be/src/exec/pipeline/pipeline.cpp 
b/be/src/exec/pipeline/pipeline.cpp
index de3c852ada1..60c395e447f 100644
--- a/be/src/exec/pipeline/pipeline.cpp
+++ b/be/src/exec/pipeline/pipeline.cpp
@@ -21,6 +21,7 @@
 #include <string>
 #include <utility>
 
+#include "exec/exchange/local_exchange_source_operator.h"
 #include "exec/operator/operator.h"
 #include "exec/pipeline/pipeline_fragment_context.h"
 #include "exec/pipeline/pipeline_task.h"
@@ -53,7 +54,14 @@ bool Pipeline::need_to_local_exchange(const DataDistribution 
target_data_distrib
         // If non-serial operators exist, we should improve parallelism for 
those.
         return true;
     }
-
+    if (auto local_exchange_source =
+                
std::dynamic_pointer_cast<LocalExchangeSourceOperatorX>(_operators.front());
+        local_exchange_source && 
is_hash_exchange(target_data_distribution.distribution_type)) {
+        const auto source_exchange_type = 
local_exchange_source->exchange_type();
+        if (source_exchange_type != ExchangeType::NOOP && 
!is_hash_exchange(source_exchange_type)) {
+            return true;
+        }
+    }
     if (target_data_distribution.distribution_type != 
ExchangeType::BUCKET_HASH_SHUFFLE &&
         target_data_distribution.distribution_type != 
ExchangeType::HASH_SHUFFLE) {
         // Always do local exchange if non-hash-partition exchanger is 
required.
diff --git a/be/test/exec/operator/agg_operator_test.cpp 
b/be/test/exec/operator/agg_operator_test.cpp
index 75592bfa097..02b6a79bb72 100644
--- a/be/test/exec/operator/agg_operator_test.cpp
+++ b/be/test/exec/operator/agg_operator_test.cpp
@@ -22,12 +22,14 @@
 
 #include "core/data_type/data_type_nullable.h"
 #include "core/data_type/data_type_number.h"
+#include "exec/exchange/local_exchange_source_operator.h"
 #include "exec/operator/aggregation_sink_operator.h"
 #include "exec/operator/aggregation_source_operator.h"
 #include "exec/operator/assert_num_rows_operator.h"
 #include "exec/operator/mock_operator.h"
 #include "exec/operator/operator_helper.h"
 #include "exec/pipeline/dependency.h"
+#include "exec/pipeline/pipeline.h"
 #include "testutil/column_helper.h"
 #include "testutil/mock/mock_agg_fn_evaluator.h"
 #include "testutil/mock/mock_slot_ref.h"
@@ -98,6 +100,23 @@ struct MockAggSourceOperator : public AggSourceOperatorX {
     std::unique_ptr<RowDescriptor> mock_row_descriptor;
 };
 
+class MockDistributionOperator final : public OperatorX<MockLocalState> {
+public:
+    MockDistributionOperator(ExchangeType exchange_type) : 
_exchange_type(exchange_type) {}
+
+    Status get_block(RuntimeState* /*state*/, Block* /*block*/, bool* eos) 
override {
+        *eos = true;
+        return Status::OK();
+    }
+
+    DataDistribution required_data_distribution(RuntimeState* /*state*/) const 
override {
+        return {_exchange_type};
+    }
+
+private:
+    ExchangeType _exchange_type;
+};
+
 std::shared_ptr<AggSinkOperatorX> create_agg_sink_op(OperatorContext& ctx, 
bool is_merge,
                                                      bool without_key) {
     auto op = std::make_shared<MockAggsinkOperator>();
@@ -108,6 +127,44 @@ std::shared_ptr<AggSinkOperatorX> 
create_agg_sink_op(OperatorContext& ctx, bool
     return op;
 }
 
+TEST(AggOperatorRequiredDistributionTest, 
require_hash_shuffle_after_non_hash_child_exchange) {
+    OperatorContext ctx;
+    auto sink_op = std::make_shared<MockAggsinkOperator>();
+    sink_op->_partition_exprs.emplace_back();
+    sink_op->_needs_finalize = false;
+    OperatorPtr child =
+            
std::make_shared<MockDistributionOperator>(ExchangeType::ADAPTIVE_PASSTHROUGH);
+    sink_op->_child = child;
+
+    const auto distribution = sink_op->required_data_distribution(&ctx.state);
+    EXPECT_EQ(ExchangeType::HASH_SHUFFLE, distribution.distribution_type);
+}
+
+TEST(AggOperatorRequiredDistributionTest, 
require_hash_shuffle_after_non_hash_local_exchange) {
+    OperatorContext ctx;
+    auto sink_op = std::make_shared<MockAggsinkOperator>();
+    sink_op->_needs_finalize = false;
+    OperatorPtr child = std::make_shared<LocalExchangeSourceOperatorX>();
+    EXPECT_TRUE(child->init(ExchangeType::ADAPTIVE_PASSTHROUGH).ok());
+    sink_op->_child = child;
+
+    TExpr distinct_agg_expr;
+    distinct_agg_expr.nodes.emplace_back();
+    distinct_agg_expr.nodes[0].fn.name.function_name = "multi_distinct_count";
+    TPlanNode tnode;
+    tnode.agg_node.aggregate_functions.push_back(distinct_agg_expr);
+    tnode.__set_distribute_expr_lists({{TExpr {}}});
+    sink_op->update_operator(tnode, false, false);
+
+    const auto distribution = sink_op->required_data_distribution(&ctx.state);
+    EXPECT_EQ(ExchangeType::HASH_SHUFFLE, distribution.distribution_type);
+
+    Pipeline pipeline(0, 4, 4);
+    EXPECT_TRUE(pipeline.add_operator(child, 0).ok());
+    
pipeline.set_data_distribution(DataDistribution(ExchangeType::HASH_SHUFFLE));
+    EXPECT_TRUE(pipeline.need_to_local_exchange(distribution, 1));
+}
+
 std::shared_ptr<AggSourceOperatorX> create_agg_source_op(OperatorContext& ctx, 
bool without_key,
                                                          bool needs_finalize) {
     auto op = std::make_shared<MockAggSourceOperator>();
diff --git 
a/be/test/exec/operator/distinct_streaming_aggregation_operator_test.cpp 
b/be/test/exec/operator/distinct_streaming_aggregation_operator_test.cpp
index 88434e47fd7..17282356625 100644
--- a/be/test/exec/operator/distinct_streaming_aggregation_operator_test.cpp
+++ b/be/test/exec/operator/distinct_streaming_aggregation_operator_test.cpp
@@ -22,6 +22,7 @@
 #include <memory>
 
 #include "core/block/block.h"
+#include "exec/exchange/local_exchange_source_operator.h"
 #include "exec/operator/mock_operator.h"
 #include "exec/operator/operator_helper.h"
 #include "testutil/column_helper.h"
@@ -97,6 +98,20 @@ TEST_F(DistinctStreamingAggOperatorTest, test1) {
     }
 }
 
+TEST_F(DistinctStreamingAggOperatorTest, 
require_hash_shuffle_after_non_hash_local_exchange) {
+    state->_query_options.__set_enable_local_exchange_before_agg(false);
+    op->_is_streaming_preagg = false;
+    op->_partition_exprs.emplace_back();
+    op->_probe_expr_ctxs = MockSlotRef::create_mock_contexts(0, 
std::make_shared<DataTypeInt64>());
+
+    OperatorPtr child = std::make_shared<LocalExchangeSourceOperatorX>();
+    EXPECT_TRUE(child->init(ExchangeType::ADAPTIVE_PASSTHROUGH).ok());
+    op->_child = child;
+
+    const auto distribution = op->required_data_distribution(state.get());
+    EXPECT_EQ(ExchangeType::HASH_SHUFFLE, distribution.distribution_type);
+}
+
 TEST_F(DistinctStreamingAggOperatorTest, test2) {
     op->_is_streaming_preagg = false;
     op->_limit = 3;
diff --git a/be/test/exec/operator/streaming_agg_operator_test.cpp 
b/be/test/exec/operator/streaming_agg_operator_test.cpp
index 0421d58bfd2..bbe54ebec5d 100644
--- a/be/test/exec/operator/streaming_agg_operator_test.cpp
+++ b/be/test/exec/operator/streaming_agg_operator_test.cpp
@@ -23,6 +23,7 @@
 #include "core/data_type/data_type_bitmap.h"
 #include "core/data_type/data_type_number.h"
 #include "core/value/bitmap_value.h"
+#include "exec/exchange/local_exchange_source_operator.h"
 #include "exec/operator/aggregation_sink_operator.h"
 #include "exec/operator/aggregation_source_operator.h"
 #include "exec/operator/mock_operator.h"
@@ -152,6 +153,19 @@ TEST_F(StreamingAggOperatorTest, test1) {
     { EXPECT_TRUE(local_state->close(state.get()).ok()); }
 }
 
+TEST_F(StreamingAggOperatorTest, 
require_hash_shuffle_after_non_hash_local_exchange) {
+    state->_query_options.__set_enable_local_exchange_before_agg(false);
+    op->_needs_finalize = false;
+    op->_partition_exprs.emplace_back();
+
+    OperatorPtr child = std::make_shared<LocalExchangeSourceOperatorX>();
+    EXPECT_TRUE(child->init(ExchangeType::ADAPTIVE_PASSTHROUGH).ok());
+    EXPECT_TRUE(op->set_child(child));
+
+    const auto distribution = op->required_data_distribution(state.get());
+    EXPECT_EQ(ExchangeType::HASH_SHUFFLE, distribution.distribution_type);
+}
+
 TEST_F(StreamingAggOperatorTest, test2) {
     op->_aggregate_evaluators.push_back(create_mock_agg_fn_evaluator(
             pool, MockSlotRef::create_mock_contexts(1, 
std::make_shared<DataTypeInt64>()), false,
diff --git 
a/regression-test/data/query_p0/join/test_agg_after_nested_loop_join_local_exchange.out
 
b/regression-test/data/query_p0/join/test_agg_after_nested_loop_join_local_exchange.out
new file mode 100644
index 00000000000..cd357b13436
--- /dev/null
+++ 
b/regression-test/data/query_p0/join/test_agg_after_nested_loop_join_local_exchange.out
@@ -0,0 +1,3 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !agg_after_nlj_local_exchange --
+10     5070261
diff --git 
a/regression-test/suites/query_p0/join/test_agg_after_nested_loop_join_local_exchange.groovy
 
b/regression-test/suites/query_p0/join/test_agg_after_nested_loop_join_local_exchange.groovy
new file mode 100644
index 00000000000..91889b319c8
--- /dev/null
+++ 
b/regression-test/suites/query_p0/join/test_agg_after_nested_loop_join_local_exchange.groovy
@@ -0,0 +1,130 @@
+// 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_agg_after_nested_loop_join_local_exchange", "query_p0") {
+    sql "DROP TABLE IF EXISTS test_agg_after_nlj_local_exchange_t1"
+    sql "DROP TABLE IF EXISTS test_agg_after_nlj_local_exchange_t2"
+
+    sql """
+        CREATE TABLE test_agg_after_nlj_local_exchange_t1 (
+            col_bigint_undef_signed BIGINT,
+            col_varchar_10__undef_signed VARCHAR(10),
+            col_varchar_64__undef_signed VARCHAR(64),
+            pk INT
+        )
+        ENGINE=OLAP
+        DISTRIBUTED BY HASH(pk) BUCKETS 10
+        PROPERTIES("replication_num" = "1")
+    """
+
+    sql """
+        INSERT INTO test_agg_after_nlj_local_exchange_t1
+        (pk, col_bigint_undef_signed, col_varchar_10__undef_signed, 
col_varchar_64__undef_signed)
+        VALUES
+            (0, -94, 'had', 'y'),
+            (1, 672609, 'k', 'h'),
+            (2, -3766684, 'a', 'p'),
+            (3, 5070261, 'on', 'x'),
+            (4, NULL, 'u', 'at'),
+            (5, -86, 'v', 'c'),
+            (6, 21910, 'how', 'm'),
+            (7, -63, 'that''s', 'go'),
+            (8, -8276281, 's', 'a'),
+            (9, -101, 'w', 'y')
+    """
+
+    sql """
+        CREATE TABLE test_agg_after_nlj_local_exchange_t2 (
+            pk INT,
+            col_varchar_10__undef_signed VARCHAR(10),
+            col_bigint_undef_signed BIGINT,
+            col_varchar_64__undef_signed VARCHAR(64)
+        )
+        ENGINE=OLAP
+        DUPLICATE KEY(pk, col_varchar_10__undef_signed)
+        DISTRIBUTED BY HASH(pk) BUCKETS 10
+        PROPERTIES("replication_num" = "1")
+    """
+
+    sql """
+        INSERT INTO test_agg_after_nlj_local_exchange_t2
+        (pk, col_bigint_undef_signed, col_varchar_10__undef_signed, 
col_varchar_64__undef_signed)
+        VALUES
+            (0, NULL, 'right', 'g'),
+            (1, -486256, 'on', 'on'),
+            (2, -1, 'I''ll', 'at'),
+            (3, 29263, 'h', 'don''t'),
+            (4, 5453, 'a', 's'),
+            (5, -119, 'j', 'can''t'),
+            (6, 89, 'one', 'n'),
+            (7, -7227, 's', 'u'),
+            (8, 94, 'time', 'b'),
+            (9, 1816630, 'yes', 'yes')
+    """
+
+    sql "SYNC"
+
+    sql "SET default_variant_doc_hash_shard_count = 0"
+    sql "SET default_variant_max_subcolumns_count = 4"
+    sql "SET default_variant_sparse_hash_shard_count = 4"
+    sql "SET disable_join_reorder = true"
+    sql "SET disable_streaming_preaggregations = true"
+    sql "SET enable_common_expr_pushdown = false"
+    sql "SET enable_common_expr_pushdown_for_inverted_index = false"
+    sql "SET enable_distinct_streaming_agg_force_passthrough = false"
+    sql "SET enable_function_pushdown = true"
+    sql "SET enable_local_exchange_before_agg = false"
+    sql "SET enable_runtime_filter_partition_prune = false"
+    sql "SET enable_runtime_filter_prune = false"
+    sql "SET enable_strong_consistency_read = true"
+    sql "SET enable_sync_runtime_filter_size = false"
+    sql "SET exchange_multi_blocks_byte_size = 5563624"
+    sql "SET experimental_enable_parallel_scan = false"
+    sql "SET parallel_pipeline_task_num = 4"
+    sql "SET parallel_prepare_threshold = 28"
+    sql "SET query_timeout = 600"
+    sql "SET runtime_filter_type = 'IN,MIN_MAX'"
+    sql "SET runtime_filter_wait_time_ms = 5000"
+    sql "SET topn_opt_limit_threshold = 1000"
+    sql "SET agg_phase = 4"
+
+    order_qt_agg_after_nlj_local_exchange """
+        SELECT
+            COUNT(DISTINCT table1.`pk`) AS field1,
+            MAX(table1.col_bigint_undef_signed) AS field2
+        FROM
+            test_agg_after_nlj_local_exchange_t1 AS table1
+        LEFT OUTER JOIN test_agg_after_nlj_local_exchange_t2 AS table2
+            ON table2.col_varchar_10__undef_signed = 
table2.col_varchar_64__undef_signed
+        LEFT JOIN test_agg_after_nlj_local_exchange_t1 AS table3
+            ON table2.col_varchar_10__undef_signed = 
table2.col_varchar_64__undef_signed
+        WHERE
+            table1.`pk` > 3
+            AND table1.`pk` < (3 + 25)
+            OR table1.col_varchar_64__undef_signed > 'cnvUBxJyCp'
+            AND table1.col_varchar_64__undef_signed <= 'z'
+            OR table1.col_bigint_undef_signed != 2
+            OR table1.`pk` NOT BETWEEN 2 AND (2 + 1)
+            AND table1.`pk` > 7
+            AND table1.`pk` < (7 + 2)
+            AND table1.`pk` IN (2, 10, 2)
+        ORDER BY
+            field1,
+            field2
+        LIMIT 1000
+    """
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to