use of io.mycat.calcite.rewriter.Distribution in project Mycat2 by MyCATApache.
the class AsyncMycatDataContextImpl method getSqlMap.
public static List<PartitionGroup> getSqlMap(Map<RexNode, RexNode> constantMap, MycatView view, DrdsSqlWithParams drdsSqlWithParams, Optional<List<PartitionGroup>> hintDataMapping) {
Distribution distribution = view.getDistribution();
Distribution.Type type = distribution.type();
switch(type) {
case BROADCAST:
{
Map<String, Partition> builder = new HashMap<>();
String targetName = null;
for (GlobalTable globalTable : distribution.getGlobalTables()) {
if (targetName == null) {
int i = ThreadLocalRandom.current().nextInt(0, globalTable.getGlobalDataNode().size());
Partition partition = globalTable.getGlobalDataNode().get(i);
targetName = partition.getTargetName();
}
builder.put(globalTable.getUniqueName(), globalTable.getDataNode());
}
return Collections.singletonList(new PartitionGroup(targetName, builder));
}
case PHY:
Map<String, Partition> builder = new HashMap<>();
String targetName = null;
for (GlobalTable globalTable : distribution.getGlobalTables()) {
builder.put(globalTable.getUniqueName(), globalTable.getDataNode());
}
for (NormalTable normalTable : distribution.getNormalTables()) {
if (targetName == null) {
targetName = normalTable.getDataNode().getTargetName();
}
builder.put(normalTable.getUniqueName(), normalTable.getDataNode());
}
return Collections.singletonList(new PartitionGroup(targetName, builder));
case SHARDING:
if (hintDataMapping.isPresent()) {
return hintDataMapping.get();
}
ShardingTable shardingTable = distribution.getShardingTables().get(0);
RexBuilder rexBuilder = MycatCalciteSupport.RexBuilder;
RexNode condition = view.getCondition().orElse(MycatCalciteSupport.RexBuilder.makeLiteral(true));
List<RexNode> inputConditions = new ArrayList<>(constantMap.size() + 1);
inputConditions.add(condition);
for (Map.Entry<RexNode, RexNode> rexNodeRexNodeEntry : constantMap.entrySet()) {
inputConditions.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexNodeRexNodeEntry.getKey(), rexNodeRexNodeEntry.getValue()));
}
ParamHolder paramHolder = ParamHolder.CURRENT_THREAD_LOCAL.get();
paramHolder.setData(drdsSqlWithParams.getParams(), drdsSqlWithParams.getTypeNames());
try {
ArrayList<RexNode> res = new ArrayList<>(inputConditions.size());
MycatRexExecutor.INSTANCE.reduce(rexBuilder, inputConditions, res);
condition = res.get(0);
ValuePredicateAnalyzer predicateAnalyzer = new ValuePredicateAnalyzer(shardingTable.keyMetas(true), shardingTable.getColumns().stream().map(i -> i.getColumnName()).collect(Collectors.toList()));
Map<QueryType, List<ValueIndexCondition>> indexConditionMap = predicateAnalyzer.translateMatch(condition);
List<Partition> partitions = ValueIndexCondition.getPartitions(shardingTable.getShardingFuntion(), indexConditionMap, drdsSqlWithParams.getParams());
return mapSharding(view, partitions);
} finally {
paramHolder.clear();
}
default:
throw new IllegalStateException("Unexpected value: " + distribution.type());
}
}
use of io.mycat.calcite.rewriter.Distribution in project Mycat2 by MyCATApache.
the class AsyncMycatDataContextImpl method mapSharding.
public static List<PartitionGroup> mapSharding(MycatView view, List<Partition> partitionList) {
Distribution distribution = view.getDistribution();
List<ShardingTable> shardingTableList = distribution.getShardingTables();
ShardingTable primaryShardingTable = shardingTableList.get(0);
CustomRuleFunction primaryShardingFunction = primaryShardingTable.getShardingFuntion();
HashMap<String, Partition> groupTemplate = new HashMap<>();
for (NormalTable normalTable : distribution.getNormalTables()) {
// 可能存在错误的数据分布,但是错误的数据分布访问不到
groupTemplate.put(normalTable.getUniqueName(), normalTable.getDataNode());
}
for (GlobalTable globalTable : distribution.getGlobalTables()) {
groupTemplate.put(globalTable.getUniqueName(), globalTable.getDataNode());
}
if (distribution.getShardingTables().size() == 1) {
List<PartitionGroup> res = new ArrayList<>(partitionList.size());
for (Partition partition : partitionList) {
HashMap<String, Partition> map = new HashMap<>(groupTemplate);
map.put(primaryShardingTable.getUniqueName(), partition);
res.add(new PartitionGroup(partition.getTargetName(), map));
}
return res;
} else {
List<ShardingTable> joinShardingTables = shardingTableList.subList(1, shardingTableList.size());
List<PartitionGroup> res = new ArrayList<>(partitionList.size());
for (Partition primaryPartition : partitionList) {
HashMap<String, Partition> map = new HashMap<>(groupTemplate);
map.put(primaryShardingTable.getUniqueName(), primaryPartition);
for (ShardingTable joinShardingTable : joinShardingTables) {
CustomRuleFunction joinFunction = joinShardingTable.function();
if (primaryShardingFunction.isSameDistribution(joinFunction)) {
Partition joinPartition = joinFunction.getPartition(primaryShardingFunction.indexOf(primaryPartition));
map.put(joinShardingTable.getUniqueName(), joinPartition);
} else if (primaryShardingFunction.isSameTargetFunctionDistribution(joinFunction)) {
List<Partition> joinPartitions = joinShardingTable.getPartitionsByTargetName(primaryPartition.getTargetName());
if (joinPartitions.size() != 1) {
throw new IllegalArgumentException("wrong partition " + joinPartitions + " in " + view);
}
map.put(joinShardingTable.getUniqueName(), joinPartitions.get(0));
}
}
res.add(new PartitionGroup(primaryPartition.getTargetName(), map));
}
return res;
}
}
use of io.mycat.calcite.rewriter.Distribution in project Mycat2 by MyCATApache.
the class HBTQueryConvertor method filterFromTable.
public RelNode filterFromTable(FilterFromTableSchema input) {
List<String> names = input.getNames();
relBuilder.scan(names);
TableScan tableScan = (TableScan) relBuilder.peek();
RelOptTable table = tableScan.getTable();
relBuilder.as(names.get(names.size() - 1));
relBuilder.filter(toRex(input.getFilter()));
Filter build = (Filter) relBuilder.build();
relBuilder.clear();
MycatLogicTable mycatTable = table.unwrap(MycatLogicTable.class);
Distribution distribution = mycatTable.createDistribution();
Iterable<Partition> dataNodes = distribution.getDataNodes().flatMap(i -> i.values().stream()).collect(Collectors.toList());
return build.copy(build.getTraitSet(), ImmutableList.of(toPhyTable(mycatTable, dataNodes)));
}
use of io.mycat.calcite.rewriter.Distribution in project Mycat2 by MyCATApache.
the class HackRouter method analyse.
public boolean analyse() {
Set<Pair<String, String>> tableNames = new HashSet<>();
Set<String> methods = new HashSet<>();
AtomicBoolean hasVar = new AtomicBoolean(false);
selectStatement.accept(new MySqlASTVisitorAdapter() {
@Override
public boolean visit(SQLExprTableSource x) {
String tableName = x.getTableName();
if (tableName != null) {
String schema = Optional.ofNullable(x.getSchema()).orElse(defaultSchema);
if (schema == null) {
throw new MycatException("please use schema;");
}
tableNames.add(Pair.of(SQLUtils.normalize(schema), SQLUtils.normalize(tableName)));
}
return super.visit(x);
}
@Override
public boolean visit(SQLMethodInvokeExpr x) {
methods.add(x.getMethodName());
return super.visit(x);
}
@Override
public boolean visit(SQLVariantRefExpr x) {
if (!"?".equals(x.getName())) {
hasVar.set(true);
}
return super.visit(x);
}
});
this.metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class);
if (PUSH_DOWN_SELECT_DUAL && tableNames.isEmpty() && !hasVar.get()) {
if (!methods.isEmpty() && methods.stream().noneMatch(name -> SQLRBORewriter.Information_Functions.containsKey(SQLUtils.normalize(name), false))) {
targetMap = NameMap.immutableCopyOf(Collections.emptyMap());
targetName = MetadataManager.getPrototype();
return true;
}
}
res = metadataManager.checkVaildNormalRoute(tableNames);
if (res.isPresent()) {
Distribution distribution = res.get();
ImmutableMap.Builder<String, Partition> builder = ImmutableMap.builder();
builder.putAll(distribution.getGlobalTables().stream().collect(Collectors.toMap(k -> k.getUniqueName(), v -> v.getDataNode())));
Map<String, Partition> normalMap = distribution.getNormalTables().stream().collect(Collectors.toMap(k -> k.getUniqueName(), v -> v.getDataNode()));
builder.putAll(normalMap);
targetMap = NameMap.immutableCopyOf(builder.build());
switch(distribution.type()) {
case BROADCAST:
List<Partition> globalDataNode = distribution.getGlobalTables().get(0).getGlobalDataNode();
int i = ThreadLocalRandom.current().nextInt(0, globalDataNode.size());
targetName = globalDataNode.get(i).getTargetName();
return true;
case SHARDING:
return false;
case PHY:
{
targetName = normalMap.values().iterator().next().getTargetName();
return true;
}
}
} else {
return false;
}
return false;
}
use of io.mycat.calcite.rewriter.Distribution in project Mycat2 by MyCATApache.
the class MetadataManager method checkVaildNormalRoute.
public Optional<Distribution> checkVaildNormalRoute(Set<Pair<String, String>> tableNames) {
NameMap<SchemaHandler> schemaMap1 = getSchemaMap();
Distribution leftDistribution = null;
TableHandler tableHandler = null;
for (Pair<String, String> tableName : tableNames) {
SchemaHandler schemaHandler = schemaMap1.get(SQLUtils.normalize(tableName.getKey()), false);
if (schemaHandler != null) {
NameMap<TableHandler> logicTables = schemaHandler.logicTables();
if (logicTables != null) {
tableHandler = logicTables.get(SQLUtils.normalize(tableName.getValue()), false);
if (tableHandler != null) {
if (tableHandler.getType() == LogicTableType.NORMAL || tableHandler.getType() == LogicTableType.GLOBAL) {
Distribution rightDistribution;
if (tableHandler.getType() == LogicTableType.NORMAL) {
NormalTable tableHandler1 = (NormalTable) tableHandler;
rightDistribution = Distribution.of(tableHandler1);
} else if (tableHandler.getType() == LogicTableType.GLOBAL) {
GlobalTable tableHandler1 = (GlobalTable) tableHandler;
rightDistribution = Distribution.of(tableHandler1);
} else {
throw new IllegalArgumentException("unsupported table type:" + tableHandler.getType());
}
if (leftDistribution == null) {
leftDistribution = rightDistribution;
} else {
Optional<Distribution> newDistribution = leftDistribution.join(rightDistribution);
if (newDistribution.isPresent()) {
leftDistribution = newDistribution.get();
} else {
return Optional.empty();
}
}
continue;
} else {
// sharding table
return Optional.empty();
}
}
}
}
}
if (leftDistribution == null) {
return Optional.empty();
}
return Optional.of(leftDistribution);
}
Aggregations