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