Created
March 29, 2021 08:40
-
-
Save junwen12221/61b0b18dfff1024e9ae3d68e465bc8c2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import io.mycat.DataNode; | |
import io.mycat.calcite.table.ShardingTable; | |
import io.mycat.router.CustomRuleFunction; | |
import org.apache.calcite.rex.RexDynamicParam; | |
import org.apache.calcite.rex.RexLiteral; | |
import org.apache.calcite.rex.RexNode; | |
import java.util.Collections; | |
import java.util.List; | |
public interface ConditionHandler { | |
List<DataNode> handle(ShardingTable shardingTable, Object[] params); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
public class DataNodeMapping { | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import com.alibaba.druid.sql.SQLUtils; | |
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; | |
import io.mycat.*; | |
import io.mycat.assemble.MycatTest; | |
import io.mycat.calcite.resultset.CalciteRowMetaData; | |
import io.mycat.calcite.spm.Plan; | |
import io.mycat.calcite.spm.PlanCache; | |
import io.mycat.calcite.table.SchemaHandler; | |
import io.mycat.config.*; | |
import io.mycat.datasource.jdbc.datasource.JdbcConnectionManager; | |
import io.mycat.hint.CreateClusterHint; | |
import io.mycat.hint.CreateDataSourceHint; | |
import io.mycat.hint.CreateSchemaHint; | |
import io.mycat.plug.loadBalance.LoadBalanceManager; | |
import io.mycat.plug.sequence.SequenceGenerator; | |
import io.mycat.replica.ReplicaSelectorRuntime; | |
import io.mycat.runtime.MycatDataContextImpl; | |
import io.mycat.sqlhandler.ConfigUpdater; | |
import io.mycat.util.JsonUtil; | |
import io.mycat.util.NameMap; | |
import jdk.nashorn.internal.objects.annotations.Getter; | |
import lombok.AllArgsConstructor; | |
import lombok.SneakyThrows; | |
import org.apache.calcite.plan.RelOptUtil; | |
import org.apache.calcite.rel.RelNode; | |
import org.apache.calcite.sql.SqlExplainFormat; | |
import org.apache.calcite.sql.SqlExplainLevel; | |
import org.apache.calcite.util.Util; | |
import org.junit.Before; | |
import javax.annotation.concurrent.NotThreadSafe; | |
import java.io.IOException; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.StandardOpenOption; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import java.util.List; | |
import java.util.Map; | |
public abstract class DrdsTest implements MycatTest { | |
static DrdsRunner drdsRunner = null; | |
@SneakyThrows | |
public static DrdsRunner getDrds() { | |
if (drdsRunner != null) { | |
return drdsRunner; | |
} | |
synchronized (DrdsTest.class) { | |
if (drdsRunner == null) { | |
MycatCore mycatCore = new MycatCore(); | |
FileMetadataStorageManager fileMetadataStorageManager = MetaClusterCurrent.wrapper(FileMetadataStorageManager.class); | |
MycatRouterConfig mycatRouterConfig = new MycatRouterConfig(); | |
LogicSchemaConfig logicSchemaConfig = new LogicSchemaConfig(); | |
mycatRouterConfig.getSchemas().add(logicSchemaConfig); | |
logicSchemaConfig.setSchemaName("db1"); | |
NormalTableConfig mainNormalTableConfig = new NormalTableConfig(); | |
mainNormalTableConfig.setCreateTableSQL("CREATE TABLE `normal` (\n" + | |
" `id` int(11) NOT NULL,\n" + | |
" `addressname` varchar(20) DEFAULT NULL,\n" + | |
" PRIMARY KEY (`id`)\n" + | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n"); | |
NormalBackEndTableInfoConfig normalBackEndTableInfoConfig = new NormalBackEndTableInfoConfig(); | |
normalBackEndTableInfoConfig.setTargetName("prototype"); | |
normalBackEndTableInfoConfig.setSchemaName("db1"); | |
normalBackEndTableInfoConfig.setTableName("normal"); | |
mainNormalTableConfig.setDataNode(normalBackEndTableInfoConfig); | |
logicSchemaConfig.getNormalTables().put("normal", mainNormalTableConfig); | |
NormalTableConfig orherNormalTableConfig = new NormalTableConfig(); | |
orherNormalTableConfig.setCreateTableSQL("CREATE TABLE `normal2` (\n" + | |
" `id` int(11) NOT NULL,\n" + | |
" `addressname` varchar(20) DEFAULT NULL,\n" + | |
" PRIMARY KEY (`id`)\n" + | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n"); | |
NormalBackEndTableInfoConfig otherNormalBackEndTableInfoConfig = new NormalBackEndTableInfoConfig(); | |
otherNormalBackEndTableInfoConfig.setTargetName("prototype"); | |
otherNormalBackEndTableInfoConfig.setSchemaName("db1"); | |
otherNormalBackEndTableInfoConfig.setTableName("normal2"); | |
orherNormalTableConfig.setDataNode(otherNormalBackEndTableInfoConfig); | |
logicSchemaConfig.getNormalTables().put("normal2", orherNormalTableConfig); | |
GlobalTableConfig globalTableConfig = new GlobalTableConfig(); | |
globalTableConfig.getDataNodes().add( | |
GlobalBackEndTableInfoConfig.builder().targetName("c0").build() | |
); | |
globalTableConfig.getDataNodes().add( | |
GlobalBackEndTableInfoConfig.builder().targetName("c1").build() | |
); | |
globalTableConfig.setCreateTableSQL("CREATE TABLE `global` (\n" + | |
" `id` int(11) NOT NULL AUTO_INCREMENT,\n" + | |
" `companyname` varchar(20) DEFAULT NULL,\n" + | |
" `addressid` int(11) DEFAULT NULL,\n" + | |
" PRIMARY KEY (`id`)\n" + | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 broadcast; "); | |
logicSchemaConfig.getGlobalTables().put("global", globalTableConfig); | |
ShardingTableConfig mainSharding = new ShardingTableConfig(); | |
mainSharding.setCreateTableSQL("CREATE TABLE db1.`sharding` (\n" + | |
" `id` bigint NOT NULL AUTO_INCREMENT,\n" + | |
" `user_id` varchar(100) DEFAULT NULL,\n" + | |
" `traveldate` date DEFAULT NULL,\n" + | |
" `fee` decimal(10,0) DEFAULT NULL,\n" + | |
" `days` int DEFAULT NULL,\n" + | |
" `blob` longblob,\n" + | |
" PRIMARY KEY (`id`),\n" + | |
" KEY `id` (`id`)\n" + | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8" | |
+ " dbpartition by hash(id) tbpartition by hash(id) tbpartitions 2 dbpartitions 2;"); | |
mainSharding.setFunction(ShardingFuntion.builder().properties(JsonUtil.from("{\n" + | |
"\t\t\t\t\t\"dbNum\":\"2\",\n" + | |
"\t\t\t\t\t\"mappingFormat\":\"c${targetIndex}/db1_${dbIndex}/sharding_${tableIndex}\",\n" + | |
"\t\t\t\t\t\"tableNum\":\"2\",\n" + | |
"\t\t\t\t\t\"tableMethod\":\"hash(id)\",\n" + | |
"\t\t\t\t\t\"storeNum\":2,\n" + | |
"\t\t\t\t\t\"dbMethod\":\"hash(id)\"\n" + | |
"\t\t\t\t}", Map.class)).build()); | |
logicSchemaConfig.getShadingTables().put("sharding", mainSharding); | |
ShardingTableConfig er = new ShardingTableConfig(); | |
er.setCreateTableSQL("CREATE TABLE db1.`er` (\n" + | |
" `id` bigint NOT NULL AUTO_INCREMENT,\n" + | |
" `user_id` varchar(100) DEFAULT NULL,\n" + | |
" `traveldate` date DEFAULT NULL,\n" + | |
" `fee` decimal(10,0) DEFAULT NULL,\n" + | |
" `days` int DEFAULT NULL,\n" + | |
" `blob` longblob,\n" + | |
" PRIMARY KEY (`id`),\n" + | |
" KEY `id` (`id`)\n" + | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8" | |
+ " dbpartition by hash(id) tbpartition by hash(id) tbpartitions 2 dbpartitions 2;"); | |
er.setFunction(ShardingFuntion.builder().properties(JsonUtil.from("{\n" + | |
"\t\t\t\t\t\"dbNum\":\"2\",\n" + | |
"\t\t\t\t\t\"mappingFormat\":\"c${targetIndex}/db1_${dbIndex}/er_${tableIndex}\",\n" + | |
"\t\t\t\t\t\"tableNum\":\"2\",\n" + | |
"\t\t\t\t\t\"tableMethod\":\"hash(id)\",\n" + | |
"\t\t\t\t\t\"storeNum\":2,\n" + | |
"\t\t\t\t\t\"dbMethod\":\"hash(id)\"\n" + | |
"\t\t\t\t}", Map.class)).build()); | |
logicSchemaConfig.getShadingTables().put("er", er); | |
ShardingTableConfig other_sharding = new ShardingTableConfig(); | |
other_sharding.setCreateTableSQL("CREATE TABLE db1.`other_sharding` (\n" + | |
" `id` bigint NOT NULL AUTO_INCREMENT,\n" + | |
" `user_id` varchar(100) DEFAULT NULL,\n" + | |
" `traveldate` date DEFAULT NULL,\n" + | |
" `fee` decimal(10,0) DEFAULT NULL,\n" + | |
" `days` int DEFAULT NULL,\n" + | |
" `blob` longblob,\n" + | |
" PRIMARY KEY (`id`),\n" + | |
" KEY `id` (`id`)\n" + | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8" | |
+ " dbpartition by mod_hash(id) tbpartition by hash(id) tbpartitions 2 dbpartitions 2;"); | |
other_sharding.setFunction(ShardingFuntion.builder().properties(JsonUtil.from("{\n" + | |
"\t\t\t\t\t\"dbNum\":\"2\",\n" + | |
"\t\t\t\t\t\"mappingFormat\":\"c${targetIndex}/db1_${dbIndex}/other_sharding_${tableIndex}\",\n" + | |
"\t\t\t\t\t\"tableNum\":\"2\",\n" + | |
"\t\t\t\t\t\"tableMethod\":\"UNI_HASH(id)\",\n" + | |
"\t\t\t\t\t\"storeNum\":2,\n" + | |
"\t\t\t\t\t\"dbMethod\":\"hash(id)\"\n" + | |
"\t\t\t\t}", Map.class)).build()); | |
logicSchemaConfig.getShadingTables().put("other_sharding", other_sharding); | |
mycatRouterConfig.getClusters().add(CreateClusterHint.createConfig("c0", Arrays.asList("ds0"), Collections.emptyList())); | |
mycatRouterConfig.getClusters().add(CreateClusterHint.createConfig("c1", Arrays.asList("ds1"), Collections.emptyList())); | |
{ | |
NormalTableConfig orherTargetNormalTableConfig = new NormalTableConfig(); | |
orherTargetNormalTableConfig.setCreateTableSQL("CREATE TABLE `normal3` (\n" + | |
" `id` int(11) NOT NULL,\n" + | |
" `addressname` varchar(20) DEFAULT NULL,\n" + | |
" PRIMARY KEY (`id`)\n" + | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n"); | |
NormalBackEndTableInfoConfig otherTargetNormalBackEndTableInfoConfig = new NormalBackEndTableInfoConfig(); | |
otherTargetNormalBackEndTableInfoConfig.setTargetName("ds1"); | |
otherTargetNormalBackEndTableInfoConfig.setSchemaName("db1"); | |
otherTargetNormalBackEndTableInfoConfig.setTableName("normal3"); | |
orherTargetNormalTableConfig.setDataNode(otherTargetNormalBackEndTableInfoConfig); | |
logicSchemaConfig.getNormalTables().put("normal3", orherTargetNormalTableConfig); | |
} | |
mycatRouterConfig.getDatasources().add(CreateDataSourceHint.createConfig("ds0", DB1)); | |
mycatRouterConfig.getDatasources().add(CreateDataSourceHint.createConfig("ds1", DB2)); | |
mycatRouterConfig.getDatasources().add(CreateDataSourceHint.createConfig("prototype", DB1)); | |
fileMetadataStorageManager.start(mycatRouterConfig); | |
drdsRunner = MetaClusterCurrent.wrapper(DrdsRunner.class); | |
} | |
} | |
return drdsRunner; | |
} | |
public static Explain parse(String sql) { | |
DrdsRunner drds = getDrds(); | |
DrdsSql drdsSql = drds.preParse(sql); | |
MycatDataContextImpl mycatDataContext = new MycatDataContextImpl(); | |
Plan plan = drds.getPlan(mycatDataContext, drdsSql); | |
return new Explain(plan,drdsSql); | |
} | |
public static String dumpPlan(RelNode relNode) { | |
String dumpPlan = Util.toLinux(RelOptUtil.dumpPlan("", relNode, SqlExplainFormat.TEXT, | |
SqlExplainLevel.EXPPLAN_ATTRIBUTES)); | |
System.out.println(dumpPlan); | |
return dumpPlan; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import io.mycat.DrdsSql; | |
import io.mycat.calcite.spm.Plan; | |
import io.mycat.calcite.spm.SpecificSql; | |
import lombok.AllArgsConstructor; | |
import lombok.Getter; | |
import org.apache.calcite.plan.RelOptUtil; | |
import org.apache.calcite.rel.RelNode; | |
import org.apache.calcite.sql.SqlExplainFormat; | |
import org.apache.calcite.sql.SqlExplainLevel; | |
import org.apache.calcite.util.Util; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.IdentityHashMap; | |
import java.util.List; | |
import java.util.stream.Collectors; | |
@Getter | |
public class Explain { | |
private Plan plan; | |
private DrdsSql drdsSql; | |
public Explain(Plan plan, DrdsSql drdsSql) { | |
this.plan = plan; | |
this.drdsSql = drdsSql; | |
} | |
public String getColumnInfo() { | |
return plan.getMetaData().toSimpleText(); | |
} | |
// public String dumpPlan2() { | |
// String dumpPlan = Util.toLinux(RelOptUtil.dumpPlan("", plan.getPhysical(), SqlExplainFormat.TEXT, | |
// SqlExplainLevel.EXPPLAN_ATTRIBUTES)); | |
// System.out.println(dumpPlan); | |
// return dumpPlan; | |
// } | |
public String dumpPlan() { | |
return plan.dumpPlan().replaceAll("\r"," ").replaceAll("\n"," "); | |
} | |
public List<SpecificSql> specificSql() { | |
return plan.specificSql(drdsSql); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import io.mycat.DataNode; | |
import io.mycat.calcite.table.ShardingTable; | |
import io.mycat.router.CustomRuleFunction; | |
import lombok.ToString; | |
import java.util.Collections; | |
import java.util.List; | |
@ToString | |
public class GetQueryAllIterator implements ConditionHandler{ | |
public GetQueryAllIterator() { | |
} | |
public static GetQueryAllIterator of() { | |
return new GetQueryAllIterator(); | |
} | |
public List<DataNode> handle(ShardingTable table, Object[] params) { | |
CustomRuleFunction shardingFuntion = table.getShardingFuntion(); | |
return shardingFuntion.calculate(Collections.emptyMap()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import io.mycat.DataNode; | |
import io.mycat.RangeVariable; | |
import io.mycat.RangeVariableType; | |
import io.mycat.calcite.table.ShardingTable; | |
import io.mycat.querycondition.ComparisonOperator; | |
import io.mycat.querycondition.KeyMeta; | |
import io.mycat.router.CustomRuleFunction; | |
import lombok.ToString; | |
import org.apache.calcite.rel.RelCollation; | |
import org.apache.calcite.rex.RexNode; | |
import java.util.*; | |
import static io.mycat.drdsrunner.MycatRexUtil.resolveParam; | |
@ToString | |
public class GetRangeQueryIterator implements ConditionHandler { | |
private final List<Object> rangeQueryLowerKey; | |
private final ComparisonOperator rangeQueryLowerOp; | |
private final List<Object> rangeQueryUpperKey; | |
private final ComparisonOperator rangeQueryUpperOp; | |
private final List<String> selectedColumnNames; | |
public GetRangeQueryIterator(List<Object> rangeQueryLowerKey, | |
ComparisonOperator rangeQueryLowerOp, | |
List<Object> rangeQueryUpperKey, | |
ComparisonOperator rangeQueryUpperOp, | |
List<String> selectedColumnNames) { | |
this.rangeQueryLowerKey = rangeQueryLowerKey; | |
this.rangeQueryLowerOp = rangeQueryLowerOp; | |
this.rangeQueryUpperKey = rangeQueryUpperKey; | |
this.rangeQueryUpperOp = rangeQueryUpperOp; | |
this.selectedColumnNames = selectedColumnNames; | |
} | |
public static GetRangeQueryIterator of(List<Object> rangeQueryLowerKey, | |
ComparisonOperator rangeQueryLowerOp, | |
List<Object> rangeQueryUpperKey, | |
ComparisonOperator rangeQueryUpperOp, | |
List<String> selectedColumnNames) { | |
return new GetRangeQueryIterator(rangeQueryLowerKey, rangeQueryLowerOp, rangeQueryUpperKey, rangeQueryUpperOp, selectedColumnNames); | |
} | |
public List<DataNode> handle(ShardingTable table, Object[] paramsArgs) { | |
List<Object> rangeQueryLowerKey = this.rangeQueryLowerKey; | |
ComparisonOperator rangeQueryLowerOp = this.rangeQueryLowerOp; | |
List<Object> rangeQueryUpperKey = this.rangeQueryUpperKey; | |
ComparisonOperator rangeQueryUpperOp = this.rangeQueryUpperOp; | |
List<String> selectedColumnNames = this.selectedColumnNames; | |
return getDataNodes(table, paramsArgs, rangeQueryLowerKey, rangeQueryLowerOp, rangeQueryUpperKey, rangeQueryUpperOp, selectedColumnNames); | |
} | |
public static List<DataNode> getDataNodes(ShardingTable table, Object[] paramsArgs, List<Object> rangeQueryLowerKey, ComparisonOperator rangeQueryLowerOp, List<Object> rangeQueryUpperKey, ComparisonOperator rangeQueryUpperOp, List<String> selectedColumnNames) { | |
Object[] leftValues = new Object[rangeQueryLowerKey.size()]; | |
Object[] rightValues = new Object[rangeQueryUpperKey.size()]; | |
for (int i = 0; i < leftValues.length; i++) { | |
Object o = rangeQueryLowerKey.get(i); | |
if (o instanceof RexNode) { | |
leftValues[i] = resolveParam((RexNode) o, paramsArgs); | |
} else { | |
leftValues[i] = o; | |
} | |
} | |
for (int i = 0; i < rightValues.length; i++) { | |
Object o = rangeQueryUpperKey.get(i); | |
if (o instanceof RexNode) { | |
rightValues[i] = resolveParam((RexNode) o, paramsArgs); | |
} else { | |
rightValues[i] = o; | |
} | |
} | |
Arrays.sort(leftValues); | |
Arrays.sort(rightValues); | |
Object leftSmallOne = leftValues[0]; | |
Object rightBigOne = rightValues[rightValues.length - 1]; | |
if (rangeQueryLowerOp == ComparisonOperator.LT) { | |
rangeQueryLowerOp = ComparisonOperator.LTE; | |
} | |
if (rangeQueryUpperOp == ComparisonOperator.GT) { | |
rangeQueryUpperOp = ComparisonOperator.GTE; | |
} | |
if (rangeQueryLowerOp == ComparisonOperator.LTE && rangeQueryUpperOp == ComparisonOperator.GTE){ | |
String columnName = selectedColumnNames.get(0); | |
HashMap<String, Collection<RangeVariable>> map = new HashMap<>(); | |
map.put(columnName,Collections.singleton(new RangeVariable(columnName, RangeVariableType.RANGE,leftSmallOne,rightBigOne))); | |
return table.getShardingFuntion().calculate(map); | |
}else { | |
return table.getShardingFuntion().calculate(Collections.emptyMap()); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import io.mycat.DataNode; | |
import io.mycat.calcite.table.ShardingTable; | |
import io.mycat.querycondition.ComparisonOperator; | |
import io.mycat.router.CustomRuleFunction; | |
import lombok.ToString; | |
import org.apache.calcite.rex.RexNode; | |
import java.util.Collections; | |
import java.util.List; | |
@ToString | |
public class GetRecordIteratorBySk implements ConditionHandler{ | |
private final String indexName; | |
private final List<Object> pointQueryKey; | |
private final ComparisonOperator gte; | |
private final List<Object> pointQueryKey1; | |
private final ComparisonOperator lte; | |
private final List<String> selectedColumnNames; | |
public GetRecordIteratorBySk(String indexName, List<Object> pointQueryKey, ComparisonOperator gte, List<Object> pointQueryKey1, ComparisonOperator lte, List<String> selectedColumnNames) { | |
this.indexName = indexName; | |
this.pointQueryKey = pointQueryKey; | |
this.gte = gte; | |
this.pointQueryKey1 = pointQueryKey1; | |
this.lte = lte; | |
this.selectedColumnNames = selectedColumnNames; | |
} | |
public static GetRecordIteratorBySk of(String indexName, List<Object> pointQueryKey, ComparisonOperator gte, List<Object> pointQueryKey1, ComparisonOperator lte, List<String> selectedColumnNames, List<RexNode> pushDownConditions){ | |
return new GetRecordIteratorBySk(indexName,pointQueryKey,gte,pointQueryKey1,lte,selectedColumnNames); | |
} | |
public List<DataNode> handle(ShardingTable table, Object[] params) { | |
GetRangeQueryIterator.getDataNodes(table,params,pointQueryKey,) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import io.mycat.querycondition.QueryType; | |
import org.testng.annotations.Test; | |
public class IndexCondition2 { | |
public static final IndexCondition2 EMPTY_CONDITION = ; | |
public QueryType getQueryType() { | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import org.apache.calcite.rex.RexDynamicParam; | |
import org.apache.calcite.rex.RexLiteral; | |
import org.apache.calcite.rex.RexNode; | |
public class MycatRexUtil { | |
public static Object resolveParam(RexNode rexNode, Object[] params) { | |
if (rexNode instanceof RexDynamicParam) { | |
int index = ((RexDynamicParam) rexNode).getIndex(); | |
return params[index]; | |
} | |
if (rexNode instanceof RexLiteral) { | |
return ((RexLiteral) rexNode).getValue(); | |
} | |
return rexNode; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import com.alibaba.druid.sql.SQLUtils; | |
import com.alibaba.druid.sql.ast.SQLStatement; | |
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; | |
import io.mycat.DrdsRunner; | |
import io.mycat.MetaClusterCurrent; | |
import io.mycat.MetadataManager; | |
import io.mycat.MycatCore; | |
import io.mycat.calcite.MycatCalciteSupport; | |
import io.mycat.calcite.physical.MycatInsertRel; | |
import io.mycat.calcite.physical.MycatUpdateRel; | |
import io.mycat.config.*; | |
import io.mycat.hint.CreateClusterHint; | |
import io.mycat.hint.CreateDataSourceHint; | |
import io.mycat.router.ShardingTableHandler; | |
import io.mycat.util.JsonUtil; | |
import org.apache.calcite.persistor.MycatInsertRelPersistor; | |
import org.apache.calcite.persistor.MycatUpdateRelPersistor; | |
import org.apache.calcite.persistor.RelOptCostPersistor; | |
import org.apache.calcite.plan.RelOptCost; | |
import org.junit.Assert; | |
import org.junit.Test; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import java.util.Map; | |
import static io.mycat.assemble.MycatTest.DB1; | |
import static io.mycat.assemble.MycatTest.DB2; | |
import static org.apache.calcite.persistor.RelOptCostPersistor.toRelOptCost; | |
public class PersistTest { | |
@Test | |
public void testMycaUpdateRel() { | |
initRuntime(); | |
MetadataManager metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class); | |
MycatUpdateRel mycatUpdateRel = MycatUpdateRel.create(Arrays.asList(MycatCalciteSupport.RexBuilder.makeLiteral(true)), | |
(SQLStatement) SQLUtils.parseSingleMysqlStatement( | |
"INSERT INTO db1.sharding (id) VALUES (?)"),"db1","sharding"); | |
String persist = MycatUpdateRelPersistor.persist(mycatUpdateRel); | |
Assert.assertEquals(persist, MycatUpdateRelPersistor.persist(MycatUpdateRelPersistor.unPersist(persist))); | |
} | |
@Test | |
public void testMycatInsertRel() { | |
initRuntime(); | |
MetadataManager metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class); | |
MycatInsertRel mycatInsertRel = MycatInsertRel.create(-1, Arrays.asList(1), | |
(MySqlInsertStatement) SQLUtils.parseSingleMysqlStatement( | |
"INSERT INTO db1.sharding (id) VALUES (?)"), (ShardingTableHandler) metadataManager.getTable("db1", "sharding")); | |
String persist = MycatInsertRelPersistor.persist(mycatInsertRel); | |
Assert.assertEquals(persist, MycatInsertRelPersistor.persist(MycatInsertRelPersistor.unPersist(persist))); | |
} | |
public static void main(String[] args) { | |
initRuntime(); | |
MetadataManager wrapper = MetaClusterCurrent.wrapper(MetadataManager.class); | |
System.out.println(); | |
} | |
public static void initRuntime() { | |
MycatCore mycatCore = new MycatCore(); | |
FileMetadataStorageManager fileMetadataStorageManager = MetaClusterCurrent.wrapper(FileMetadataStorageManager.class); | |
MycatRouterConfig mycatRouterConfig = new MycatRouterConfig(); | |
LogicSchemaConfig logicSchemaConfig = new LogicSchemaConfig(); | |
mycatRouterConfig.getSchemas().add(logicSchemaConfig); | |
logicSchemaConfig.setSchemaName("db1"); | |
ShardingTableConfig mainSharding = new ShardingTableConfig(); | |
mainSharding.setCreateTableSQL("CREATE TABLE db1.`sharding` (\n" + | |
" `id` bigint NOT NULL AUTO_INCREMENT,\n" + | |
" `user_id` varchar(100) DEFAULT NULL,\n" + | |
" `traveldate` date DEFAULT NULL,\n" + | |
" `fee` decimal(10,0) DEFAULT NULL,\n" + | |
" `days` int DEFAULT NULL,\n" + | |
" `blob` longblob,\n" + | |
" PRIMARY KEY (`id`),\n" + | |
" KEY `id` (`id`)\n" + | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8" | |
+ " dbpartition by hash(id) tbpartition by hash(id) tbpartitions 2 dbpartitions 2;"); | |
mainSharding.setFunction(ShardingFuntion.builder().properties(JsonUtil.from("{\n" + | |
"\t\t\t\t\t\"dbNum\":\"2\",\n" + | |
"\t\t\t\t\t\"mappingFormat\":\"c${targetIndex}/db1_${dbIndex}/sharding_${tableIndex}\",\n" + | |
"\t\t\t\t\t\"tableNum\":\"2\",\n" + | |
"\t\t\t\t\t\"tableMethod\":\"hash(id)\",\n" + | |
"\t\t\t\t\t\"storeNum\":2,\n" + | |
"\t\t\t\t\t\"dbMethod\":\"hash(id)\"\n" + | |
"\t\t\t\t}", Map.class)).build()); | |
logicSchemaConfig.getShadingTables().put("sharding", mainSharding); | |
mycatRouterConfig.getClusters().add(CreateClusterHint.createConfig("c0", Arrays.asList("ds0"), Collections.emptyList())); | |
mycatRouterConfig.getDatasources().add(CreateDataSourceHint.createConfig("ds0", DB1)); | |
mycatRouterConfig.getDatasources().add(CreateDataSourceHint.createConfig("prototype", DB1)); | |
fileMetadataStorageManager.start(mycatRouterConfig); | |
} | |
@Test | |
public void testVolcanoCostPersist() { | |
String text = "{\n" + | |
"\t\"cpu\":2.0,\n" + | |
"\t\"io\":3.0,\n" + | |
"\t\"rowCount\":1.0,\n" + | |
"\t\"className\":\"org.apache.calcite.plan.volcano.VolcanoCost\"\n" + | |
"}"; | |
RelOptCost relOptCost = toRelOptCost(text); | |
Assert.assertEquals(text, RelOptCostPersistor. persist(relOptCost)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import com.google.common.collect.HashMultimap; | |
import com.google.common.collect.Lists; | |
import com.google.common.collect.Multimap; | |
import io.mycat.calcite.MycatCalciteSupport; | |
import io.mycat.querycondition.*; | |
import org.apache.calcite.plan.RelOptUtil; | |
import org.apache.calcite.rex.*; | |
import org.apache.calcite.sql.SqlKind; | |
import org.apache.calcite.sql.type.SqlTypeName; | |
import org.apache.commons.collections4.CollectionUtils; | |
import java.util.*; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
public class PredicateAnalyzer3 { | |
private static final RexBuilder REX_BUILDER = MycatCalciteSupport.RexBuilder; | |
private final List<KeyMeta> keyMetaList; | |
private final String forceIndexName; | |
public PredicateAnalyzer3(List<KeyMeta> keyMetaList, String forceIndexName) { | |
this.keyMetaList = keyMetaList; | |
this.forceIndexName = forceIndexName; | |
} | |
public static class KeyMeta { | |
String columnName; | |
} | |
public static class IndexCondition { | |
public static final IndexCondition EMPTY_CONDITION = ; | |
String indexName; | |
boolean canPushDown() { | |
} | |
public boolean nameMatch(String name) { | |
return name != null && name.equalsIgnoreCase(indexName); | |
} | |
public QueryType getQueryType() { | |
return null; | |
} | |
} | |
public IndexCondition translateMatch(RexNode condition) { | |
List<RexNode> disjunctions = RelOptUtil.disjunctions(condition); | |
if (disjunctions.size() == 1) { | |
return translateAnd(disjunctions.get(0)); | |
} else { | |
return IndexCondition.EMPTY_CONDITION; | |
} | |
} | |
private IndexCondition translateAnd(RexNode condition) { | |
// expand calls to SEARCH(..., Sarg()) to >, =, etc. | |
final RexNode condition2 = | |
RexUtil.expandSearch(REX_BUILDER, null, condition); | |
// decompose condition by AND, flatten row expression | |
List<RexNode> rexNodeList = RelOptUtil.conjunctions(condition2); | |
List<IndexCondition> indexConditions = new ArrayList<>(); | |
// try to push down filter by secondary keys | |
for (KeyMeta skMeta : keyMetaList) { | |
indexConditions.add(findPushDownCondition(rexNodeList, skMeta)); | |
} | |
// a collection of all possible push down conditions, see if it can | |
// be pushed down, filter by forcing index name, then sort by comparator | |
Stream<IndexCondition> pushDownConditions = indexConditions.stream() | |
.filter(IndexCondition::canPushDown) | |
.filter(this::nonForceIndexOrMatchForceIndexName) | |
.sorted(new IndexConditionComparator()); | |
return pushDownConditions.findFirst().orElse(IndexCondition.EMPTY_CONDITION); | |
} | |
private List<InternalRexNode> analyzePrefixMatches(List<RexNode> rexNodeList, io.mycat.querycondition.KeyMeta keyMeta) { | |
return rexNodeList.stream() | |
.map(rexNode -> translateMatch2(rexNode, keyMeta)) | |
.filter(Optional::isPresent) | |
.map(Optional::get) | |
.collect(Collectors.toList()); | |
} | |
/** | |
* Translates a call to a binary operator. Returns null on failure. | |
*/ | |
private Optional<InternalRexNode> translateBinary2(String op, RexNode left, | |
RexNode right, RexNode originNode, io.mycat.querycondition.KeyMeta keyMeta) { | |
RexNode rightLiteral; | |
if (right.isA(SqlKind.LITERAL) || right.isA(SqlKind.DYNAMIC_PARAM)) { | |
rightLiteral = right; | |
} else { | |
// because MySQL's TIMESTAMP is mapped to TIMESTAMP_WITH_TIME_ZONE sql type, | |
// we should cast the value to literal. | |
if (right.isA(SqlKind.CAST) | |
&& isSqlTypeMatch((RexCall) right, SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE)) { | |
rightLiteral = ((RexCall) right).operands.get(0); | |
} else { | |
return Optional.empty(); | |
} | |
} | |
switch (left.getKind()) { | |
case INPUT_REF: | |
final RexInputRef left1 = (RexInputRef) left; | |
String name = fieldNames.get(left1.getIndex()); | |
// filter out field does not show in index column | |
if (!keyMeta.getKeyColumnNames().contains(name)) { | |
return Optional.empty(); | |
} | |
return translateOp2(op, name, rightLiteral, originNode, keyMeta); | |
case CAST: | |
return translateBinary2(op, ((RexCall) left).operands.get(0), right, | |
originNode, keyMeta); | |
default: | |
return Optional.empty(); | |
} | |
} | |
/** | |
* Combines a field name, operator, and literal to produce a predicate string. | |
*/ | |
private static Optional<InternalRexNode> translateOp2(String op, String name, | |
RexNode right, RexNode originNode, io.mycat.querycondition.KeyMeta keyMeta) { | |
; | |
InternalRexNode node = new InternalRexNode(); | |
node.node = originNode; | |
node.ordinalInKey = keyMeta.getKeyColumnNames().indexOf(name); | |
// For variable length column, Innodb-java-reader have a limitation, | |
// left-prefix index length should be less than search value literal. | |
// For example, we cannot leverage index of EMAIL(3) upon search value | |
// `[email protected]`, because the value length is longer than 3. | |
node.fieldName = name; | |
node.op = op; | |
node.right = right; | |
return Optional.of(node); | |
} | |
private IndexCondition findPushDownCondition(List<RexNode> rexNodeList, KeyMeta skMeta) { | |
// find field expressions matching index columns and specific operators | |
List<InternalRexNode> matchedRexNodeList = analyzePrefixMatches(rexNodeList, keyMeta); | |
// none of the conditions can be pushed down | |
if (CollectionUtils.isEmpty(matchedRexNodeList)) { | |
return IndexCondition.EMPTY_CONDITION; | |
} | |
// a collection that maps ordinal in index column list | |
// to multiple field expressions | |
Multimap<Integer,InternalRexNode> keyOrdToNodesMap = HashMultimap.create(); | |
for (InternalRexNode node : matchedRexNodeList) { | |
keyOrdToNodesMap.put(node.ordinalInKey, node); | |
} | |
// left-prefix index rule not match | |
Collection<InternalRexNode> leftMostKeyNodes = keyOrdToNodesMap.get(0); | |
if (CollectionUtils.isEmpty(leftMostKeyNodes)) { | |
return IndexCondition.EMPTY_CONDITION; | |
} | |
// create result which might have conditions to push down | |
List<String> indexColumnNames = keyMeta.getKeyColumnNames(); | |
List<RexNode> pushDownRexNodeList = new ArrayList<>(); | |
List<RexNode> remainderRexNodeList = new ArrayList<>(rexNodeList); | |
io.mycat.querycondition.IndexCondition condition = | |
io.mycat.querycondition.IndexCondition.create(fieldNames, keyMeta.getName(), indexColumnNames); | |
// handle point query if possible | |
condition = handlePointQuery(condition, keyMeta, leftMostKeyNodes, | |
keyOrdToNodesMap, pushDownRexNodeList, remainderRexNodeList); | |
if (condition.canPushDown()) { | |
return condition; | |
} | |
// handle range query | |
condition = handleRangeQuery(condition, keyMeta, leftMostKeyNodes, | |
pushDownRexNodeList, remainderRexNodeList, ">=", ">"); | |
condition = handleRangeQuery(condition, keyMeta, leftMostKeyNodes, | |
pushDownRexNodeList, remainderRexNodeList, "<=", "<"); | |
return condition; | |
} | |
private boolean nonForceIndexOrMatchForceIndexName(IndexCondition indexCondition) { | |
return Optional.ofNullable(forceIndexName) | |
.map(indexCondition::nameMatch).orElse(true); | |
} | |
static class IndexConditionComparator implements Comparator<IndexCondition> { | |
@Override | |
public int compare(IndexCondition o1,IndexCondition o2) { | |
return Integer.compare(o1.getQueryType().priority(), o2.getQueryType().priority()); | |
} | |
} | |
/** | |
* Internal representation of a row expression. | |
*/ | |
private static class InternalRexNode { | |
/** | |
* Relation expression node. | |
*/ | |
RexNode node; | |
/** | |
* Field ordinal in indexes. | |
*/ | |
int ordinalInKey; | |
/** | |
* Field name. | |
*/ | |
String fieldName; | |
/** | |
* Binary operation like =, >=, <=, > or <. | |
*/ | |
String op; | |
/** | |
* Binary operation right literal value. | |
*/ | |
Object right; | |
} | |
private static io.mycat.querycondition.IndexCondition handleRangeQuery(io.mycat.querycondition.IndexCondition condition, | |
io.mycat.querycondition.KeyMeta keyMeta, Collection<InternalRexNode> leftMostKeyNodes, | |
List<RexNode> pushDownRexNodeList, | |
List<RexNode> remainderRexNodeList, | |
String... opList) { | |
Optional<InternalRexNode> node = findFirstOp(leftMostKeyNodes, opList); | |
if (node.isPresent()) { | |
pushDownRexNodeList.add(node.get().node); | |
remainderRexNodeList.remove(node.get().node); | |
List<Object> key = createKey(Lists.newArrayList(node.get())); | |
ComparisonOperator op = ComparisonOperator.parse(node.get().op); | |
if (ComparisonOperator.isLowerBoundOp(opList)) { | |
return condition | |
.withQueryType(QueryType.getRangeQuery(keyMeta.isSecondaryKey())) | |
.withRangeQueryLowerOp(op) | |
.withRangeQueryLowerKey(key) | |
.withPushDownConditions(pushDownRexNodeList) | |
.withRemainderConditions(remainderRexNodeList); | |
} else if (ComparisonOperator.isUpperBoundOp(opList)) { | |
return condition | |
.withQueryType(QueryType.getRangeQuery(keyMeta.isSecondaryKey())) | |
.withRangeQueryUpperOp(op) | |
.withRangeQueryUpperKey(key) | |
.withPushDownConditions(pushDownRexNodeList) | |
.withRemainderConditions(remainderRexNodeList); | |
} else { | |
throw new AssertionError("comparison operation is invalid " + op); | |
} | |
} | |
return condition; | |
} | |
private static boolean isSqlTypeMatch(RexCall rexCall, SqlTypeName sqlTypeName) { | |
assert rexCall != null; | |
return rexCall.type.getSqlTypeName() == sqlTypeName; | |
} | |
/** | |
* Translates a binary relation. | |
*/ | |
private Optional<InternalRexNode> translateMatch2(RexNode node, io.mycat.querycondition.KeyMeta keyMeta) { | |
switch (node.getKind()) { | |
case EQUALS: | |
return translateBinary("=", "=", (RexCall) node, keyMeta); | |
case LESS_THAN: | |
return translateBinary("<", ">", (RexCall) node, keyMeta); | |
case LESS_THAN_OR_EQUAL: | |
return translateBinary("<=", ">=", (RexCall) node, keyMeta); | |
case GREATER_THAN: | |
return translateBinary(">", "<", (RexCall) node, keyMeta); | |
case GREATER_THAN_OR_EQUAL: | |
return translateBinary(">=", "<=", (RexCall) node, keyMeta); | |
default: | |
return Optional.empty(); | |
} | |
} | |
private Optional<InternalRexNode> translateBinary(String op, String rop, | |
RexCall call, io.mycat.querycondition.KeyMeta keyMeta) { | |
final RexNode left = call.operands.get(0); | |
final RexNode right = call.operands.get(1); | |
Optional<InternalRexNode> expression = | |
translateBinary2(op, left, right, call, keyMeta); | |
if (expression.isPresent()) { | |
return expression; | |
} | |
expression = translateBinary2(rop, right, left, call, keyMeta); | |
return expression; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//package io.mycat.drdsrunner; | |
// | |
//import io.mycat.calcite.MycatCalciteSupport; | |
//import io.mycat.querycondition.*; | |
//import org.apache.calcite.rex.*; | |
//import org.apache.calcite.sql.fun.SqlStdOperatorTable; | |
//import org.apache.calcite.sql.type.SqlTypeName; | |
//import org.jetbrains.annotations.NotNull; | |
//import org.junit.Assert; | |
//import org.junit.Test; | |
// | |
//import java.util.*; | |
// | |
//public class PredicateAnalyzerTest { | |
// private static final RexBuilder rexBuilder = MycatCalciteSupport.RexBuilder; | |
// | |
// | |
// @Test | |
// public void testTrue() { | |
// RexLiteral rexLiteral = rexBuilder.makeLiteral(true); | |
// List<String> columnList = Arrays.asList("id"); | |
// PredicateAnalyzer2 predicateAnalyzer2 = new PredicateAnalyzer2( | |
// columnList, | |
// KeyMeta.builder().name("default").type(KeyMeta.Type.PRIMARY_KEY).keyColumnNames(columnList).build(), Collections.emptyList(), null); | |
// IndexCondition indexCondition = predicateAnalyzer2.translateMatch(rexLiteral); | |
// Assert.assertEquals(null, indexCondition.getQueryType()); | |
// } | |
// | |
// @Test | |
// public void testEqual() { | |
// RexNode rexNode = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 0 | |
// ), rexBuilder.makeLiteral(1, MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), false)); | |
// List<String> columnList = Arrays.asList("id"); | |
// PredicateAnalyzer2 predicateAnalyzer2 = new PredicateAnalyzer2( | |
// columnList, | |
// KeyMeta.builder().name("default").type(KeyMeta.Type.PRIMARY_KEY).keyColumnNames(columnList).build(), Collections.emptyList(), null); | |
// Object o = getObject(predicateAnalyzer2, (rexNode)); | |
// Assert.assertEquals("QueryByPrimaryKey(pointQueryKey=[1], selectedColumnNames=[id])", Objects.toString(o)); | |
// } | |
// | |
// @Test | |
// public void testEqualParam() { | |
// RexNode rexNode = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 0 | |
// ), rexBuilder.makeDynamicParam(MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), 0)); | |
// List<String> columnList = Arrays.asList("id"); | |
// PredicateAnalyzer2 predicateAnalyzer2 = new PredicateAnalyzer2( | |
// columnList, | |
// KeyMeta.builder().name("default").type(KeyMeta.Type.PRIMARY_KEY).keyColumnNames(columnList).build(), Collections.emptyList(), null); | |
// Object o = getObject(predicateAnalyzer2.translateMatch(rexNode), columnList); | |
// Assert.assertEquals("QueryByPrimaryKey(pointQueryKey=[?0], selectedColumnNames=[id])", Objects.toString(o)); | |
// } | |
// | |
// @Test | |
// public void testRange() { | |
// RexNode leftRexNode = rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 0 | |
// ), rexBuilder.makeDynamicParam(MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), 0)); | |
// | |
// RexNode rightRexNode = rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 0 | |
// ), rexBuilder.makeDynamicParam(MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), 1)); | |
// | |
// RexNode rexNode = rexBuilder.makeCall(SqlStdOperatorTable.AND, leftRexNode, rightRexNode); | |
// List<String> columnList = Arrays.asList("id"); | |
// PredicateAnalyzer2 predicateAnalyzer2 = new PredicateAnalyzer2( | |
// columnList, | |
// KeyMeta.builder().name("default").type(KeyMeta.Type.PRIMARY_KEY).keyColumnNames(columnList).build(), Collections.emptyList(), null); | |
// Object o = getObject(predicateAnalyzer2.translateMatch(rexNode), columnList); | |
// Assert.assertEquals("GetRangeQueryIterator(rangeQueryLowerKey=[?0], rangeQueryLowerOp=GT, rangeQueryUpperKey=[?1], rangeQueryUpperOp=LT, selectedColumnNames=[id])", Objects.toString(o)); | |
// } | |
// | |
// @Test | |
// public void testOr() { | |
// RexNode leftRexNode = rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 0 | |
// ), rexBuilder.makeDynamicParam(MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), 0)); | |
// | |
// RexNode rightRexNode = rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 0 | |
// ), rexBuilder.makeDynamicParam(MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), 1)); | |
// | |
// RexNode rexNode = rexBuilder.makeCall(SqlStdOperatorTable.OR, leftRexNode, rightRexNode); | |
// List<String> columnList = Arrays.asList("id"); | |
// PredicateAnalyzer2 predicateAnalyzer2 = new PredicateAnalyzer2( | |
// columnList, | |
// KeyMeta.builder().name("default").type(KeyMeta.Type.PRIMARY_KEY).keyColumnNames(columnList).build(), Collections.emptyList(), null); | |
// Assert.assertEquals("(null, index=null)", Objects.toString(predicateAnalyzer2.translateMatch(rexNode))); | |
// } | |
// | |
// @Test | |
// public void testNot() { | |
// RexNode leftRexNode = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 0 | |
// ), rexBuilder.makeDynamicParam(MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), 0)); | |
// RexNode rexNode = rexBuilder.makeCall(SqlStdOperatorTable.NOT, leftRexNode); | |
// List<String> columnList = Arrays.asList("id"); | |
// PredicateAnalyzer2 predicateAnalyzer2 = new PredicateAnalyzer2( | |
// columnList, | |
// KeyMeta.builder().name("default").type(KeyMeta.Type.PRIMARY_KEY).keyColumnNames(columnList).build(), Collections.emptyList(), null); | |
// Assert.assertEquals("(null, index=null)", Objects.toString(predicateAnalyzer2.translateMatch(rexNode))); | |
// } | |
// | |
// @Test | |
// public void testDoubleColumns() { | |
// RexNode leftRexNode = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 0 | |
// ), rexBuilder.makeDynamicParam(MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), 0)); | |
// RexNode rightRexNode = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef( | |
// MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), | |
// 1 | |
// ), rexBuilder.makeDynamicParam(MycatCalciteSupport.TypeFactory.createSqlType(SqlTypeName.INTEGER), 0)); | |
// List<String> columnList = Arrays.asList("id", "id2"); | |
// PredicateAnalyzer2 predicateAnalyzer2 = new PredicateAnalyzer2( | |
// columnList, | |
// KeyMeta.builder().name("default").type(KeyMeta.Type.PRIMARY_KEY).keyColumnNames(columnList).build(), Collections.emptyList(), null); | |
// Assert.assertEquals("(PK_POINT_QUERY, index=default, id=?0,id2=?0)", Objects.toString(predicateAnalyzer2.translateMatch(RexUtil.composeConjunction(rexBuilder, Arrays.asList(leftRexNode, rightRexNode))))); | |
// } | |
// | |
// @NotNull | |
// private Object getObject(PredicateAnalyzer2 predicateAnalyzer2, RexNode rexNode, List<String> columnList) { | |
// IndexCondition condition = predicateAnalyzer2.translateMatch(rexNode); | |
// final List<Object> pointQueryKey = condition.getPointQueryKey(); | |
// final ComparisonOperator rangeQueryLowerOp = condition.getRangeQueryLowerOp(); | |
// final List<Object> rangeQueryLowerKey = condition.getRangeQueryLowerKey(); | |
// final ComparisonOperator rangeQueryUpperOp = condition.getRangeQueryUpperOp(); | |
// final List<Object> rangeQueryUpperKey = condition.getRangeQueryUpperKey(); | |
// final String indexName = condition.getIndexName(); | |
// | |
// final List<String> selectedColumnNames = columnList; | |
// | |
// | |
// Object o; | |
// switch (condition.getQueryType()) { | |
// case PK_POINT_QUERY: | |
// //queryByPrimaryKey | |
// o = QueryByPrimaryKey.of(pointQueryKey,condition.getIndexColumnNames()); | |
// break; | |
// case PK_RANGE_QUERY: | |
// o = GetRangeQueryIterator.of( | |
// rangeQueryLowerKey, rangeQueryLowerOp, rangeQueryUpperKey, rangeQueryUpperOp, condition.getIndexColumnNames()); | |
// break; | |
// case SK_POINT_QUERY: | |
// o = GetRecordIteratorBySk.of(indexName, | |
// pointQueryKey, ComparisonOperator.GTE, pointQueryKey, ComparisonOperator.LTE, | |
// selectedColumnNames, pushDownConditions); | |
// break; | |
// case SK_RANGE_QUERY: | |
// case SK_FULL_SCAN: | |
// o = GetRecordIteratorBySk.of(indexName, | |
// rangeQueryLowerKey, rangeQueryLowerOp, rangeQueryUpperKey, rangeQueryUpperOp, | |
// selectedColumnNames, pushDownConditions); | |
// break; | |
// case PK_FULL_SCAN: | |
// default: | |
// o = GetQueryAllIterator.of(); | |
// break; | |
// | |
// } | |
// return o; | |
// } | |
// | |
// | |
//} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import io.mycat.DataNode; | |
import io.mycat.RangeVariable; | |
import io.mycat.RangeVariableType; | |
import io.mycat.calcite.table.ShardingTable; | |
import io.mycat.querycondition.KeyMeta; | |
import io.mycat.router.CustomRuleFunction; | |
import lombok.ToString; | |
import org.apache.calcite.rex.RexDynamicParam; | |
import org.apache.calcite.rex.RexNode; | |
import java.util.*; | |
import static io.mycat.drdsrunner.MycatRexUtil.resolveParam; | |
@ToString | |
public class QueryByPrimaryKey implements ConditionHandler { | |
private final List<Object> pointQueryKey; | |
private final List<String> fieldList; | |
public QueryByPrimaryKey(List<Object> pointQueryKey, List<String> fieldList) { | |
this.pointQueryKey = pointQueryKey; | |
this.fieldList = fieldList; | |
} | |
public static QueryByPrimaryKey of(List<Object> pointQueryKey, List<String> fieldList) { | |
return new QueryByPrimaryKey(pointQueryKey, fieldList); | |
} | |
public List<DataNode> handle(ShardingTable table, Object[] params) { | |
CustomRuleFunction shardingFuntion = table.getShardingFuntion(); | |
if (pointQueryKey.isEmpty()) { | |
return shardingFuntion.calculate(Collections.emptyMap()); | |
} | |
List<String> keyColumnNames = fieldList; | |
String columnName = keyColumnNames.get(0); | |
Map<String, Collection<RangeVariable>> map = new HashMap<>(); | |
Object[] values = new Object[pointQueryKey.size()]; | |
int index = 0; | |
for (Object o : pointQueryKey) { | |
if (o instanceof RexNode) { | |
values[index] = resolveParam((RexNode) o, params); | |
}else { | |
values[index] = o; | |
} | |
index++; | |
} | |
Collection<RangeVariable> rangeVariables = map.computeIfAbsent(columnName, (k) -> new ArrayList<>()); | |
for (Object value : values) { | |
rangeVariables.add(new RangeVariable(columnName, RangeVariableType.EQUAL, value)); | |
} | |
if (pointQueryKey.isEmpty()) { | |
return shardingFuntion.calculate(Collections.emptyMap()); | |
} | |
return shardingFuntion.calculate(map); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.mycat.drdsrunner; | |
import io.mycat.calcite.physical.MycatProject; | |
import io.mycat.calcite.spm.SpecificSql; | |
import org.apache.calcite.rel.RelNode; | |
import org.junit.Assert; | |
import org.junit.Test; | |
import java.io.*; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Set; | |
import java.util.concurrent.TimeUnit; | |
public class ShardingJoinTest extends DrdsTest { | |
// @Test | |
// public void testSelectTest() throws Exception { | |
// Explain explain = parse("select 1"); | |
// RelNode physical = explain.getPlan().getPhysical(); | |
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | |
// ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); | |
// objectOutputStream.writeObject(physical); | |
// | |
// physical instanceof MycatProject | |
// ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(outputStream.toByteArray())); | |
// Object o = inputStream.readObject(); | |
// Assert.assertEquals("[{columnType=INTEGER, nullable=false, columnName=1}]", explain.getColumnInfo()); | |
// Assert.assertEquals("MycatProject(1=[1]) MycatValues(tuples=[[{ 0 }]]) ", explain.dumpPlan()); | |
// } | |
@Test | |
public void testSelect1() throws Exception { | |
Explain explain = parse("select 1"); | |
Assert.assertEquals("[{columnType=INTEGER, nullable=false, columnName=1}]", explain.getColumnInfo()); | |
Assert.assertEquals("MycatProject(1=[1]) MycatValues(tuples=[[{ 0 }]]) ", explain.dumpPlan()); | |
} | |
@Test | |
public void testSelectNormal() throws Exception { | |
Explain explain = parse("select * from db1.normal"); | |
Assert.assertEquals("[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=addressname}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[normalTables=db1.normal]) ", explain.dumpPlan()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[normalTables=db1.normal]) , parameterizedSql=SELECT * FROM db1.normal, sqls=[Each(targetName=prototype, sql=SELECT * FROM db1.normal)])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectNormalNormal() throws Exception { | |
Explain explain = parse("select * from db1.normal s join db1.normal2 e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=addressname}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=addressname0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[normalTables=db1.normal,db1.normal2]) ", explain.dumpPlan()); | |
// Assert.assertEquals("[SpecificSql(relNode=MycatView(distribution=[normalTables=db1.normal,db1.normal2]) , parameterizedSql=SELECT * FROM db1.normal INNER JOIN db1.normal2 ON (`normal`.`id` = `normal2`.`id`), sqls=[Each(targetName=prototype, sql=SELECT * FROM db1.normal INNER JOIN db1.normal2 ON (`normal`.`id` = `normal2`.`id`))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectNormalOtherNormal() throws Exception { | |
Explain explain = parse("select * from db1.normal s join db1.normal3 e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=addressname}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=addressname0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatHashJoin(condition=[=($0, $2)], joinType=[inner]) MycatView(distribution=[normalTables=db1.normal]) MycatView(distribution=[normalTables=db1.normal3]) ", explain.dumpPlan()); | |
// Assert.assertEquals("[SpecificSql(relNode=MycatView(distribution=[normalTables=db1.normal,db1.normal2]) , parameterizedSql=SELECT * FROM db1.normal INNER JOIN db1.normal2 ON (`normal`.`id` = `normal2`.`id`), sqls=[Each(targetName=prototype, sql=SELECT * FROM db1.normal INNER JOIN db1.normal2 ON (`normal`.`id` = `normal2`.`id`))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectNormalGlobal() throws Exception { | |
Explain explain = parse("select * from db1.normal s join db1.global e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=addressname}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[normalTables=db1.normal,globalTables=db1.global]) ", explain.dumpPlan()); | |
// Assert.assertEquals("[SpecificSql(relNode=MycatView(distribution=[normalTables=db1.normal,globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.normal INNER JOIN db1.global ON (`normal`.`id` = `global`.`id`), sqls=[Each(targetName=prototype, sql=SELECT * FROM db1.normal INNER JOIN db1.global ON (`normal`.`id` = `global`.`id`))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectNormalSharding() throws Exception { | |
Explain explain = parse("select * from db1.normal s join db1.sharding e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=addressname}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatHashJoin(condition=[=($0, $2)], joinType=[inner]) MycatView(distribution=[normalTables=db1.normal]) MycatView(distribution=[shardingTables=db1.sharding]) ", explain.dumpPlan()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[normalTables=db1.normal]) , parameterizedSql=SELECT * FROM db1.normal, sqls=[Each(targetName=prototype, sql=SELECT * FROM db1.normal)]), SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding]) , parameterizedSql=SELECT * FROM db1.sharding, sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 UNION ALL SELECT * FROM db1_0.sharding_1)), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 UNION ALL SELECT * FROM db1_1.sharding_1))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectSharding() throws Exception { | |
Explain explain = parse("select * from db1.sharding"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding]) ", explain.dumpPlan()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding]) , parameterizedSql=SELECT * FROM db1.sharding, sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 UNION ALL SELECT * FROM db1_0.sharding_1)), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 UNION ALL SELECT * FROM db1_1.sharding_1))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingWhere() throws Exception { | |
Explain explain = parse("select * from db1.sharding where id = 1"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding], conditions=[=(CAST($0):DECIMAL(19, 0), ?0)]) ", explain.dumpPlan()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding], conditions=[=(CAST($0):DECIMAL(19, 0), ?0)]) , parameterizedSql=SELECT * FROM db1.sharding WHERE (CAST(`id` AS decimal) = ?), sqls=[Each(targetName=c0, sql=SELECT * FROM db1_0.sharding_1 WHERE (CAST(`id` AS decimal) = ?))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingSelf() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.sharding e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=user_id0}, {columnType=DATE, nullable=true, columnName=traveldate0}, {columnType=DECIMAL, nullable=true, columnName=fee0}, {columnType=BIGINT, nullable=true, columnName=days0}, {columnType=VARBINARY, nullable=true, columnName=blob0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,db1.sharding]) ", explain.dumpPlan()); | |
// Assert.assertEquals("[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding,db1.sharding]) , parameterizedSql=SELECT * FROM db1.sharding INNER JOIN db1.sharding AS `sharding0` ON (`sharding`.`id` = `sharding0`.`id`), sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 INNER JOIN db1_0.sharding_0 AS `sharding_00` ON (`sharding_0`.`id` = `sharding_00`.`id`) UNION ALL SELECT * FROM db1_0.sharding_1 INNER JOIN db1_0.sharding_1 AS `sharding_10` ON (`sharding_1`.`id` = `sharding_10`.`id`))), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 INNER JOIN db1_1.sharding_0 AS `sharding_00` ON (`sharding_0`.`id` = `sharding_00`.`id`) UNION ALL SELECT * FROM db1_1.sharding_1 INNER JOIN db1_1.sharding_1 AS `sharding_10` ON (`sharding_1`.`id` = `sharding_10`.`id`)))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingSharding() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.other_sharding e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=user_id0}, {columnType=DATE, nullable=true, columnName=traveldate0}, {columnType=DECIMAL, nullable=true, columnName=fee0}, {columnType=BIGINT, nullable=true, columnName=days0}, {columnType=VARBINARY, nullable=true, columnName=blob0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatHashJoin(condition=[=($0, $6)], joinType=[inner]) MycatView(distribution=[shardingTables=db1.sharding]) MycatView(distribution=[shardingTables=db1.other_sharding]) ", explain.dumpPlan()); | |
// Assert.assertEquals("[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding]) , parameterizedSql=SELECT * FROM db1.sharding, sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 UNION ALL SELECT * FROM db1_0.sharding_1)), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 UNION ALL SELECT * FROM db1_1.sharding_1))]), SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.other_sharding]) , parameterizedSql=SELECT * FROM db1.other_sharding, sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.other_sharding_0 UNION ALL SELECT * FROM db1_0.other_sharding_1)), Each(targetName=c1, sql=(SELECT * FROM db1_1.other_sharding_0 UNION ALL SELECT * FROM db1_1.other_sharding_1))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingNormal() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.normal e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=addressname}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatHashJoin(condition=[=($0, $6)], joinType=[inner]) MycatView(distribution=[shardingTables=db1.sharding]) MycatView(distribution=[normalTables=db1.normal]) ", explain.dumpPlan()); | |
// Assert.assertEquals("[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding]) , parameterizedSql=SELECT * FROM db1.sharding, sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 UNION ALL SELECT * FROM db1_0.sharding_1)), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 UNION ALL SELECT * FROM db1_1.sharding_1))]), SpecificSql(relNode=MycatView(distribution=[normalTables=db1.normal]) , parameterizedSql=SELECT * FROM db1.normal, sqls=[Each(targetName=prototype, sql=SELECT * FROM db1.normal)])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingGlobal() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.global e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,globalTables=db1.global]) ", explain.dumpPlan()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding,globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.sharding INNER JOIN db1.global ON (`sharding`.`id` = `global`.`id`), sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 INNER JOIN db1.global ON (`sharding_0`.`id` = `global`.`id`) UNION ALL SELECT * FROM db1_0.sharding_1 INNER JOIN db1.global AS `global0` ON (`sharding_1`.`id` = `global0`.`id`))), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 INNER JOIN db1.global ON (`sharding_0`.`id` = `global`.`id`) UNION ALL SELECT * FROM db1_1.sharding_1 INNER JOIN db1.global AS `global0` ON (`sharding_1`.`id` = `global0`.`id`)))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingERWhere() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.er e on s.id = e.id where s.id = 1"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=user_id0}, {columnType=DATE, nullable=true, columnName=traveldate0}, {columnType=DECIMAL, nullable=true, columnName=fee0}, {columnType=BIGINT, nullable=true, columnName=days0}, {columnType=VARBINARY, nullable=true, columnName=blob0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,db1.er], conditions=[=(CAST($0):DECIMAL(19, 0), ?0)]) ", explain.dumpPlan()); | |
System.out.println(explain.specificSql()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding], conditions=[=(CAST($0):DECIMAL(19, 0), ?0)]) , parameterizedSql=SELECT * FROM db1.sharding WHERE (CAST(`id` AS decimal) = ?), sqls=[Each(targetName=c0, sql=SELECT * FROM db1_0.sharding_1 WHERE (CAST(`id` AS decimal) = ?))]), SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.er], conditions=[=(CAST($0):DECIMAL(19, 0), ?0)]) , parameterizedSql=SELECT * FROM db1.er WHERE (CAST(`id` AS decimal) = ?), sqls=[Each(targetName=c0, sql=SELECT * FROM db1_0.er_1 WHERE (CAST(`id` AS decimal) = ?))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingER() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.er e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=user_id0}, {columnType=DATE, nullable=true, columnName=traveldate0}, {columnType=DECIMAL, nullable=true, columnName=fee0}, {columnType=BIGINT, nullable=true, columnName=days0}, {columnType=VARBINARY, nullable=true, columnName=blob0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,db1.er]) ", explain.dumpPlan()); | |
System.out.println(explain.specificSql()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding,db1.er]) , parameterizedSql=SELECT * FROM db1.sharding INNER JOIN db1.er ON (`sharding`.`id` = `er`.`id`), sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 INNER JOIN db1_0.er_0 ON (`sharding_0`.`id` = `er_0`.`id`) UNION ALL SELECT * FROM db1_0.sharding_1 INNER JOIN db1_0.er_1 ON (`sharding_1`.`id` = `er_1`.`id`))), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 INNER JOIN db1_1.er_0 ON (`sharding_0`.`id` = `er_0`.`id`) UNION ALL SELECT * FROM db1_1.sharding_1 INNER JOIN db1_1.er_1 ON (`sharding_1`.`id` = `er_1`.`id`)))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingERGlobal() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.er e on s.id = e.id join db1.global g on e.id = g.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=user_id0}, {columnType=DATE, nullable=true, columnName=traveldate0}, {columnType=DECIMAL, nullable=true, columnName=fee0}, {columnType=BIGINT, nullable=true, columnName=days0}, {columnType=VARBINARY, nullable=true, columnName=blob0}, {columnType=BIGINT, nullable=true, columnName=id1}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,db1.er,globalTables=db1.global]) ", explain.dumpPlan()); | |
System.out.println(explain.specificSql()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding,db1.er,globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.sharding INNER JOIN db1.er ON (`sharding`.`id` = `er`.`id`) INNER JOIN db1.global ON (`er`.`id` = `global`.`id`), sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 INNER JOIN db1_0.er_0 ON (`sharding_0`.`id` = `er_0`.`id`) INNER JOIN db1.global ON (`er_0`.`id` = `global`.`id`) UNION ALL SELECT * FROM db1_0.sharding_1 INNER JOIN db1_0.er_1 ON (`sharding_1`.`id` = `er_1`.`id`) INNER JOIN db1.global AS `global0` ON (`er_1`.`id` = `global0`.`id`))), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 INNER JOIN db1_1.er_0 ON (`sharding_0`.`id` = `er_0`.`id`) INNER JOIN db1.global ON (`er_0`.`id` = `global`.`id`) UNION ALL SELECT * FROM db1_1.sharding_1 INNER JOIN db1_1.er_1 ON (`sharding_1`.`id` = `er_1`.`id`) INNER JOIN db1.global AS `global0` ON (`er_1`.`id` = `global0`.`id`)))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingGlobalER() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.global g on s.id = g.id join db1.er e on e.id = s.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}, {columnType=BIGINT, nullable=true, columnName=id1}, {columnType=VARCHAR, nullable=true, columnName=user_id0}, {columnType=DATE, nullable=true, columnName=traveldate0}, {columnType=DECIMAL, nullable=true, columnName=fee0}, {columnType=BIGINT, nullable=true, columnName=days0}, {columnType=VARBINARY, nullable=true, columnName=blob0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,db1.er,globalTables=db1.global]) ", explain.dumpPlan()); | |
System.out.println(explain.specificSql()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding,globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.sharding INNER JOIN db1.global ON (`sharding`.`id` = `global`.`id`), sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.sharding_0 INNER JOIN db1.global ON (`sharding_0`.`id` = `global`.`id`) UNION ALL SELECT * FROM db1_0.sharding_1 INNER JOIN db1.global AS `global0` ON (`sharding_1`.`id` = `global0`.`id`))), Each(targetName=c1, sql=(SELECT * FROM db1_1.sharding_0 INNER JOIN db1.global ON (`sharding_0`.`id` = `global`.`id`) UNION ALL SELECT * FROM db1_1.sharding_1 INNER JOIN db1.global AS `global0` ON (`sharding_1`.`id` = `global0`.`id`)))]), SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.er]) , parameterizedSql=SELECT * FROM db1.er, sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.er_0 UNION ALL SELECT * FROM db1_0.er_1)), Each(targetName=c1, sql=(SELECT * FROM db1_1.er_0 UNION ALL SELECT * FROM db1_1.er_1))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectShardingGlobalER2() throws Exception { | |
Explain explain = parse("select * from db1.sharding s join db1.global g on s.id = g.id join db1.er e on e.id = g.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}, {columnType=BIGINT, nullable=true, columnName=id1}, {columnType=VARCHAR, nullable=true, columnName=user_id0}, {columnType=DATE, nullable=true, columnName=traveldate0}, {columnType=DECIMAL, nullable=true, columnName=fee0}, {columnType=BIGINT, nullable=true, columnName=days0}, {columnType=VARBINARY, nullable=true, columnName=blob0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,db1.er,globalTables=db1.global]) ", explain.dumpPlan()); | |
System.out.println(explain.specificSql()); | |
} | |
@Test | |
public void testSelectShardingGlobalBadColumn() throws Exception { | |
Explain explain = parse("select t2.id from db1.sharding t2 join db1.normal t1 on t2.id = t1.id join db1.er l2 on t2.id = l2.id;"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}]", | |
explain.getColumnInfo()); | |
System.out.println(explain.dumpPlan()); | |
System.out.println(explain.specificSql()); | |
} | |
@Test | |
public void testSelectGlobalShardingBadColumn() throws Exception { | |
Explain explain = parse("select * from db1.global g join db1.sharding s on s.id = g.id join db1.er e on e.id = g.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}, {columnType=BIGINT, nullable=true, columnName=id1}, {columnType=VARCHAR, nullable=true, columnName=user_id0}, {columnType=DATE, nullable=true, columnName=traveldate0}, {columnType=DECIMAL, nullable=true, columnName=fee0}, {columnType=BIGINT, nullable=true, columnName=days0}, {columnType=VARBINARY, nullable=true, columnName=blob0}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,db1.er,globalTables=db1.global]) ", explain.dumpPlan()); | |
System.out.println(explain.specificSql()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding,globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.global INNER JOIN db1.sharding ON (`global`.`id` = `sharding`.`id`), sqls=[Each(targetName=c0, sql=(SELECT * FROM db1.global INNER JOIN db1_0.sharding_0 ON (`global`.`id` = `sharding_0`.`id`) UNION ALL SELECT * FROM db1.global AS `global0` INNER JOIN db1_0.sharding_1 ON (`global0`.`id` = `sharding_1`.`id`))), Each(targetName=c1, sql=(SELECT * FROM db1.global INNER JOIN db1_1.sharding_0 ON (`global`.`id` = `sharding_0`.`id`) UNION ALL SELECT * FROM db1.global AS `global0` INNER JOIN db1_1.sharding_1 ON (`global0`.`id` = `sharding_1`.`id`)))]), SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.er]) , parameterizedSql=SELECT * FROM db1.er, sqls=[Each(targetName=c0, sql=(SELECT * FROM db1_0.er_0 UNION ALL SELECT * FROM db1_0.er_1)), Each(targetName=c1, sql=(SELECT * FROM db1_1.er_0 UNION ALL SELECT * FROM db1_1.er_1))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectGlobal() throws Exception { | |
Set<String> explainColumnSet = new HashSet<>(); | |
Set<String> explainSet = new HashSet<>(); | |
Set<List<SpecificSql>> sqlSet = new HashSet<>(); | |
long end = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(5); | |
Explain explain; | |
while (true) { | |
explain = parse("select * from db1.global"); | |
explainColumnSet.add(explain.getColumnInfo()); | |
explainSet.add(explain.dumpPlan()); | |
sqlSet.add(explain.specificSql()); | |
if (sqlSet.size() > 1 || (System.currentTimeMillis() > end)) { | |
break; | |
} | |
} | |
Assert.assertTrue( | |
explainColumnSet.contains( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}]") | |
); | |
Assert.assertEquals("MycatView(distribution=[globalTables=db1.global]) ",explain.dumpPlan()); | |
// Assert.assertEquals("[[SpecificSql(relNode=MycatView(distribution=[globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.global, sqls=[Each(targetName=c0, sql=SELECT * FROM db1.global)])], [SpecificSql(relNode=MycatView(distribution=[globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.global, sqls=[Each(targetName=c1, sql=SELECT * FROM db1.global)])]]", | |
// sqlSet.toString()); | |
} | |
@Test | |
public void testSelectGlobalNormal() throws Exception { | |
Explain explain = parse("select * from db1.global s join db1.normal e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=addressname}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[normalTables=db1.normal,globalTables=db1.global]) ", explain.dumpPlan()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[normalTables=db1.normal,globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.global INNER JOIN db1.normal ON (`global`.`id` = `normal`.`id`), sqls=[Each(targetName=prototype, sql=SELECT * FROM db1.global INNER JOIN db1.normal ON (`global`.`id` = `normal`.`id`))])]", | |
// explain.specificSql().toString()); | |
} | |
@Test | |
public void testSelectGlobalSharding() throws Exception { | |
Explain explain = parse("select * from db1.global s join db1.sharding e on s.id = e.id"); | |
Assert.assertEquals( | |
"[{columnType=BIGINT, nullable=true, columnName=id}, {columnType=VARCHAR, nullable=true, columnName=companyname}, {columnType=BIGINT, nullable=true, columnName=addressid}, {columnType=BIGINT, nullable=true, columnName=id0}, {columnType=VARCHAR, nullable=true, columnName=user_id}, {columnType=DATE, nullable=true, columnName=traveldate}, {columnType=DECIMAL, nullable=true, columnName=fee}, {columnType=BIGINT, nullable=true, columnName=days}, {columnType=VARBINARY, nullable=true, columnName=blob}]", | |
explain.getColumnInfo()); | |
Assert.assertEquals("MycatView(distribution=[shardingTables=db1.sharding,globalTables=db1.global]) ", explain.dumpPlan()); | |
// Assert.assertEquals( | |
// "[SpecificSql(relNode=MycatView(distribution=[shardingTables=db1.sharding,globalTables=db1.global]) , parameterizedSql=SELECT * FROM db1.global INNER JOIN db1.sharding ON (`global`.`id` = `sharding`.`id`), sqls=[Each(targetName=c0, sql=(SELECT * FROM db1.global INNER JOIN db1_0.sharding_0 ON (`global`.`id` = `sharding_0`.`id`) UNION ALL SELECT * FROM db1.global AS `global0` INNER JOIN db1_0.sharding_1 ON (`global0`.`id` = `sharding_1`.`id`))), Each(targetName=c1, sql=(SELECT * FROM db1.global INNER JOIN db1_1.sharding_0 ON (`global`.`id` = `sharding_0`.`id`) UNION ALL SELECT * FROM db1.global AS `global0` INNER JOIN db1_1.sharding_1 ON (`global0`.`id` = `sharding_1`.`id`)))])]", | |
// explain.specificSql().toString()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment