Search in sources :

Example 16 with MycatView

use of io.mycat.calcite.logical.MycatView in project Mycat2 by MyCATApache.

the class SQLRBORewriter method aggregate.

public static Optional<RelNode> aggregate(RelNode original, Aggregate aggregate) {
    RelNode input = original;
    Distribution dataNodeInfo = null;
    MycatView view = null;
    ImmutableList<RelHint> hints = aggregate.getHints();
    if (input instanceof MycatView) {
        dataNodeInfo = ((MycatView) input).getDistribution();
        view = (MycatView) original;
        if (view.banPushdown()) {
            return Optional.empty();
        }
        input = ((MycatView) input).getRelNode();
    }
    if (dataNodeInfo == null) {
        return Optional.empty();
    }
    if (dataNodeInfo.type() == Distribution.Type.PHY || dataNodeInfo.type() == Distribution.Type.BROADCAST) {
        input = aggregate.copy(aggregate.getTraitSet(), ImmutableList.of(input));
        return Optional.of(view.changeTo(input, dataNodeInfo));
    } else {
        ImmutableBitSet groupSet = aggregate.getGroupSet();
        RelMetadataQuery metadataQuery = aggregate.getCluster().getMetadataQuery();
        IdentityHashMap<MycatLogicTable, Set<String>> shardingKeysMap = new IdentityHashMap<>();
        for (Integer integer : groupSet) {
            RelColumnOrigin columnOrigin = metadataQuery.getColumnOrigin(input, integer);
            if (columnOrigin == null || columnOrigin.isDerived()) {
                continue;
            }
            MycatLogicTable mycatLogicTable = columnOrigin.getOriginTable().unwrap(MycatLogicTable.class);
            if (mycatLogicTable == null || !mycatLogicTable.isSharding()) {
                continue;
            }
            ShardingTableHandler tableHandler = (ShardingTableHandler) mycatLogicTable.getTable();
            SimpleColumnInfo simpleColumnInfo = tableHandler.getColumns().get(columnOrigin.getOriginColumnOrdinal());
            if (simpleColumnInfo.isShardingKey()) {
                Set<String> shardingKeySet = shardingKeysMap.computeIfAbsent(mycatLogicTable, s -> new HashSet<>());
                shardingKeySet.add(simpleColumnInfo.getColumnName());
                if (tableHandler.function().requireShardingKeys(shardingKeySet)) {
                    input = aggregate.copy(aggregate.getTraitSet(), ImmutableList.of(input));
                    return Optional.of(view.changeTo(input, dataNodeInfo));
                }
            }
        }
        RelNode backup = input;
        if (!(input instanceof Union)) {
            input = LogicalUnion.create(ImmutableList.of(input, input), true);
            input = LogicalAggregate.create(input, aggregate.getHints(), aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList());
        }
        HepProgramBuilder hepProgram = new HepProgramBuilder();
        hepProgram.addMatchLimit(512);
        hepProgram.addRuleInstance(MycatAggregateUnionTransposeRule.Config.DEFAULT.toRule());
        HepPlanner planner = new HepPlanner(hepProgram.build());
        planner.setRoot(input);
        RelNode bestExp = planner.findBestExp();
        if (bestExp instanceof Aggregate) {
            Aggregate mergeAgg = (Aggregate) bestExp;
            if (mergeAgg.getInput() instanceof Union && mergeAgg.getInput(0).getInput(0) instanceof Aggregate) {
                MycatView multiView = view.changeTo(mergeAgg.getInput(0).getInput(0), dataNodeInfo);
                MycatHashAggregate mycatHashAggregate = MycatHashAggregate.create(mergeAgg.getTraitSet(), hints, multiView, mergeAgg.getGroupSet(), mergeAgg.getGroupSets(), mergeAgg.getAggCallList());
                return Optional.of(mycatHashAggregate);
            }
        }
        {
            return splitAggregate(view, aggregate);
        }
    }
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) ShardingTableHandler(io.mycat.router.ShardingTableHandler) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) HepProgramBuilder(org.apache.calcite.plan.hep.HepProgramBuilder) RelHint(org.apache.calcite.rel.hint.RelHint) HepPlanner(org.apache.calcite.plan.hep.HepPlanner) MycatView(io.mycat.calcite.logical.MycatView) MycatHashAggregate(io.mycat.calcite.physical.MycatHashAggregate) RelNode(org.apache.calcite.rel.RelNode) RelColumnOrigin(org.apache.calcite.rel.metadata.RelColumnOrigin) MycatHashAggregate(io.mycat.calcite.physical.MycatHashAggregate)

Example 17 with MycatView

use of io.mycat.calcite.logical.MycatView in project Mycat2 by MyCATApache.

the class SQLRBORewriter method project.

