in src/query-common/src/main/java/org/apache/kylin/query/util/QueryAliasMatcher.java [321:402]
public SqlNode visit(SqlCall call) {
if (call instanceof SqlSelect) {
//don't go into sub-query
return null;
}
// record alias, since the passed in root is a FROM clause, any AS is related to table alias
if (call instanceof SqlBasicCall && call.getOperator() instanceof SqlAsOperator) {
//join Table as xxx
List<SqlNode> operands = call.getOperandList();
if (operands != null && operands.size() == 2) {
SqlNode operand0 = operands.get(0);
SqlNode operand1 = operands.get(1);
//both side of the join is SqlIdentifier (not subquery), table as alias
if (operand0 instanceof SqlIdentifier && operand1 instanceof SqlIdentifier) {
String alias = operand1.toString();
SqlIdentifier tableIdentifier = (SqlIdentifier) operand0;
Pair<String, String> schemaAndTable = getSchemaAndTable(tableIdentifier);
ColumnRowType columnRowType = buildColumnRowType(alias, schemaAndTable.getFirst(),
schemaAndTable.getSecond());
alias2CRT.put(alias, columnRowType);
}
//subquery as alias
if ((operand0 instanceof SqlSelect)
|| ((operand0 instanceof SqlOrderBy) && operand1 instanceof SqlIdentifier)) {
String alias = operand1.toString();
alias2CRT.put(alias, SUBQUERY_TAG);
}
// union-all as alias
if ((operand0 instanceof SqlBasicCall && operand0.getKind() == SqlKind.UNION
&& operand1 instanceof SqlIdentifier)) {
String alias = operand1.toString();
alias2CRT.put(alias, SUBQUERY_TAG);
}
}
return null; //don't visit child anymore
}
List<SqlNode> operandList = call.getOperandList();
// if it's a join, the last element is "condition".
// skip its part as it may also contain SqlIdentifier(representing condition column),
// which is hard to tell from SqlIdentifier representing join tables (without AS)
List<SqlNode> operands = call instanceof SqlJoin ? operandList.subList(0, operandList.size() - 1)
: operandList;
for (SqlNode operand : operands) {
if (operand != null) {
operand.accept(this);
}
}
//Note this part is after visiting all children, it's on purpose so that by the time the SqlJoin
//is handled, all of its related join tables must have been recorded in alias2CRT
if (call instanceof SqlJoin) {
SqlJoin join = (SqlJoin) call;
if (join.getConditionType() != JoinConditionType.ON) {
throw new IllegalArgumentException(
"JoinConditionType is not ON: " + join.toSqlString(CalciteSqlDialect.DEFAULT));
}
if (join.getJoinType() != JoinType.INNER && join.getJoinType() != JoinType.LEFT) {
throw new IllegalArgumentException("JoinType must be INNER or LEFT");
}
if (join.getCondition() instanceof SqlBasicCall) {
JoinConditionCapturer joinConditionCapturer = new JoinConditionCapturer(alias2CRT,
join.getJoinType().toString());
join.getCondition().accept(joinConditionCapturer);
JoinDesc joinDesc = joinConditionCapturer.getJoinDescs();
foundJoinOnCC = foundJoinOnCC || joinConditionCapturer.foundCC;
if (joinDesc.getForeignKey().length != 0 && !joinConditionCapturer.foundNonEqualJoin)
joinDescs.add(joinDesc);
} else {
throw new IllegalArgumentException("join condition should be SqlBasicCall");
}
}
return null;
}