Search in sources :

Example 1 with MycatSQLTableLookup

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

the class MycatJoinTableLookupTransposeRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    Join join = call.rel(0);
    RelDataType originalRowType = join.getRowType();
    RelOptCluster cluster = join.getCluster();
    RelNode outerLeft = call.rel(1);
    RelNode outerRight = call.rel(2);
    if (outerLeft instanceof MycatSQLTableLookup) {
        MycatSQLTableLookup mycatSQLTableLookup = (MycatSQLTableLookup) outerLeft;
        if (mycatSQLTableLookup.getType() == MycatSQLTableLookup.Type.BACK) {
            int fieldCount = mycatSQLTableLookup.getInput().getRowType().getFieldCount();
            if (join.analyzeCondition().leftSet().asList().stream().allMatch(i -> i < fieldCount)) {
                // 与最左表无关
                RelNode bottomInput = mycatSQLTableLookup.getInput();
                MycatView indexRightView = (MycatView) mycatSQLTableLookup.getRight();
                RelNode newInputJoin = join.copy(bottomInput.getTraitSet(), ImmutableList.of(bottomInput, outerRight));
                MycatSQLTableLookup newMycatSQLTableLookup = new MycatSQLTableLookup(join.getCluster(), join.getTraitSet(), newInputJoin, indexRightView, mycatSQLTableLookup.getJoinType(), mycatSQLTableLookup.getCondition(), mycatSQLTableLookup.getCorrelationIds(), mycatSQLTableLookup.getType());
                fixProject(originalRowType, newMycatSQLTableLookup, call.builder()).ifPresent(res -> {
                    call.transformTo(res);
                });
                return;
            }
        }
    }
    if (outerRight instanceof MycatSQLTableLookup) {
        MycatSQLTableLookup mycatSQLTableLookup = (MycatSQLTableLookup) outerRight;
        MycatView indexRightView = (MycatView) mycatSQLTableLookup.getRight();
        RelNode newInputJoin = join.copy(outerLeft.getTraitSet(), ImmutableList.of(mycatSQLTableLookup.getInput(), indexRightView));
        if (mycatSQLTableLookup.getType() == MycatSQLTableLookup.Type.BACK) {
            int fieldCount = mycatSQLTableLookup.getInput().getRowType().getFieldCount();
            if (join.analyzeCondition().rightSet().asList().stream().allMatch(i -> i > fieldCount)) {
                // 最右回表无关
                MycatSQLTableLookup newMycatSQLTableLookup = new MycatSQLTableLookup(join.getCluster(), join.getTraitSet(), newInputJoin, indexRightView, mycatSQLTableLookup.getJoinType(), mycatSQLTableLookup.getCondition(), mycatSQLTableLookup.getCorrelationIds(), mycatSQLTableLookup.getType());
                fixProject(originalRowType, newMycatSQLTableLookup, call.builder()).ifPresent(res -> {
                    call.transformTo(res);
                });
                return;
            }
        }
    }
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) MycatSQLTableLookup(io.mycat.calcite.physical.MycatSQLTableLookup) MycatView(io.mycat.calcite.logical.MycatView) RelNode(org.apache.calcite.rel.RelNode) Join(org.apache.calcite.rel.core.Join) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 2 with MycatSQLTableLookup

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

