Search in sources :

Example 1 with KeyMeta

use of io.mycat.querycondition.KeyMeta in project Mycat2 by MyCATApache.

the class PredicateAnalyzer method translateAnd.

private Map<QueryType, List<IndexCondition>> translateAnd(RexNode condition) {
    // expand calls to SEARCH(..., Sarg()) to >, =, etc.
    final RexNode condition2 = RexUtil.expandSearch(REX_BUILDER, null, condition);
    // decompose condition by AND, flatten row expression
    List<RexNode> rexNodeList = RelOptUtil.conjunctions(condition2);
    List<IndexCondition> indexConditions = new ArrayList<>();
    // try to push down filter by secondary keys
    for (KeyMeta skMeta : keyMetas) {
        indexConditions.add(findPushDownCondition(rexNodeList, skMeta));
    }
    return indexConditions.stream().filter(i -> i != null).filter(IndexCondition::canPushDown).filter(indexCondition -> nonForceIndexOrMatchForceIndexName(indexCondition.getName())).sorted(Comparator.comparing(x -> x.getQueryType().priority())).collect(Collectors.groupingBy(k -> k.getQueryType(), Collectors.collectingAndThen(Collectors.toList(), indexConditions1 -> {
        HashMap<String, IndexCondition> conditionMap = new HashMap<>();
        for (IndexCondition newOne : indexConditions1) {
            List<String> fieldNames = newOne.getIndexColumnNames();
            for (String fieldName : fieldNames) {
                IndexCondition oldOne = conditionMap.getOrDefault(fieldName, null);
                if (oldOne == null) {
                    conditionMap.put(fieldName, newOne);
                    continue;
                } else {
                    if (newOne.getQueryType().compareTo(oldOne.getQueryType()) < 0) {
                        conditionMap.put(fieldName, newOne);
                    }
                }
            }
        }
        return new ArrayList<>(conditionMap.values());
    })));
}
Also used : ShardingTable(io.mycat.calcite.table.ShardingTable) java.util(java.util) SqlKind(org.apache.calcite.sql.SqlKind) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) org.apache.calcite.rex(org.apache.calcite.rex) ComparisonOperator(io.mycat.querycondition.ComparisonOperator) MycatCalciteSupport(io.mycat.calcite.MycatCalciteSupport) Multimap(com.google.common.collect.Multimap) RelNode(org.apache.calcite.rel.RelNode) RelOptUtil(org.apache.calcite.plan.RelOptUtil) Collectors(java.util.stream.Collectors) HashMultimap(com.google.common.collect.HashMultimap) Lists(com.google.common.collect.Lists) QueryType(io.mycat.querycondition.QueryType) KeyMeta(io.mycat.querycondition.KeyMeta) KeyMeta(io.mycat.querycondition.KeyMeta)

Example 2 with KeyMeta

use of io.mycat.querycondition.KeyMeta in project Mycat2 by MyCATApache.

the class ValuePredicateAnalyzer method tryAndIn.

@Nullable
private Map<QueryType, List<ValueIndexCondition>> tryAndIn(RexNode condition) {
    try {
        if (condition.isA(SqlKind.AND)) {
            RexCall rexCall = (RexCall) condition;
            List<RexNode> operands = rexCall.getOperands();
            RexNode primaryHead = operands.get(0);
            if (operands.subList(1, operands.size()).stream().anyMatch(i -> RexUtil.findOperatorCall(SqlStdOperatorTable.OR, i) != null)) {
                return Collections.emptyMap();
            }
            boolean allMatch = true;
            RexNode primaryInputRef = null;
            List<RexNode> valueList = new ArrayList<>();
            if (primaryHead.isA(SqlKind.OR)) {
                RexCall primaryNode = (RexCall) primaryHead;
                for (RexNode maybeEquals : primaryNode.getOperands()) {
                    if (maybeEquals.isA(SqlKind.EQUALS)) {
                        RexCall equals = (RexCall) maybeEquals;
                        RexNode maybeId = equals.getOperands().get(0);
                        valueList.add(RexUtil.removeCast(equals.getOperands().get(1)));
                        if (maybeId.isA(SqlKind.INPUT_REF)) {
                            if (primaryInputRef == null) {
                                primaryInputRef = maybeId;
                                continue;
                            } else if (primaryInputRef.equals(maybeId)) {
                                continue;
                            }
                        }
                    }
                    allMatch = false;
                    break;
                }
                if (allMatch && !valueList.isEmpty()) {
                    Map<QueryType, List<ValueIndexCondition>> indexConditions = new HashMap<>();
                    ValueIndexCondition pushDownCondition = null;
                    for (KeyMeta skMeta : keyMetas) {
                        for (RexNode rexNode : valueList) {
                            if (pushDownCondition == null) {
                                pushDownCondition = findPushDownCondition(ImmutableList.of(MycatCalciteSupport.RexBuilder.makeCall(SqlStdOperatorTable.EQUALS, primaryInputRef, rexNode)), skMeta);
                            } else {
                                pushDownCondition.pointQueryKey.add(rexNode);
                            }
                        }
                    }
                    if (pushDownCondition != null) {
                        indexConditions.put(QueryType.PK_POINT_QUERY, Collections.singletonList(pushDownCondition));
                    }
                    return indexConditions;
                }
            }
        }
        return Collections.emptyMap();
    } catch (Throwable throwable) {
        LOGGER.warn("", throwable);
    }
    return Collections.emptyMap();
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) QueryType(io.mycat.querycondition.QueryType) KeyMeta(io.mycat.querycondition.KeyMeta) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with KeyMeta

use of io.mycat.querycondition.KeyMeta in project Mycat2 by MyCATApache.

the class ShardingTable method keyMetas.

public List<KeyMeta> keyMetas(boolean distinct) {
    if (this.sharedKeyMetas == null) {
        List<String> shardingKeys = this.getColumns().stream().filter(i -> i.isShardingKey()).map(i -> i.getColumnName()).collect(Collectors.toList());
        List<KeyMeta> keyMetas = new ArrayList<>();
        for (int i = 0; i < shardingKeys.size(); i++) {
            KeyMeta keyMeta = KeyMeta.of(shardingFuntion.name(), shardingKeys.get(i));
            keyMetas.add(keyMeta);
        }
        this.sharedKeyMetas = keyMetas;
    }
    if (distinct) {
        if (this.sharedAndDistnctKeydMetas == null) {
            List<String> distinctKeys = this.getColumns().stream().filter(i -> i.isUniqueKey()).map(i -> i.getColumnName()).collect(Collectors.toList());
            List<KeyMeta> sharedAndDistnctKeydMetas = new ArrayList<>(this.sharedKeyMetas);
            for (String distinctKey : distinctKeys) {
                sharedAndDistnctKeydMetas.add(KeyMeta.of("mycat_unique_" + distinctKey.toLowerCase(), distinctKeys));
            }
            this.sharedAndDistnctKeydMetas = sharedAndDistnctKeydMetas;
            return this.sharedAndDistnctKeydMetas;
        } else {
            return this.sharedAndDistnctKeydMetas;
        }
    } else {
        return this.sharedKeyMetas;
    }
}
Also used : java.util(java.util) DDLHelper.createDatabaseIfNotExist(io.mycat.util.DDLHelper.createDatabaseIfNotExist) CustomRuleFunction(io.mycat.router.CustomRuleFunction) io.mycat(io.mycat) Getter(lombok.Getter) ShardingTableConfig(io.mycat.config.ShardingTableConfig) DefaultConnection(io.mycat.datasource.jdbc.datasource.DefaultConnection) CreateTableUtils(io.mycat.util.CreateTableUtils) Supplier(java.util.function.Supplier) Collectors(java.util.stream.Collectors) GSIService(io.mycat.gsi.GSIService) ShardingTableHandler(io.mycat.router.ShardingTableHandler) SequenceGenerator(io.mycat.plug.sequence.SequenceGenerator) ImmutableList(com.google.common.collect.ImmutableList) ReplicaSelectorManager(io.mycat.replica.ReplicaSelectorManager) JdbcConnectionManager(io.mycat.datasource.jdbc.datasource.JdbcConnectionManager) KeyMeta(io.mycat.querycondition.KeyMeta) KeyMeta(io.mycat.querycondition.KeyMeta)

Example 4 with KeyMeta

use of io.mycat.querycondition.KeyMeta in project Mycat2 by MyCATApache.

the class ValuePredicateAnalyzer method translateAnd.

private Map<QueryType, List<ValueIndexCondition>> translateAnd(RexNode condition) {
    List<RexNode> rexNodeList = RelOptUtil.conjunctions(condition);
    List<ValueIndexCondition> indexConditions = new ArrayList<>();
    // try to push down filter by secondary keys
    for (KeyMeta skMeta : keyMetas) {
        indexConditions.add(findPushDownCondition(rexNodeList, skMeta));
    }
    return indexConditions.stream().filter(i -> i != null).filter(ValueIndexCondition::canPushDown).filter(indexCondition -> nonForceIndexOrMatchForceIndexName(indexCondition.getName())).sorted(Comparator.comparing(x -> x.getQueryType().priority())).collect(Collectors.groupingBy(k -> k.getQueryType(), Collectors.collectingAndThen(Collectors.toList(), indexConditions1 -> {
        HashMap<String, ValueIndexCondition> conditionMap = new HashMap<>();
        for (ValueIndexCondition newOne : indexConditions1) {
            List<String> fieldNames = newOne.getIndexColumnNames();
            for (String fieldName : fieldNames) {
                ValueIndexCondition oldOne = conditionMap.getOrDefault(fieldName, null);
                if (oldOne == null) {
                    conditionMap.put(fieldName, newOne);
                    continue;
                } else {
                    if (newOne.getQueryType().compareTo(oldOne.getQueryType()) < 0) {
                        conditionMap.put(fieldName, newOne);
                    }
                }
            }
        }
        return new ArrayList<>(conditionMap.values());
    })));
}
Also used : ShardingTable(io.mycat.calcite.table.ShardingTable) Sarg(org.apache.calcite.util.Sarg) java.util(java.util) SqlKind(org.apache.calcite.sql.SqlKind) Logger(org.slf4j.Logger) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) org.apache.calcite.rex(org.apache.calcite.rex) ComparisonOperator(io.mycat.querycondition.ComparisonOperator) LoggerFactory(org.slf4j.LoggerFactory) MycatCalciteSupport(io.mycat.calcite.MycatCalciteSupport) Multimap(com.google.common.collect.Multimap) RelNode(org.apache.calcite.rel.RelNode) RelOptUtil(org.apache.calcite.plan.RelOptUtil) Collectors(java.util.stream.Collectors) Nullable(org.jetbrains.annotations.Nullable) HashMultimap(com.google.common.collect.HashMultimap) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) QueryType(io.mycat.querycondition.QueryType) SqlStdOperatorTable(org.apache.calcite.sql.fun.SqlStdOperatorTable) KeyMeta(io.mycat.querycondition.KeyMeta) KeyMeta(io.mycat.querycondition.KeyMeta)

Example 5 with KeyMeta

use of io.mycat.querycondition.KeyMeta in project Mycat2 by MyCATApache.

the class ValuePredicateAnalyzer method conditionClippingByKeyMeta.

public static RexNode conditionClippingByKeyMeta(RexNode condition, List<String> fieldNames, List<KeyMeta> keyMetas) {
    List<RexNode> rexNodeList = RelOptUtil.conjunctions(condition);
    if (rexNodeList.isEmpty() || rexNodeList.size() == 1) {
        return condition;
    } else {
        class ShardingKeyFinder extends RexShuttle {

            boolean find = false;

            @Override
            public RexNode visitInputRef(RexInputRef inputRef) {
                if (find) {
                    return inputRef;
                }
                int index = inputRef.getIndex();
                String name = fieldNames.get(index);
                for (KeyMeta keyMeta : keyMetas) {
                    if (keyMeta.findColumnName(name)) {
                        find = true;
                        break;
                    }
                }
                return super.visitInputRef(inputRef);
            }
        }
        List<RexNode> newRexNodeList = new ArrayList<>();
        for (RexNode rexNode : rexNodeList) {
            ShardingKeyFinder shardingKeyFinder = new ShardingKeyFinder();
            rexNode.accept(shardingKeyFinder);
            if (shardingKeyFinder.find) {
                newRexNodeList.add(rexNode);
            }
        }
        rexNodeList = newRexNodeList;
        if (rexNodeList.isEmpty()) {
            return condition;
        } else if (rexNodeList.size() == 1) {
            condition = rexNodeList.get(0);
        } else {
            condition = rexNodeList.stream().reduce((rexNode, rexNode2) -> MycatCalciteSupport.RexBuilder.makeCall(SqlStdOperatorTable.AND, rexNode, rexNode2)).get();
        }
    }
    return condition;
}
Also used : ShardingTable(io.mycat.calcite.table.ShardingTable) Sarg(org.apache.calcite.util.Sarg) java.util(java.util) SqlKind(org.apache.calcite.sql.SqlKind) Logger(org.slf4j.Logger) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) org.apache.calcite.rex(org.apache.calcite.rex) ComparisonOperator(io.mycat.querycondition.ComparisonOperator) LoggerFactory(org.slf4j.LoggerFactory) MycatCalciteSupport(io.mycat.calcite.MycatCalciteSupport) Multimap(com.google.common.collect.Multimap) RelNode(org.apache.calcite.rel.RelNode) RelOptUtil(org.apache.calcite.plan.RelOptUtil) Collectors(java.util.stream.Collectors) Nullable(org.jetbrains.annotations.Nullable) HashMultimap(com.google.common.collect.HashMultimap) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) QueryType(io.mycat.querycondition.QueryType) SqlStdOperatorTable(org.apache.calcite.sql.fun.SqlStdOperatorTable) KeyMeta(io.mycat.querycondition.KeyMeta) KeyMeta(io.mycat.querycondition.KeyMeta)

Aggregations

KeyMeta (io.mycat.querycondition.KeyMeta)5 ImmutableList (com.google.common.collect.ImmutableList)4 QueryType (io.mycat.querycondition.QueryType)4 java.util (java.util)4 Collectors (java.util.stream.Collectors)4 HashMultimap (com.google.common.collect.HashMultimap)3 Lists (com.google.common.collect.Lists)3 Multimap (com.google.common.collect.Multimap)3 MycatCalciteSupport (io.mycat.calcite.MycatCalciteSupport)3 ShardingTable (io.mycat.calcite.table.ShardingTable)3 ComparisonOperator (io.mycat.querycondition.ComparisonOperator)3 RelOptUtil (org.apache.calcite.plan.RelOptUtil)3 RelNode (org.apache.calcite.rel.RelNode)3 org.apache.calcite.rex (org.apache.calcite.rex)3 SqlKind (org.apache.calcite.sql.SqlKind)3 SqlTypeName (org.apache.calcite.sql.type.SqlTypeName)3 Nullable (org.jetbrains.annotations.Nullable)3 SqlStdOperatorTable (org.apache.calcite.sql.fun.SqlStdOperatorTable)2 Sarg (org.apache.calcite.util.Sarg)2 Logger (org.slf4j.Logger)2