Search in sources :

Example 1 with MycatSortMergeJoin

use of io.mycat.calcite.physical.MycatSortMergeJoin in project Mycat2 by MyCATApache.

the class SQLRBORewriter method tryMergeJoin.

@NotNull
public static Optional<RelNode> tryMergeJoin(RelNode left, RelNode right, Join join) {
    if (!DrdsSqlCompiler.RBO_MERGE_JOIN) {
        return Optional.empty();
    }
    boolean isleftView = left instanceof MycatView;
    boolean isRightView = right instanceof MycatView;
    if (isleftView && isRightView) {
        if (((MycatView) left).banPushdown() || ((MycatView) right).banPushdown()) {
            return Optional.empty();
        }
        MycatSortMergeJoin mycatSortMergeJoin = MycatMergeJoinRule.INSTANCE.tryMycatSortMergeJoin(join.copy(join.getTraitSet(), ImmutableList.of(left, right)), true);
        return Optional.ofNullable(mycatSortMergeJoin);
    } else {
        return Optional.empty();
    }
}
Also used : MycatView(io.mycat.calcite.logical.MycatView) MycatSortMergeJoin(io.mycat.calcite.physical.MycatSortMergeJoin) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with MycatSortMergeJoin

use of io.mycat.calcite.physical.MycatSortMergeJoin in project Mycat2 by MyCATApache.

the class MycatMergeJoinRule method tryMycatSortMergeJoin.

@Nullable
public MycatSortMergeJoin tryMycatSortMergeJoin(Join rel, boolean rbo) {
    if (!DrdsSqlCompiler.RBO_MERGE_JOIN) {
        return null;
    }
    RelHint lastJoinHint = HintTools.getLastJoinHint(rel.getHints());
    if (lastJoinHint != null) {
        switch(lastJoinHint.hintName.toLowerCase()) {
            case "use_hash_join":
            case "use_bka_join":
            case "use_nl_join":
                return null;
            case "use_merge_join":
            default:
        }
    }
    try {
        Join join = rel;
        final JoinInfo info = join.analyzeCondition();
        if (!EnumerableMergeJoin.isMergeJoinSupported(join.getJoinType())) {
            // EnumerableMergeJoin only supports certain join types.
            return null;
        }
        if (info.pairs().size() == 0) {
            // EnumerableMergeJoin CAN support cartesian join, but disable it for now.
            return null;
        }
        final List<RelNode> newInputs = new ArrayList<>();
        final List<RelCollation> collations = new ArrayList<>();
        int offset = 0;
        for (Ord<RelNode> ord : Ord.zip(join.getInputs())) {
            RelTraitSet traits = ord.e.getTraitSet().replace(MycatConvention.INSTANCE);
            if (!info.pairs().isEmpty()) {
                final List<RelFieldCollation> fieldCollations = new ArrayList<>();
                for (int key : info.keys().get(ord.i)) {
                    fieldCollations.add(new RelFieldCollation(key, RelFieldCollation.Direction.ASCENDING, RelFieldCollation.NullDirection.LAST));
                }
                final RelCollation collation = RelCollations.of(fieldCollations);
                collations.add(RelCollations.shift(collation, offset));
                traits = traits.replace(collation);
            }
            newInputs.add(convert(ord.e, traits, rbo));
            offset += ord.e.getRowType().getFieldCount();
        }
        final RelNode left = newInputs.get(0);
        final RelNode right = newInputs.get(1);
        final RelOptCluster cluster = join.getCluster();
        RelNode newRel;
        RelTraitSet traitSet = join.getTraitSet().replace(MycatConvention.INSTANCE);
        if (!collations.isEmpty()) {
            traitSet = traitSet.replace(collations);
        }
        // Re-arrange condition: first the equi-join elements, then the non-equi-join ones (if any);
        // this is not strictly necessary but it will be useful to avoid spurious errors in the
        // unit tests when verifying the plan.
        final RexBuilder rexBuilder = join.getCluster().getRexBuilder();
        final RexNode equi = info.getEquiCondition(left, right, rexBuilder);
        final RexNode condition;
        if (info.isEqui()) {
            condition = equi;
        } else {
            final RexNode nonEqui = RexUtil.composeConjunction(rexBuilder, info.nonEquiConditions);
            condition = RexUtil.composeConjunction(rexBuilder, Arrays.asList(equi, nonEqui));
        }
        if (!join.isSemiJoin()) {
            return MycatSortMergeJoin.create(traitSet, join.getHints(), convert(left, out), convert(right, out), condition, join.getJoinType());
        } else {
            return MycatSortMergeSemiJoin.create(traitSet, join.getHints(), convert(left, out), convert(right, out), condition, join.getJoinType());
        }
    } catch (Throwable throwable) {
        LOGGER.error(this.description, throwable);
    }
    return null;
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) ArrayList(java.util.ArrayList) MycatSortMergeJoin(io.mycat.calcite.physical.MycatSortMergeJoin) Join(org.apache.calcite.rel.core.Join) MycatSortMergeSemiJoin(io.mycat.calcite.physical.MycatSortMergeSemiJoin) EnumerableMergeJoin(org.apache.calcite.adapter.enumerable.EnumerableMergeJoin) RelTraitSet(org.apache.calcite.plan.RelTraitSet) RelHint(org.apache.calcite.rel.hint.RelHint) RelHint(org.apache.calcite.rel.hint.RelHint) JoinInfo(org.apache.calcite.rel.core.JoinInfo) RelCollation(org.apache.calcite.rel.RelCollation) RelNode(org.apache.calcite.rel.RelNode) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

MycatSortMergeJoin (io.mycat.calcite.physical.MycatSortMergeJoin)2 MycatView (io.mycat.calcite.logical.MycatView)1 MycatSortMergeSemiJoin (io.mycat.calcite.physical.MycatSortMergeSemiJoin)1 ArrayList (java.util.ArrayList)1 EnumerableMergeJoin (org.apache.calcite.adapter.enumerable.EnumerableMergeJoin)1 RelOptCluster (org.apache.calcite.plan.RelOptCluster)1 RelTraitSet (org.apache.calcite.plan.RelTraitSet)1 RelCollation (org.apache.calcite.rel.RelCollation)1 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)1 RelNode (org.apache.calcite.rel.RelNode)1 Join (org.apache.calcite.rel.core.Join)1 JoinInfo (org.apache.calcite.rel.core.JoinInfo)1 RelHint (org.apache.calcite.rel.hint.RelHint)1 RexBuilder (org.apache.calcite.rex.RexBuilder)1 RexNode (org.apache.calcite.rex.RexNode)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1