the class MycatValuesJoinRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    Join join = call.rel(0);
    RelHint lastJoinHint = HintTools.getLastJoinHint(join.getHints());
    if (lastJoinHint != null) {
        if (!"use_values_join".equalsIgnoreCase(lastJoinHint.hintName)) {
            return;
        }
    } else {
        return;
    }
    RelOptCluster cluster = join.getCluster();
    RelNode left = call.rel(1);
    RelNode right = call.rel(2);
    JoinInfo joinInfo = join.analyzeCondition();
    if (!joinInfo.isEqui()) {
        return;
    }
    if (!(right instanceof MycatView)) {
        return;
    }
    MycatView mycatView = (MycatView) right;
    if (mycatView.banPushdown()) {
        return;
    }
    JoinRelType joinType = join.getJoinType();
    switch(joinType) {
        case INNER:
        case SEMI:
        case LEFT:
        case RIGHT:
            break;
        default:
            return;
    }
    if (RelOptUtil.countJoins(mycatView.getRelNode()) > 1) {
        return;
    }
    RexBuilder rexBuilder = MycatCalciteSupport.RexBuilder;
    RelDataTypeFactory typeFactory = cluster.getTypeFactory();
    List<RexNode> leftExprs = new ArrayList<>();
    List<CorrelationId> correlationIds = new ArrayList<>();
    {
        for (Integer leftKey : join.analyzeCondition().leftSet()) {
            CorrelationId correl = cluster.createCorrel();
            correlationIds.add(correl);
            RelDataType type = left.getRowType().getFieldList().get(leftKey).getType();
            RexNode rexNode = rexBuilder.makeCorrel(typeFactory.createSqlType(SqlTypeName.VARCHAR), correl);
            leftExprs.add(rexBuilder.makeCast(type, rexNode));
        }
    }
    switch(mycatView.getDistribution().type()) {
        case PHY:
        case BROADCAST:
            RelBuilder builder = call.builder();
            builder.push(MycatTableLookupValues.create(cluster, left.getRowType(), leftExprs, left.getTraitSet())).push(mycatView.getRelNode()).join(joinType, join.getCondition());
            MycatView view = mycatView.changeTo(builder.build());
            MycatSQLTableLookup mycatSQLTableLookup = new MycatSQLTableLookup(cluster, join.getTraitSet(), left, view, joinType, join.getCondition(), correlationIds, MycatSQLTableLookup.Type.NONE);
            call.transformTo(mycatSQLTableLookup);
            break;
        default:
    }
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelBuilder(org.apache.calcite.tools.RelBuilder) ArrayList(java.util.ArrayList) Join(org.apache.calcite.rel.core.Join) RelDataType(org.apache.calcite.rel.type.RelDataType) RelHint(org.apache.calcite.rel.hint.RelHint) JoinInfo(org.apache.calcite.rel.core.JoinInfo) JoinRelType(org.apache.calcite.rel.core.JoinRelType) MycatSQLTableLookup(io.mycat.calcite.physical.MycatSQLTableLookup) MycatView(io.mycat.calcite.logical.MycatView) RelNode(org.apache.calcite.rel.RelNode) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with MycatSQLTableLookup

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

the class PlanImpl method specificSql.

@NotNull
public List<SpecificSql> specificSql(DrdsSqlWithParams drdsSql, int mergeUnionSize) {
    List<SpecificSql> res = new ArrayList<>();
    getMycatRel().accept(new RelShuttleImpl() {

        @Override
        protected RelNode visitChildren(RelNode relNode) {
            List<Each> sqls = new ArrayList<>();
            String parameterizedSql = "";
            if (relNode instanceof MycatView) {
                MycatView view = (MycatView) relNode;
                SqlNode sqlTemplate = view.getSQLTemplate(false);
                ImmutableMultimap<String, SqlString> apply = view.apply(mergeUnionSize, sqlTemplate, AsyncMycatDataContextImpl.getSqlMap(executerContext.getConstantMap(), view, drdsSql, drdsSql.getHintDataNodeFilter()), drdsSql.getParams());
                ImmutableMultimap<String, SqlString> stringImmutableMultimap = apply;
                for (Map.Entry<String, SqlString> entry : (stringImmutableMultimap.entries())) {
                    SqlString sqlString = new SqlString(entry.getValue().getDialect(), (Util.toLinux(entry.getValue().getSql())), entry.getValue().getDynamicParameters());
                    sqls.add(new Each(entry.getKey(), sqlString.getSql()));
                }
                if (relNode instanceof MycatView) {
                    parameterizedSql = ((MycatView) relNode).getSql();
                }
                if (relNode instanceof MycatTransientSQLTableScan) {
                    parameterizedSql = ((MycatTransientSQLTableScan) relNode).getSql();
                }
                res.add(new SpecificSql(relNode.getDigest(), parameterizedSql, sqls));
            } else if (relNode instanceof MycatSQLTableLookup) {
                MycatView right = ((MycatSQLTableLookup) relNode).getRight();
                right.accept(this);
            }
            return super.visitChildren(relNode);
        }
    });
    return res;
}
Also used : MycatTransientSQLTableScan(io.mycat.calcite.table.MycatTransientSQLTableScan) RelShuttleImpl(org.apache.calcite.rel.RelShuttleImpl) SqlString(org.apache.calcite.sql.util.SqlString) SqlString(org.apache.calcite.sql.util.SqlString) MycatSQLTableLookup(io.mycat.calcite.physical.MycatSQLTableLookup) MycatView(io.mycat.calcite.logical.MycatView) RelNode(org.apache.calcite.rel.RelNode) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) SqlNode(org.apache.calcite.sql.SqlNode) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with MycatSQLTableLookup

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

the class MycatTableLookupSemiJoinRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    Join join = call.rel(0);
    RelOptCluster cluster = join.getCluster();
    RelNode left = call.rel(1);
    RelNode right = call.rel(2);
    RelMetadataQuery metadataQuery = cluster.getMetadataQuery();
    RelHint lastJoinHint = HintTools.getLastJoinHint(join.getHints());
    // if (lastJoinHint == null){
    // return;
    // }
    boolean hint = false;
    if (lastJoinHint != null && "use_bka_join".equalsIgnoreCase(lastJoinHint.hintName)) {
        hint = true;
    } else {
        double leftRowCount = Optional.ofNullable(metadataQuery.getRowCount(left)).orElse(0.0);
        if (leftRowCount > BKA_JOIN_LEFT_ROW_COUNT_LIMIT) {
            return;
        }
    }
    if (!join.analyzeCondition().isEqui()) {
        return;
    }
    if (!(right instanceof MycatView)) {
        return;
    }
    MycatView mycatView = (MycatView) right;
    if (mycatView.banPushdown()) {
        return;
    }
    if (!hint) {
        if (!isGisView(mycatView))
            return;
    }
    JoinRelType joinType = join.getJoinType();
    switch(joinType) {
        case LEFT:
        case INNER:
        case SEMI:
            break;
        default:
            return;
    }
    if (RelOptUtil.countJoins(mycatView.getRelNode()) > 1) {
        return;
    }
    RelBuilder relBuilder = MycatCalciteSupport.relBuilderFactory.create(cluster, null);
    // 
    // ImmutableList.Builder<RelDataTypeField> listBuilder = ImmutableList.builder();
    // Map<Integer, Integer> sourcePosToTargetPos = new HashMap<>();
    // extractedTrimJoinLeftKeys(join, listBuilder, sourcePosToTargetPos);
    // RelRecordType argTypeListRecordType = new RelRecordType(listBuilder.build());
    // Mapping mapping = Mappings.bijection(sourcePosToTargetPos);
    // RexNode equiCondition = RexUtil.apply(mapping, RelOptUtil.createEquiJoinCondition(right, join.analyzeCondition().rightKeys, left, join.analyzeCondition().leftKeys,
    // MycatCalciteSupport.RexBuilder));
    RexBuilder rexBuilder = MycatCalciteSupport.RexBuilder;
    RelDataTypeFactory typeFactory = cluster.getTypeFactory();
    relBuilder.push(right);
    List<RexNode> rightExprs = new ArrayList<>();
    {
        for (Integer rightKey : join.analyzeCondition().rightSet()) {
            rightExprs.add(relBuilder.field(rightKey));
        }
    }
    List<RexNode> leftExprs = new ArrayList<>();
    List<CorrelationId> correlationIds = new ArrayList<>();
    {
        for (Integer leftKey : join.analyzeCondition().leftSet()) {
            CorrelationId correl = cluster.createCorrel();
            correlationIds.add(correl);
            RelDataType type = left.getRowType().getFieldList().get(leftKey).getType();
            RexNode rexNode = rexBuilder.makeCorrel(typeFactory.createUnknownType(), correl);
            leftExprs.add(rexBuilder.makeCast(type, rexNode));
        }
    }
    RexNode condition = relBuilder.call(MYCAT_SQL_LOOKUP_IN, rexBuilder.makeCall(SqlStdOperatorTable.ROW, rightExprs), rexBuilder.makeCall(SqlStdOperatorTable.ROW, leftExprs));
    Distribution.Type type = mycatView.getDistribution().type();
    switch(type) {
        case PHY:
        case BROADCAST:
            {
                RelNode relNode = mycatView.getRelNode();
                relBuilder.push(relNode);
                relBuilder.filter(condition);
                relBuilder.rename(mycatView.getRowType().getFieldNames());
                MycatView view = mycatView.changeTo(relBuilder.build());
                call.transformTo(new MycatSQLTableLookup(cluster, join.getTraitSet(), left, view, joinType, join.getCondition(), correlationIds, MycatSQLTableLookup.Type.BACK));
                return;
            }
        case SHARDING:
            {
                RelNode innerRelNode = mycatView.getRelNode();
                boolean bottomFilter = innerRelNode instanceof TableScan;
                relBuilder.push(mycatView.getRelNode());
                relBuilder.filter(condition);
                RelNode innerDataNode = relBuilder.rename(mycatView.getRowType().getFieldNames()).build();
                Optional<RexNode> viewConditionOptional = mycatView.getCondition();
                RexNode finalCondition = null;
                if (!viewConditionOptional.isPresent() && bottomFilter) {
                    finalCondition = condition;
                } else if (bottomFilter) {
                    finalCondition = viewConditionOptional.map(i -> RexUtil.composeConjunction(MycatCalciteSupport.RexBuilder, ImmutableList.of(i, condition))).orElse(condition);
                }
                MycatView resView = MycatView.ofCondition(innerDataNode, mycatView.getDistribution(), finalCondition);
                call.transformTo(new MycatSQLTableLookup(cluster, join.getTraitSet(), left, resView, joinType, join.getCondition(), correlationIds, MycatSQLTableLookup.Type.BACK));
                break;
            }
        default:
    }
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) TableScan(org.apache.calcite.rel.core.TableScan) RelBuilder(org.apache.calcite.tools.RelBuilder) Optional(java.util.Optional) ArrayList(java.util.ArrayList) Join(org.apache.calcite.rel.core.Join) RelDataType(org.apache.calcite.rel.type.RelDataType) RelHint(org.apache.calcite.rel.hint.RelHint) JoinRelType(org.apache.calcite.rel.core.JoinRelType) MycatSQLTableLookup(io.mycat.calcite.physical.MycatSQLTableLookup) MycatView(io.mycat.calcite.logical.MycatView) RelNode(org.apache.calcite.rel.RelNode) Distribution(io.mycat.calcite.rewriter.Distribution) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexNode(org.apache.calcite.rex.RexNode)

Example 5 with MycatSQLTableLookup

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

the class MycatTableLookupCombineRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    Join join = call.rel(0);
    RelOptCluster cluster = join.getCluster();
    MycatSQLTableLookup left = call.rel(1);
    if (left.getType() != MycatSQLTableLookup.Type.NONE) {
        return;
    }
    RelNode right = call.rel(2);
    JoinInfo joinInfo = join.analyzeCondition();
    if (!(right instanceof MycatView)) {
        return;
    }
    MycatView inneRightMycatView = (MycatView) left.getRight();
    MycatView outerRightmycatView = (MycatView) right;
    if (outerRightmycatView.banPushdown()) {
        return;
    }
    JoinRelType joinType = join.getJoinType();
    switch(joinType) {
        case INNER:
        case SEMI:
            break;
        default:
            return;
    }
    if (RelOptUtil.countJoins(outerRightmycatView.getRelNode()) > 1) {
        return;
    }
    switch(outerRightmycatView.getDistribution().type()) {
        case PHY:
        case BROADCAST:
            {
                RelBuilder builder = call.builder();
                inneRightMycatView.getDistribution().join(outerRightmycatView.getDistribution()).ifPresent(c -> {
                    RelBuilder relBuilder = builder.push(inneRightMycatView.getRelNode()).push(outerRightmycatView.getRelNode()).join(joinType, join.getCondition());
                    RelNode relNode = relBuilder.build();
                    MycatView view = MycatView.ofCondition(relNode, c, null);
                    call.transformTo(left.changeTo(left.getInput(0), view));
                });
                break;
            }
        case SHARDING:
            {
                SQLRBORewriter.bottomJoin(inneRightMycatView, outerRightmycatView, join).ifPresent(relNode1 -> {
                    call.transformTo(left.changeTo(left.getInput(0), (MycatView) relNode1));
                });
                break;
            }
        default:
    }
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) JoinInfo(org.apache.calcite.rel.core.JoinInfo) RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelBuilder(org.apache.calcite.tools.RelBuilder) MycatView(io.mycat.calcite.logical.MycatView) JoinRelType(org.apache.calcite.rel.core.JoinRelType) RelRule(org.apache.calcite.plan.RelRule) RelNode(org.apache.calcite.rel.RelNode) RelOptUtil(org.apache.calcite.plan.RelOptUtil) JoinInfo(org.apache.calcite.rel.core.JoinInfo) MycatSQLTableLookup(io.mycat.calcite.physical.MycatSQLTableLookup) RelOptRuleCall(org.apache.calcite.plan.RelOptRuleCall) Join(org.apache.calcite.rel.core.Join) SQLRBORewriter(io.mycat.calcite.rewriter.SQLRBORewriter) MycatSQLTableLookup(io.mycat.calcite.physical.MycatSQLTableLookup) JoinRelType(org.apache.calcite.rel.core.JoinRelType) MycatView(io.mycat.calcite.logical.MycatView) RelBuilder(org.apache.calcite.tools.RelBuilder) RelNode(org.apache.calcite.rel.RelNode) Join(org.apache.calcite.rel.core.Join)

Aggregations

MycatView (io.mycat.calcite.logical.MycatView)6 MycatSQLTableLookup (io.mycat.calcite.physical.MycatSQLTableLookup)6 RelNode (org.apache.calcite.rel.RelNode)6 RelOptCluster (org.apache.calcite.plan.RelOptCluster)4 Join (org.apache.calcite.rel.core.Join)4 JoinRelType (org.apache.calcite.rel.core.JoinRelType)3 RexNode (org.apache.calcite.rex.RexNode)3 RelBuilder (org.apache.calcite.tools.RelBuilder)3 MycatTransientSQLTableScan (io.mycat.calcite.table.MycatTransientSQLTableScan)2 ArrayList (java.util.ArrayList)2 RelDataType (org.apache.calcite.rel.type.RelDataType)2 ImmutableMultimap (com.google.common.collect.ImmutableMultimap)1 CopyMycatRowMetaData (io.mycat.beans.mycat.CopyMycatRowMetaData)1 MySQLErrorCode (io.mycat.beans.mysql.MySQLErrorCode)1 MySQLType (io.mycat.beans.mysql.MySQLType)1 io.mycat.calcite (io.mycat.calcite)1 MycatViewDataNodeMapping (io.mycat.calcite.logical.MycatViewDataNodeMapping)1 MycatInsertRel (io.mycat.calcite.physical.MycatInsertRel)1 MycatMergeSort (io.mycat.calcite.physical.MycatMergeSort)1 MycatUpdateRel (io.mycat.calcite.physical.MycatUpdateRel)1