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());
})));
}
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();
}
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());
}
}
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;
}
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;
}
Aggregations