Search in sources :

Example 1 with Distribution

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());
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) SqlString(org.apache.calcite.sql.util.SqlString) ValuePredicateAnalyzer(io.mycat.calcite.rewriter.ValuePredicateAnalyzer) GlobalTable(io.mycat.calcite.table.GlobalTable) RexBuilder(org.apache.calcite.rex.RexBuilder) ImmutableList(com.google.common.collect.ImmutableList) ShardingTable(io.mycat.calcite.table.ShardingTable) NormalTable(io.mycat.calcite.table.NormalTable) ParamHolder(io.mycat.calcite.spm.ParamHolder) Distribution(io.mycat.calcite.rewriter.Distribution) ConcurrentMap(java.util.concurrent.ConcurrentMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) QueryType(io.mycat.querycondition.QueryType) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with Distribution

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;
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) SqlString(org.apache.calcite.sql.util.SqlString) CustomRuleFunction(io.mycat.router.CustomRuleFunction) NormalTable(io.mycat.calcite.table.NormalTable) GlobalTable(io.mycat.calcite.table.GlobalTable) Distribution(io.mycat.calcite.rewriter.Distribution) ImmutableList(com.google.common.collect.ImmutableList) ShardingTable(io.mycat.calcite.table.ShardingTable)

Example 3 with Distribution

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)));
}
Also used : MetadataManager(io.mycat.MetadataManager) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) MetaClusterCurrent(io.mycat.MetaClusterCurrent) MycatPhysicalTable(io.mycat.calcite.table.MycatPhysicalTable) SneakyThrows(lombok.SneakyThrows) org.apache.calcite.rex(org.apache.calcite.rex) LoggerFactory(org.slf4j.LoggerFactory) BigDecimal(java.math.BigDecimal) CorrelationId(org.apache.calcite.rel.core.CorrelationId) MycatTransientSQLTableScan(io.mycat.calcite.table.MycatTransientSQLTableScan) RelBuilder(org.apache.calcite.tools.RelBuilder) LocalTime(java.time.LocalTime) SQLDataType(com.alibaba.druid.sql.ast.SQLDataType) SQLSelectItem(com.alibaba.druid.sql.ast.statement.SQLSelectItem) JdbcRowMetaData(io.mycat.beans.mycat.JdbcRowMetaData) ByteString(org.apache.calcite.avatica.util.ByteString) Collectors(java.util.stream.Collectors) Stream(java.util.stream.Stream) ModifyFromSql(io.mycat.hbt.ast.modify.ModifyFromSql) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) LocalDate(java.time.LocalDate) LogicalTableScan(org.apache.calcite.rel.logical.LogicalTableScan) RelOptTableImpl(org.apache.calcite.prepare.RelOptTableImpl) java.sql(java.sql) TableScan(org.apache.calcite.rel.core.TableScan) Distribution(io.mycat.calcite.rewriter.Distribution) java.util(java.util) io.mycat.hbt.ast.base(io.mycat.hbt.ast.base) LocalDateTime(java.time.LocalDateTime) DefaultConnection(io.mycat.datasource.jdbc.datasource.DefaultConnection) Filter(org.apache.calcite.rel.core.Filter) RelOptUtil(org.apache.calcite.plan.RelOptUtil) MycatLogicTable(io.mycat.calcite.table.MycatLogicTable) RelOptTable(org.apache.calcite.plan.RelOptTable) Partition(io.mycat.Partition) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.builder(com.google.common.collect.ImmutableList.builder) JdbcConnectionManager(io.mycat.datasource.jdbc.datasource.JdbcConnectionManager) org.apache.calcite.util(org.apache.calcite.util) SqlOperator(org.apache.calcite.sql.SqlOperator) SQLSelectQueryBlock(com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock) RelDataType(org.apache.calcite.rel.type.RelDataType) SQLUtils(com.alibaba.druid.sql.SQLUtils) Logger(org.slf4j.Logger) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) HBTOp(io.mycat.hbt.ast.HBTOp) MycatCalciteSupport(io.mycat.calcite.MycatCalciteSupport) RelNode(org.apache.calcite.rel.RelNode) SqlDialect(org.apache.calcite.sql.SqlDialect) JoinRelType(org.apache.calcite.rel.core.JoinRelType) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) SQLSelectStatement(com.alibaba.druid.sql.ast.statement.SQLSelectStatement) SqlAggFunction(org.apache.calcite.sql.SqlAggFunction) io.mycat.hbt.ast.query(io.mycat.hbt.ast.query) MycatTransientSQLTableScan(io.mycat.calcite.table.MycatTransientSQLTableScan) LogicalTableScan(org.apache.calcite.rel.logical.LogicalTableScan) TableScan(org.apache.calcite.rel.core.TableScan) Partition(io.mycat.Partition) Filter(org.apache.calcite.rel.core.Filter) MycatLogicTable(io.mycat.calcite.table.MycatLogicTable) Distribution(io.mycat.calcite.rewriter.Distribution) ByteString(org.apache.calcite.avatica.util.ByteString) RelOptTable(org.apache.calcite.plan.RelOptTable)

