in core/src/main/java/org/apache/calcite/sql/advise/SqlSimpleParser.java [525:644]
public Query simplify(@Nullable String hintToken) {
TokenType clause = TokenType.SELECT;
TokenType foundInClause = null;
Query foundInSubQuery = null;
TokenType majorClause = null;
if (hintToken != null) {
for (Token token : tokenList) {
switch (token.type) {
case ID:
if (hintToken.equals(token.s)) {
foundInClause = clause;
}
break;
case SELECT:
case FROM:
case WHERE:
case GROUP:
case HAVING:
case ORDER:
majorClause = token.type;
// fall through
case JOIN:
case USING:
case ON:
clause = token.type;
break;
case COMMA:
if (majorClause == TokenType.FROM) {
// comma inside from clause
clause = TokenType.FROM;
}
break;
case QUERY:
if (((Query) token).contains(hintToken)) {
foundInClause = clause;
foundInSubQuery = (Query) token;
}
break;
default:
break;
}
}
} else {
foundInClause = TokenType.QUERY;
}
if (foundInClause != null) {
switch (foundInClause) {
case SELECT:
purgeSelectListExcept(hintToken);
purgeWhere();
purgeOrderBy();
break;
case FROM:
case JOIN:
// See comments against ON/USING.
purgeSelect();
purgeFromExcept(hintToken);
purgeWhere();
purgeGroupByHaving();
purgeOrderBy();
break;
case ON:
case USING:
// We need to treat expressions in FROM and JOIN
// differently than ON and USING. Consider
// FROM t1 JOIN t2 ON b1 JOIN t3 USING (c2)
// t1, t2, t3 occur in the FROM clause, and do not depend
// on anything; b1 and c2 occur in ON scope, and depend
// on the FROM clause
purgeSelect();
purgeWhere();
purgeOrderBy();
break;
case WHERE:
purgeSelect();
purgeGroupByHaving();
purgeOrderBy();
break;
case GROUP:
case HAVING:
purgeSelect();
purgeWhere();
purgeOrderBy();
break;
case ORDER:
purgeWhere();
break;
case QUERY:
// Indicates that the expression to be simplified is
// outside this sub-query. Preserve a simplified SELECT
// clause.
// It might be a good idea to purge select expressions, however
// purgeSelectExprsKeepAliases might end up with <<0 as "*">> which is not valid.
// purgeSelectExprsKeepAliases();
purgeWhere();
purgeGroupByHaving();
break;
default:
break;
}
}
// Simplify sub-queries.
for (Token token : tokenList) {
switch (token.type) {
case QUERY: {
Query query = (Query) token;
query.simplify(
(query == foundInSubQuery) ? hintToken : null);
break;
}
default:
break;
}
}
return this;
}