in src/query-common/src/main/java/org/apache/kylin/query/relnode/OlapContext.java [553:618]
private boolean canMinMaxDimAnsweredByMetadata(OlapRel rel, boolean resetAggWhenMatch) {
if (!KylinConfig.getInstanceFromEnv().isRouteToMetadataEnabled()) {
return false;
}
if (!(realization instanceof NDataflow) || !(rel instanceof OlapJoinRel || rel instanceof OlapTableScan)) {
logger.info("Can't route to metadata, the realization is {} and this OlapRel is {}", realization, rel);
return false;
}
/*
* Find the target pattern as shown below.
* (other rel)
* |
* Agg
* |
* Project
* |
* (TableScan or JoinRel)
*/
List<OlapRel> relStack = new ArrayList<>();
OlapRel current = this.topNode;
while (current != rel && current.getInputs().size() == 1 && current.getInput(0) instanceof OlapRel) {
relStack.add(current);
current = (OlapRel) current.getInput(0);
}
if (current != rel || relStack.size() < 2 || !(relStack.get(relStack.size() - 1) instanceof OlapProjectRel)
|| !(relStack.get(relStack.size() - 2) instanceof OlapAggregateRel)) {
logger.info("Can't route to query metadata, the rel stack is not matched");
return false;
}
OlapAggregateRel aggregateRel = (OlapAggregateRel) relStack.get(relStack.size() - 2);
if (aggregateRel.getGroups().size() > 1
|| aggregateRel.getGroups().size() == 1 && !TblColRef.InnerDataTypeEnum.LITERAL.getDataType()
.equals(aggregateRel.getGroups().get(0).getDatatype())) {
logger.info("Cannot route to query metadata, only group by constants are supported.");
return false;
}
if (aggregations.isEmpty() || !aggregations.stream().allMatch(agg -> agg.isMin() || agg.isMax())) {
logger.info("Cannot route to query metadata, only min/max aggregate functions are supported.");
return false;
}
if (aggregations.stream()
.anyMatch(agg -> TblColRef.InnerDataTypeEnum.contains(agg.getColRefs().get(0).getDatatype()))) {
logger.info("Cannot route to query metadata, not support min(expression), such as min(id+1)");
return false;
}
if (!Sets.newHashSet(realization.getAllDimensions()).containsAll(allColumns)) {
logger.info("Cannot route to query metadata, not all columns queried are treated as dimensions of index.");
return false;
}
if (resetAggWhenMatch) {
// reset rewriteAggCalls to aggCall, to avoid using measures.
aggregateRel.getRewriteAggCalls().clear();
aggregateRel.getRewriteAggCalls().addAll(aggregateRel.getAggCallList());
logger.info("Use kylin metadata to answer query with realization : {}", realization);
} else {
logger.info("OlapContext can be answered by kylin metadata with realization : {}", realization);
}
return true;
}