in core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java [94:328]
public SQLSelectQuery query(SQLObject parent, boolean acceptUnion) {
List<SQLCommentHint> hints = null;
if (lexer.token() == Token.HINT) {
hints = this.exprParser.parseHints();
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLSelectQuery select = query();
select.setParenthesized(true);
accept(Token.RPAREN);
return queryRest(select, acceptUnion);
}
if (lexer.token() == Token.VALUES) {
return valuesQuery(acceptUnion);
}
MySqlSelectQueryBlock queryBlock = new MySqlSelectQueryBlock();
queryBlock.setParent(parent);
class QueryHintHandler implements Lexer.CommentHandler {
private MySqlSelectQueryBlock queryBlock;
private Lexer lexer;
QueryHintHandler(MySqlSelectQueryBlock queryBlock, Lexer lexer) {
this.queryBlock = queryBlock;
this.lexer = lexer;
}
@Override
public boolean handle(Token lastToken, String comment) {
if (lexer.isEnabled(SQLParserFeature.TDDLHint)
&& (comment.startsWith("+ TDDL")
|| comment.startsWith("+TDDL")
|| comment.startsWith("!TDDL")
|| comment.startsWith("TDDL"))) {
SQLCommentHint hint = new TDDLHint(comment);
if (lexer.getCommentCount() > 0) {
hint.addBeforeComment(lexer.getComments());
}
queryBlock.getHints().add(hint);
lexer.nextToken();
}
return false;
}
}
this.lexer.setCommentHandler(new QueryHintHandler(queryBlock, this.lexer));
if (lexer.hasComment() && lexer.isKeepComments()) {
queryBlock.addBeforeComment(lexer.readAndResetComments());
}
if (lexer.token() == Token.SELECT) {
if (selectListCache != null) {
selectListCache.match(lexer, queryBlock);
}
}
if (lexer.token() == Token.SELECT) {
lexer.nextTokenValue();
for (; ; ) {
if (lexer.token() == Token.HINT) {
this.exprParser.parseHints(queryBlock.getHints());
} else {
break;
}
}
while (true) {
Token token = lexer.token();
if (token == (Token.DISTINCT)) {
queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.DISTINCTROW)) {
queryBlock.setDistionOption(SQLSetQuantifier.DISTINCTROW);
lexer.nextToken();
} else if (token == (Token.ALL)) {
queryBlock.setDistionOption(SQLSetQuantifier.ALL);
lexer.nextToken();
} else if (token == (Token.UNIQUE)) {
queryBlock.setDistionOption(SQLSetQuantifier.UNIQUE);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.HIGH_PRIORITY)) {
queryBlock.setHignPriority(true);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.STRAIGHT_JOIN)) {
queryBlock.setStraightJoin(true);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.SQL_SMALL_RESULT)) {
queryBlock.setSmallResult(true);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.SQL_BIG_RESULT)) {
queryBlock.setBigResult(true);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.SQL_BUFFER_RESULT)) {
queryBlock.setBufferResult(true);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.SQL_CACHE)) {
queryBlock.setCache(true);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.SQL_NO_CACHE)) {
queryBlock.setCache(false);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.SQL_CALC_FOUND_ROWS)) {
queryBlock.setCalcFoundRows(true);
lexer.nextToken();
} else if (lexer.identifierEquals(FnvHash.Constants.TOP)) {
Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.token() == Token.LITERAL_INT) {
SQLLimit limit = new SQLLimit(lexer.integerValue().intValue());
queryBlock.setLimit(limit);
lexer.nextToken();
} else if (lexer.token() == Token.DOT) {
lexer.reset(mark);
break;
}
} else {
break;
}
}
parseSelectList(queryBlock);
if (lexer.identifierEquals(FnvHash.Constants.FORCE)) {
lexer.nextToken();
accept(Token.PARTITION);
SQLName partition = this.exprParser.name();
queryBlock.setForcePartition(partition);
}
parseInto(queryBlock);
}
parseFrom(queryBlock);
parseWhere(queryBlock);
parseHierachical(queryBlock);
if (lexer.token() == Token.GROUP || lexer.token() == Token.HAVING) {
parseGroupBy(queryBlock);
}
if (lexer.identifierEquals(FnvHash.Constants.WINDOW)) {
parseWindow(queryBlock);
}
if (lexer.token() == Token.ORDER) {
queryBlock.setOrderBy(this.exprParser.parseOrderBy());
}
if (lexer.token() == Token.LIMIT) {
queryBlock.setLimit(this.exprParser.parseLimit());
}
if (lexer.token() == Token.FETCH) {
final Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.identifierEquals(FnvHash.Constants.NEXT)) {
lexer.nextToken();
SQLExpr rows = this.exprParser.primary();
queryBlock.setLimit(
new SQLLimit(rows));
acceptIdentifier("ROWS");
acceptIdentifier("ONLY");
} else {
lexer.reset(mark);
}
}
if (lexer.token() == Token.PROCEDURE) {
lexer.nextToken();
throw new ParserException("TODO. " + lexer.info());
}
if (lexer.token() == Token.INTO) {
parseInto(queryBlock);
}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
if (lexer.token() == Token.UPDATE) {
lexer.nextToken();
queryBlock.setForUpdate(true);
if (lexer.identifierEquals(FnvHash.Constants.NO_WAIT)
|| lexer.identifierEquals(FnvHash.Constants.NOWAIT)) {
lexer.nextToken();
queryBlock.setNoWait(true);
} else if (lexer.identifierEquals(FnvHash.Constants.WAIT)) {
lexer.nextToken();
SQLExpr waitTime = this.exprParser.primary();
queryBlock.setWaitTime(waitTime);
}
if (lexer.identifierEquals(FnvHash.Constants.SKIP)) {
lexer.nextToken();
acceptIdentifier("LOCKED");
queryBlock.setSkipLocked(true);
}
} else {
acceptIdentifier("SHARE");
queryBlock.setForShare(true);
}
}
if (lexer.token() == Token.LOCK) {
lexer.nextToken();
accept(Token.IN);
acceptIdentifier("SHARE");
acceptIdentifier("MODE");
queryBlock.setLockInShareMode(true);
}
if (hints != null) {
queryBlock.setHints(hints);
}
if (lexer.hasComment() && lexer.isKeepComments()) {
queryBlock.addAfterComment(lexer.readAndResetComments());
}
return queryRest(queryBlock, acceptUnion);
}