From 5d7c40632206cc1f8ac4d15503a695200adc95fb Mon Sep 17 00:00:00 2001 From: junwen12221 Date: Thu, 7 Apr 2022 15:02:28 +0800 Subject: [PATCH] fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SELECT * FROM A WHERE aid IN (SELECT DISTINCT aid FROM B )】这样的语句?B是分片表。 aid不是主键 --- .../test/java/io/mycat/sql/UserCaseTest.java | 48 +++++++++++++++ .../rewriter/MycatAggDistinctRule.java | 61 ++++++++++--------- 2 files changed, 79 insertions(+), 30 deletions(-) diff --git a/example/src/test/java/io/mycat/sql/UserCaseTest.java b/example/src/test/java/io/mycat/sql/UserCaseTest.java index 6cbbc8399..3db26c679 100644 --- a/example/src/test/java/io/mycat/sql/UserCaseTest.java +++ b/example/src/test/java/io/mycat/sql/UserCaseTest.java @@ -1670,4 +1670,52 @@ public void case2022318() throws Exception { System.out.println(); } } + + @Test + public void case20220407() throws Exception { + try (Connection mycatConnection = getMySQLConnection(DB_MYCAT_PSTMT)) { + + + execute(mycatConnection, RESET_CONFIG); + + execute(mycatConnection, "DROP DATABASE db1"); + + + execute(mycatConnection, "CREATE DATABASE db1"); + + execute(mycatConnection, CreateDataSourceHint + .create("ds0", + DB1)); + + execute(mycatConnection, + CreateClusterHint.create("c0", + Arrays.asList("ds0"), Collections.emptyList())); + + JdbcUtils.execute(mycatConnection, "CREATE TABLE db1.`company` (\n" + + " `id` bigint(20) NOT NULL KEY,\n" + + " `user_id` varchar(100) CHARACTER SET utf8 DEFAULT NULL,\n" + + " `traveldate` datetime(6) DEFAULT NULL,\n" + + " `fee` decimal(10,0) DEFAULT NULL,\n" + + " `days` int(11) DEFAULT NULL,\n" + + " `blob` longblob DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4\n"); + + JdbcUtils.execute(mycatConnection, "CREATE TABLE db1.`travelrecord` (\n" + + " `id` bigint(20) NOT NULL KEY,\n" + + " `user_id` varchar(100) CHARACTER SET utf8 DEFAULT NULL,\n" + + " `traveldate` datetime(6) DEFAULT NULL,\n" + + " `fee` decimal(10,0) DEFAULT NULL,\n" + + " `days` int(11) DEFAULT NULL,\n" + + " `blob` longblob DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4\n" + + "dbpartition by mod_hash(user_id) dbpartitions 16;"); + + + List> maps = executeQuery(mycatConnection, "SELECT * FROM\tdb1.company WHERE id IN (SELECT DISTINCT id FROM \tdb1.travelrecord )"); + + List> maps1 = executeQuery(mycatConnection, "SELECT * FROM\tdb1.company WHERE id IN (SELECT DISTINCT fee FROM \tdb1.travelrecord )"); + + System.out.println(); + } + } } diff --git a/hbt/src/main/java/io/mycat/calcite/rewriter/MycatAggDistinctRule.java b/hbt/src/main/java/io/mycat/calcite/rewriter/MycatAggDistinctRule.java index 3c056ff2e..18e35d85a 100644 --- a/hbt/src/main/java/io/mycat/calcite/rewriter/MycatAggDistinctRule.java +++ b/hbt/src/main/java/io/mycat/calcite/rewriter/MycatAggDistinctRule.java @@ -3,6 +3,7 @@ import io.mycat.HintTools; import io.mycat.calcite.localrel.LocalAggregate; import io.mycat.calcite.logical.MycatView; +import io.mycat.datasource.jdbc.datasource.JdbcConnectionManager; import org.apache.calcite.plan.RelOptRuleCall; import org.apache.calcite.plan.RelOptUtil; import org.apache.calcite.plan.RelRule; @@ -14,6 +15,8 @@ import org.apache.calcite.rex.RexInputRef; import org.apache.calcite.sql.SqlKind; import org.apache.calcite.tools.RelBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; import java.util.function.Consumer; @@ -22,6 +25,7 @@ import static io.mycat.calcite.localrel.LocalRules.normalize; public class MycatAggDistinctRule extends RelRule { + private static final Logger LOGGER = LoggerFactory.getLogger(MycatAggDistinctRule.class); /** * Creates a RelRule. * @@ -33,42 +37,39 @@ public MycatAggDistinctRule(Config config) { @Override public void onMatch(RelOptRuleCall call) { - Aggregate topAggregate = call.rel(0); - MycatView mycatView = call.rel(2); - RelHint lastAggHint = HintTools.getLastPushAggHint(topAggregate.getHints()); - if (lastAggHint != null) { - if ("push_down_agg_distinct".equalsIgnoreCase(lastAggHint.hintName)) { + try { + Aggregate topAggregate = call.rel(0); + MycatView mycatView = call.rel(2); + RelHint lastAggHint = HintTools.getLastPushAggHint(topAggregate.getHints()); + if (lastAggHint != null) { + if ("push_down_agg_distinct".equalsIgnoreCase(lastAggHint.hintName)) { - if (topAggregate.getAggCallList().size() == 1 && topAggregate.getGroupSet().isEmpty()) { - List aggCallList = topAggregate.getAggCallList(); - if (aggCallList.size() == 1) { - AggregateCall aggregateCall = aggCallList.get(0); - if (aggregateCall.getAggregation().kind == SqlKind.COUNT) { - Aggregate distinctAgg = call.rel(1); - if (distinctAgg.getAggCallList().isEmpty() && !distinctAgg.getGroupSet().isEmpty()) { - opt(call, topAggregate, mycatView); - return; + if (topAggregate.getAggCallList().size() == 1 && topAggregate.getGroupSet().isEmpty()) { + List aggCallList = topAggregate.getAggCallList(); + if (aggCallList.size() == 1) { + AggregateCall aggregateCall = aggCallList.get(0); + if (aggregateCall.getAggregation().kind == SqlKind.COUNT) { + Aggregate distinctAgg = call.rel(1); + if (distinctAgg.getAggCallList().isEmpty() && !distinctAgg.getGroupSet().isEmpty()) { + opt(call, topAggregate, mycatView); + return; + } } } } + Aggregate aggregate = topAggregate; + MycatView input = mycatView; + SQLRBORewriter.aggregate(input, LocalAggregate.create(aggregate, input)).ifPresent(new Consumer() { + @Override + public void accept(RelNode res) { + call.transformTo(normalize(res)); + } + }); + return; } - Aggregate aggregate = topAggregate; - MycatView input = mycatView; - SQLRBORewriter.aggregate(input, LocalAggregate.create(aggregate, input)).ifPresent(new Consumer() { - @Override - public void accept(RelNode res) { - call.transformTo(normalize(res)); - } - }); - return; - } - } - if (topAggregate.getAggCallList().isEmpty() && topAggregate.getGroupSets().size() == 1) { - RelMetadataQuery metadataQuery = call.getMetadataQuery(); - if (metadataQuery.areColumnsUnique(mycatView, topAggregate.getGroupSet())) { - opt(call, topAggregate, mycatView); - return; } + }catch (Throwable throwable){ + LOGGER.debug("MycatAggDistinctRule occurs exception",throwable); } }