public static Optional<RelNode> project(RelNode original, Project project) {
    Distribution dataNodeInfo = null;
    RelNode input = original;
    MycatView mycatView = null;
    if (RexUtil.isIdentity(project.getProjects(), original.getRowType())) {
        // ProjectRemoveRule
        return Optional.empty();
    }
    if (input instanceof MycatView) {
        dataNodeInfo = ((MycatView) input).getDistribution();
        mycatView = (MycatView) original;
        input = ((MycatView) input).getRelNode();
        if (mycatView.banPushdown() && !(input instanceof Aggregate)) {
            return Optional.empty();
        }
        if (project.containsOver()) {
            if (dataNodeInfo.type() == Distribution.Type.PHY || (dataNodeInfo.type() == Distribution.Type.BROADCAST)) {
                input = project.copy(project.getTraitSet(), ImmutableList.of(input));
                return Optional.of(mycatView.changeTo(input, dataNodeInfo));
            }
        }
    }
    if (input instanceof QueryBuilder) {
        QueryBuilder queryBuilder = (QueryBuilder) input;
        Optional<QueryBuilder> builder = queryBuilder.project(ImmutableIntList.identity(project.getRowType().getFieldCount()).toIntArray());
        return (Optional) builder;
    }
    input = project.copy(project.getTraitSet(), ImmutableList.of(input));
    if (mycatView != null) {
        return Optional.of(mycatView.changeTo(input, dataNodeInfo));
    } else {
        return Optional.empty();
    }
}
Also used : MycatView(io.mycat.calcite.logical.MycatView) RelNode(org.apache.calcite.rel.RelNode) MycatHashAggregate(io.mycat.calcite.physical.MycatHashAggregate)

Example 18 with MycatView

use of io.mycat.calcite.logical.MycatView in project Mycat2 by MyCATApache.

the class SQLRBORewriter method sort.

public static Optional<RelNode> sort(RelNode original, Sort sort) {
    RelNode input = original;
    MycatView view = null;
    Distribution dataNodeInfo = null;
    if (input instanceof MycatView) {
        dataNodeInfo = ((MycatView) input).getDistribution();
        view = (MycatView) original;
        if (view.banPushdown()) {
            return Optional.empty();
        }
        input = ((MycatView) input).getRelNode();
    }
    if (dataNodeInfo == null) {
        return Optional.empty();
    }
    if (input instanceof QueryBuilder) {
        RexNode fetchRex = sort.fetch;
        RexNode offsetRex = sort.offset;
        Long fetchNumber = Long.MAX_VALUE;
        Long offsetNumber = 0L;
        RelCollation collation = sort.getCollation();
        QueryBuilder mycatCustomTable = (QueryBuilder) input;
        if (fetchRex instanceof RexLiteral) {
            Object fetchValue = ((RexLiteral) fetchRex).getValue();
            if (fetchValue != null && fetchValue instanceof Number) {
                fetchNumber = ((Number) fetchValue).longValue();
            }
        }
        if (offsetRex instanceof RexLiteral) {
            Object offsetValue = ((RexLiteral) offsetRex).getValue();
            if (offsetValue != null && offsetValue instanceof Number) {
                offsetNumber = ((Number) offsetValue).longValue();
            }
        }
        Optional<QueryBuilder> queryBuilder = mycatCustomTable.sort(offsetNumber, fetchNumber, collation);
        if (queryBuilder.isPresent()) {
            return Optional.of(queryBuilder.get());
        }
        return Optional.of(sort.copy(sort.getTraitSet().replace(MycatConvention.INSTANCE), mycatCustomTable, collation));
    }
    if (dataNodeInfo.type() == Distribution.Type.PHY || dataNodeInfo.type() == Distribution.Type.BROADCAST) {
        input = sort.copy(input.getTraitSet(), ImmutableList.of(input));
        return Optional.of(view.changeTo(input, dataNodeInfo));
    } else {
        if (sort.offset == null && sort.fetch == null) {
            input = LogicalSort.create(input, sort.getCollation(), null, null);
            input = view.changeTo(LocalSort.create((LogicalSort) input, ((LogicalSort) input).getInput()), dataNodeInfo);
            return Optional.of(input);
        }
        RexBuilder rexBuilder = MycatCalciteSupport.INSTANCE.RexBuilder;
        RexNode rexNode;
        if (sort.offset == null && sort.fetch != null) {
            rexNode = sort.fetch;
        } else if (sort.offset != null && sort.fetch == null) {
            rexNode = sort.offset;
        } else {
            if (sort.offset instanceof RexLiteral && sort.fetch instanceof RexLiteral) {
                BigDecimal decimal = ((RexLiteral) sort.offset).getValueAs(BigDecimal.class).add(((RexLiteral) sort.fetch).getValueAs(BigDecimal.class));
                rexNode = rexBuilder.makeExactLiteral(decimal);
            } else {
                rexNode = rexBuilder.makeCall(SqlStdOperatorTable.PLUS, sort.offset, sort.fetch);
            }
        }
        input = LogicalSort.create(input, sort.getCollation(), rexBuilder.makeExactLiteral(BigDecimal.ZERO), rexNode);
        input = view.changeTo(LocalSort.create((LogicalSort) input, ((LogicalSort) input).getInput()), dataNodeInfo);
        return Optional.of(input);
    }
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) BigDecimal(java.math.BigDecimal) MycatView(io.mycat.calcite.logical.MycatView) RelCollation(org.apache.calcite.rel.RelCollation) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 19 with MycatView

use of io.mycat.calcite.logical.MycatView in project Mycat2 by MyCATApache.

the class SQLRBORewriter method filter.

public static Optional<RelNode> filter(RelNode original, Filter filter) {
    RelNode input = original;
    Distribution dataNodeInfo = null;
    MycatView view = null;
    if (input instanceof MycatView) {
        dataNodeInfo = ((MycatView) input).getDistribution();
        view = (MycatView) original;
        if (view.banPushdown()) {
            return Optional.empty();
        }
        input = ((MycatView) input).getRelNode();
    }
    if (input instanceof TableScan) {
        RexNode condition = filter.getCondition();
        RelOptTable table = input.getTable();
        MycatLogicTable mycatTable = table.unwrap(MycatLogicTable.class);
        return Optional.of(MycatView.ofCondition(filter.copy(filter.getTraitSet(), input, condition), mycatTable.createDistribution(), (condition)));
    }
    if (input instanceof QueryBuilder) {
        QueryBuilder queryBuilder = (QueryBuilder) input;
        return (Optional<RelNode>) (Optional) queryBuilder.filter(filter.getCondition());
    }
    filter = (Filter) filter.copy(filter.getTraitSet(), ImmutableList.of(input));
    if (view != null) {
        return Optional.of(view.changeTo(filter, dataNodeInfo));
    } else {
        return Optional.empty();
    }
}
Also used : MycatView(io.mycat.calcite.logical.MycatView) RelNode(org.apache.calcite.rel.RelNode) RelOptTable(org.apache.calcite.plan.RelOptTable) RexNode(org.apache.calcite.rex.RexNode)

Example 20 with MycatView

use of io.mycat.calcite.logical.MycatView in project Mycat2 by MyCATApache.

the class SQLRBORewriter method view.

public static Optional<RelNode> view(List<RelNode> inputs, Union union) {
    List<RelNode> backup = new ArrayList<>(inputs);
    List<RelNode> children = new ArrayList<>();
    for (RelNode input : inputs) {
        if (input instanceof LogicalUnion) {
            Union bottomUnion = (Union) input;
            children.addAll(bottomUnion.getInputs());
        } else {
            children.add(input);
        }
    }
    inputs = children;
    List<MycatView> inputViews = new LinkedList<>();
    List<RelNode> newViews = new ArrayList<>();
    List<RelNode> others = new ArrayList<>();
    for (RelNode input : inputs) {
        if (input instanceof MycatView && !((MycatView) input).banPushdown()) {
            MycatView curView = (MycatView) input;
            if (curView.getDistribution().type() == Distribution.Type.SHARDING) {
                if (!unionAllInPartitonKey(curView)) {
                    return Optional.empty();
                }
            }
            inputViews.add((MycatView) input);
        } else {
            others.add(input);
        }
    }
    if (inputViews.isEmpty()) {
        return Optional.empty();
    }
    if (inputViews.size() > 1 && inputViews.stream().mapToInt(i -> i.getDistribution().getShardingTables().size()).sum() < 2) {
        MycatView left = inputViews.get(0);
        List<MycatView> matchViews = new ArrayList<>();
        matchViews.add(left);
        List<MycatView> failViews = new ArrayList<>();
        Distribution distribution = null;
        for (MycatView right : inputViews.subList(1, inputViews.size())) {
            Optional<Distribution> distributionOptional = left.getDistribution().join(right.getDistribution());
            if (distributionOptional.isPresent()) {
                distribution = distributionOptional.get();
                Distribution.Type type = distribution.type();
                if (type == Distribution.Type.PHY || type == Distribution.Type.BROADCAST) {
                    matchViews.add(right);
                    continue;
                } else if (type == Distribution.Type.SHARDING && unionAllInPartitonKey(left) && unionAllInPartitonKey(right) && left.getDistribution().getTargets().equals(right.getDistribution().getTargets())) {
                    matchViews.add(right);
                    continue;
                }
            }
            failViews.add(right);
        }
        if (distribution != null) {
            newViews.add(left.changeTo(union.copy(union.getTraitSet(), (List) matchViews.stream().map(i -> i.getRelNode()).collect(Collectors.toList())), distribution));
        } else {
            newViews.addAll(matchViews);
        }
        newViews.addAll(failViews);
    } else {
        newViews.addAll(inputViews);
    }
    inputs = (List) ImmutableList.builder().addAll(newViews).addAll(others).build();
    if (inputs.size() == 1) {
        return Optional.of(inputs.get(0));
    }
    if (backup.equals(inputs)) {
        return Optional.empty();
    }
    return Optional.of(union.copy(union.getTraitSet(), inputs));
}
Also used : io.mycat(io.mycat) RelShuttleImpl(org.apache.calcite.rel.RelShuttleImpl) LoggerFactory(org.slf4j.LoggerFactory) MycatSortMergeJoin(io.mycat.calcite.physical.MycatSortMergeJoin) IntPair(org.apache.calcite.util.mapping.IntPair) ShardingTableHandler(io.mycat.router.ShardingTableHandler) BigDecimal(java.math.BigDecimal) RexUtil(org.apache.calcite.rex.RexUtil) RexNode(org.apache.calcite.rex.RexNode) RelBuilder(org.apache.calcite.tools.RelBuilder) RelHint(org.apache.calcite.rel.hint.RelHint) org.apache.calcite.rel.logical(org.apache.calcite.rel.logical) RelOptCluster(org.apache.calcite.plan.RelOptCluster) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) MycatView(io.mycat.calcite.logical.MycatView) RexLiteral(org.apache.calcite.rex.RexLiteral) MycatConvention(io.mycat.calcite.MycatConvention) MycatMergeJoinRule(io.mycat.calcite.rules.MycatMergeJoinRule) Collectors(java.util.stream.Collectors) ServerConfig(io.mycat.config.ServerConfig) QueryType(io.mycat.querycondition.QueryType) RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) SqlStdOperatorTable(org.apache.calcite.sql.fun.SqlStdOperatorTable) RelCollation(org.apache.calcite.rel.RelCollation) LocalRules(io.mycat.calcite.localrel.LocalRules) NotNull(org.jetbrains.annotations.NotNull) java.util(java.util) CustomRuleFunction(io.mycat.router.CustomRuleFunction) MycatHashAggregate(io.mycat.calcite.physical.MycatHashAggregate) NumberFormat(java.text.NumberFormat) RelOptTable(org.apache.calcite.plan.RelOptTable) ImmutableList(com.google.common.collect.ImmutableList) Pair(org.apache.calcite.util.Pair) RelColumnOrigin(org.apache.calcite.rel.metadata.RelColumnOrigin) io.mycat.calcite.table(io.mycat.calcite.table) org.apache.calcite.rel.core(org.apache.calcite.rel.core) RelOptListener(org.apache.calcite.plan.RelOptListener) Logger(org.slf4j.Logger) RexBuilder(org.apache.calcite.rex.RexBuilder) MycatProject(io.mycat.calcite.physical.MycatProject) MycatCalciteSupport(io.mycat.calcite.MycatCalciteSupport) HepPlanner(org.apache.calcite.plan.hep.HepPlanner) HepProgramBuilder(org.apache.calcite.plan.hep.HepProgramBuilder) RelNode(org.apache.calcite.rel.RelNode) LocalSort(io.mycat.calcite.localrel.LocalSort) NameMap(io.mycat.util.NameMap) RelOptSchema(org.apache.calcite.plan.RelOptSchema) MycatAggregateUnionTransposeRule(io.mycat.calcite.localrel.MycatAggregateUnionTransposeRule) MycatView(io.mycat.calcite.logical.MycatView) RelNode(org.apache.calcite.rel.RelNode)

Aggregations

MycatView (io.mycat.calcite.logical.MycatView)29 RelNode (org.apache.calcite.rel.RelNode)21 RexNode (org.apache.calcite.rex.RexNode)9 RelBuilder (org.apache.calcite.tools.RelBuilder)8 RelOptCluster (org.apache.calcite.plan.RelOptCluster)7 RelHint (org.apache.calcite.rel.hint.RelHint)7 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)7 NotNull (org.jetbrains.annotations.NotNull)7 MycatSQLTableLookup (io.mycat.calcite.physical.MycatSQLTableLookup)6 Collectors (java.util.stream.Collectors)6 ImmutableList (com.google.common.collect.ImmutableList)5 RelCollation (org.apache.calcite.rel.RelCollation)5 RelShuttleImpl (org.apache.calcite.rel.RelShuttleImpl)5 RexBuilder (org.apache.calcite.rex.RexBuilder)5 MycatProject (io.mycat.calcite.physical.MycatProject)4 Join (org.apache.calcite.rel.core.Join)4 JoinRelType (org.apache.calcite.rel.core.JoinRelType)4 RelDataType (org.apache.calcite.rel.type.RelDataType)4 SqlString (org.apache.calcite.sql.util.SqlString)4 io.mycat (io.mycat)3