Search in sources :

Example 1 with QueryType

use of io.mycat.querycondition.QueryType 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 QueryType

use of io.mycat.querycondition.QueryType 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 QueryType

use of io.mycat.querycondition.QueryType 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 4 with QueryType

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

the class MycatView method estimateRowCount.

@Override
public double estimateRowCount(RelMetadataQuery mq) {
    if (relNode instanceof Sort) {
        Sort relNode = (Sort) this.relNode;
        ParamHolder paramHolder = ParamHolder.CURRENT_THREAD_LOCAL.get();
        List<Object> params = paramHolder.getParams();
        if (params != null && !params.isEmpty()) {
            RexNode fetch = relNode.fetch;
            RexNode offset = relNode.offset;
            Long fetchValue = null;
            if (fetch != null && fetch instanceof RexCall && fetch.isA(SqlKind.PLUS)) {
                List<RexNode> operands = ((RexCall) fetch).getOperands();
                Long one = resolveParam(params, operands.get(0));
                Long two = resolveParam(params, operands.get(1));
                if (one != null && two != null) {
                    fetchValue = one + two;
                }
            } else if (fetch instanceof RexLiteral) {
                fetchValue = resolveParam(params, fetch);
            }
            Long offsetValue = resolveParam(params, offset);
            if (offsetValue == null && fetchValue != null)
                return fetchValue;
            if (offsetValue != null && fetchValue != null)
                return fetchValue - offsetValue;
        }
    }
    List<IndexCondition> conditionOptional = getPredicateIndexCondition();
    double v = relNode.estimateRowCount(mq);
    if (!conditionOptional.isEmpty()) {
        IndexCondition indexCondition = conditionOptional.get(0);
        QueryType queryType = indexCondition.getQueryType();
        double factor = queryType.factor();
        switch(queryType) {
            case PK_POINT_QUERY:
                if (v > 1000) {
                    return 1000;
                } else {
                    return v;
                }
            case PK_RANGE_QUERY:
                return factor * v;
            case PK_FULL_SCAN:
                return factor * v;
        }
    }
    return v;
}
Also used : ParamHolder(io.mycat.calcite.spm.ParamHolder) MycatMergeSort(io.mycat.calcite.physical.MycatMergeSort) IndexCondition(io.mycat.calcite.rewriter.IndexCondition) QueryType(io.mycat.querycondition.QueryType)

Example 5 with QueryType

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

the class MycatView method getPredicateIndexCondition.

public List<IndexCondition> getPredicateIndexCondition() {
    if (indexConditions != null) {
        return indexConditions;
    }
    if (this.distribution.getShardingTables().isEmpty() || condition == null) {
        return Collections.emptyList();
    }
    ShardingTable shardingTable = this.distribution.getShardingTables().get(0);
    PredicateAnalyzer predicateAnalyzer = new PredicateAnalyzer(shardingTable.keyMetas(), shardingTable.getLogicTable().getFieldNames());
    Map<QueryType, List<IndexCondition>> queryTypeListMap = predicateAnalyzer.translateMatch(condition);
    indexConditions = ImmutableList.copyOf(queryTypeListMap.values().stream().flatMap(i -> i.stream()).sorted().collect(Collectors.toList()));
    if (indexConditions.isEmpty()) {
        indexConditions = Collections.emptyList();
        return indexConditions;
    }
    return indexConditions;
}
Also used : PredicateAnalyzer(io.mycat.calcite.rewriter.PredicateAnalyzer) ImmutableList(com.google.common.collect.ImmutableList) QueryType(io.mycat.querycondition.QueryType)

Aggregations

QueryType (io.mycat.querycondition.QueryType)23 Test (org.junit.Test)14 RexNode (org.apache.calcite.rex.RexNode)13 ShardingTable (io.mycat.calcite.table.ShardingTable)12 ValuePredicateAnalyzer (io.mycat.calcite.rewriter.ValuePredicateAnalyzer)9 PredicateAnalyzer (io.mycat.calcite.rewriter.PredicateAnalyzer)8 KeyMeta (io.mycat.querycondition.KeyMeta)8 java.util (java.util)8 MycatCalciteSupport (io.mycat.calcite.MycatCalciteSupport)7 RexLiteral (org.apache.calcite.rex.RexLiteral)7 SqlStdOperatorTable (org.apache.calcite.sql.fun.SqlStdOperatorTable)7 SqlTypeName (org.apache.calcite.sql.type.SqlTypeName)7 DrdsSqlCompiler (io.mycat.DrdsSqlCompiler)6 MetadataManager (io.mycat.MetadataManager)6 Partition (io.mycat.Partition)6 RexBuilder (org.apache.calcite.rex.RexBuilder)6 ImmutableList (com.google.common.collect.ImmutableList)5 ValueIndexCondition (io.mycat.calcite.rewriter.ValueIndexCondition)5 NotThreadSafe (javax.annotation.concurrent.NotThreadSafe)5 RexUtil (org.apache.calcite.rex.RexUtil)5