Example 4 with Distribution

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;
}
Also used : MySqlASTVisitorAdapter(com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter) Distribution(io.mycat.calcite.rewriter.Distribution) Pair(io.mycat.util.Pair) java.util(java.util) SQLUtils(com.alibaba.druid.sql.SQLUtils) SQLMethodInvokeExpr(com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr) io.mycat(io.mycat) ImmutableMap(com.google.common.collect.ImmutableMap) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Collectors(java.util.stream.Collectors) SQLRBORewriter(io.mycat.calcite.rewriter.SQLRBORewriter) MycatSQLExprTableSourceUtil(io.mycat.util.MycatSQLExprTableSourceUtil) MySqlASTVisitorAdapter(com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter) NameMap(io.mycat.util.NameMap) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) SQLExprTableSource(com.alibaba.druid.sql.ast.statement.SQLExprTableSource) SQLVariantRefExpr(com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr) SQLMethodInvokeExpr(com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr) ImmutableMap(com.google.common.collect.ImmutableMap) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Distribution(io.mycat.calcite.rewriter.Distribution) SQLVariantRefExpr(com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr) SQLExprTableSource(com.alibaba.druid.sql.ast.statement.SQLExprTableSource) Pair(io.mycat.util.Pair)

Example 5 with Distribution

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);
}
Also used : Distribution(io.mycat.calcite.rewriter.Distribution) ToString(lombok.ToString)

Aggregations

Distribution (io.mycat.calcite.rewriter.Distribution)5 ImmutableList (com.google.common.collect.ImmutableList)3 SQLUtils (com.alibaba.druid.sql.SQLUtils)2 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)2 GlobalTable (io.mycat.calcite.table.GlobalTable)2 NormalTable (io.mycat.calcite.table.NormalTable)2 ShardingTable (io.mycat.calcite.table.ShardingTable)2 java.util (java.util)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Collectors (java.util.stream.Collectors)2 SqlString (org.apache.calcite.sql.util.SqlString)2 SQLDataType (com.alibaba.druid.sql.ast.SQLDataType)1 SQLMethodInvokeExpr (com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr)1 SQLVariantRefExpr (com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr)1 SQLExprTableSource (com.alibaba.druid.sql.ast.statement.SQLExprTableSource)1 SQLSelectItem (com.alibaba.druid.sql.ast.statement.SQLSelectItem)1 SQLSelectQueryBlock (com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock)1 SQLSelectStatement (com.alibaba.druid.sql.ast.statement.SQLSelectStatement)1 MySqlASTVisitorAdapter (com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter)1 ImmutableList.builder (com.google.common.collect.ImmutableList.builder)1