in core/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java [153:400]
public SQLSelectQuery queryRest(SQLSelectQuery selectQuery, boolean acceptUnion) {
if (!acceptUnion) {
return selectQuery;
}
if (lexer.token == Token.UNION) {
do {
Lexer.SavePoint uninMark = lexer.mark();
lexer.nextToken();
switch (lexer.token) {
case GROUP:
case ORDER:
case WHERE:
case RPAREN:
lexer.reset(uninMark);
return selectQuery;
default:
break;
}
if (lexer.token == Token.SEMI && dialectFeatureEnabled(QueryRestSemi)) {
break;
}
SQLUnionQuery union = createSQLUnionQuery();
union.setLeft(selectQuery);
if (lexer.token == Token.ALL) {
union.setOperator(SQLUnionOperator.UNION_ALL);
lexer.nextToken();
} else if (lexer.token == Token.DISTINCT) {
union.setOperator(SQLUnionOperator.DISTINCT);
lexer.nextToken();
}
boolean paren = lexer.token == Token.LPAREN;
SQLSelectQuery right = this.query(paren ? null : union, false);
union.setRight(right);
while (lexer.isEnabled(SQLParserFeature.EnableMultiUnion)
&& lexer.token == Token.UNION
) {
Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.token == Token.UNION && dialectFeatureEnabled(TwoConsecutiveUnion)) {
continue; // skip
}
if (lexer.token == Token.ALL) {
if (union.getOperator() == SQLUnionOperator.UNION_ALL) {
lexer.nextToken();
} else {
lexer.reset(mark);
break;
}
} else if (lexer.token == Token.DISTINCT) {
if (union.getOperator() == SQLUnionOperator.DISTINCT) {
lexer.nextToken();
} else {
lexer.reset(mark);
break;
}
} else if (union.getOperator() == SQLUnionOperator.UNION) {
// skip
} else {
lexer.reset(mark);
break;
}
paren = lexer.token == Token.LPAREN;
SQLSelectQuery r = this.query(paren ? null : union, false);
r.setParenthesized(paren);
union.addRelation(r);
right = r;
}
if (!paren) {
if (right instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock rightQuery = (SQLSelectQueryBlock) right;
SQLOrderBy orderBy = rightQuery.getOrderBy();
if (orderBy != null) {
union.setOrderBy(orderBy);
rightQuery.setOrderBy(null);
}
SQLLimit limit = rightQuery.getLimit();
if (limit != null) {
union.setLimit(limit);
rightQuery.setLimit(null);
}
} else if (right instanceof SQLUnionQuery) {
SQLUnionQuery rightUnion = (SQLUnionQuery) right;
final SQLOrderBy orderBy = rightUnion.getOrderBy();
if (orderBy != null) {
union.setOrderBy(orderBy);
rightUnion.setOrderBy(null);
}
SQLLimit limit = rightUnion.getLimit();
if (limit != null) {
union.setLimit(limit);
rightUnion.setLimit(null);
}
}
}
union = unionRest(union);
selectQuery = union;
} while (lexer.token() == Token.UNION);
selectQuery = queryRest(selectQuery, true);
return selectQuery;
}
if (lexer.token == Token.EXCEPT) {
lexer.nextToken();
SQLUnionQuery union = new SQLUnionQuery();
union.setLeft(selectQuery);
if (lexer.token == Token.ALL) {
lexer.nextToken();
union.setOperator(SQLUnionOperator.EXCEPT_ALL);
} else if (lexer.token == Token.DISTINCT) {
lexer.nextToken();
union.setOperator(SQLUnionOperator.EXCEPT_DISTINCT);
} else {
union.setOperator(SQLUnionOperator.EXCEPT);
}
boolean paren = lexer.token == Token.LPAREN;
SQLSelectQuery right = this.query(union, false);
union.setRight(right);
if (!paren) {
if (right instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock rightQuery = (SQLSelectQueryBlock) right;
SQLOrderBy orderBy = rightQuery.getOrderBy();
if (orderBy != null) {
union.setOrderBy(orderBy);
rightQuery.setOrderBy(null);
}
SQLLimit limit = rightQuery.getLimit();
if (limit != null) {
union.setLimit(limit);
rightQuery.setLimit(null);
}
} else if (right instanceof SQLUnionQuery) {
SQLUnionQuery rightUnion = (SQLUnionQuery) right;
final SQLOrderBy orderBy = rightUnion.getOrderBy();
if (orderBy != null) {
union.setOrderBy(orderBy);
rightUnion.setOrderBy(null);
}
SQLLimit limit = rightUnion.getLimit();
if (limit != null) {
union.setLimit(limit);
rightUnion.setLimit(null);
}
}
}
return queryRest(union, true);
}
if (lexer.token == Token.INTERSECT) {
lexer.nextToken();
SQLUnionQuery union = new SQLUnionQuery();
union.setLeft(selectQuery);
if (lexer.token() == Token.DISTINCT) {
lexer.nextToken();
union.setOperator(SQLUnionOperator.INTERSECT_DISTINCT);
} else if (lexer.token == Token.ALL) {
lexer.nextToken();
union.setOperator(SQLUnionOperator.INTERSECT_ALL);
} else {
union.setOperator(SQLUnionOperator.INTERSECT);
}
boolean paren = lexer.token == Token.LPAREN;
SQLSelectQuery right = this.query(union, false);
union.setRight(right);
if (!paren) {
if (right instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock rightQuery = (SQLSelectQueryBlock) right;
SQLOrderBy orderBy = rightQuery.getOrderBy();
if (orderBy != null) {
union.setOrderBy(orderBy);
rightQuery.setOrderBy(null);
}
SQLLimit limit = rightQuery.getLimit();
if (limit != null) {
union.setLimit(limit);
rightQuery.setLimit(null);
}
} else if (right instanceof SQLUnionQuery) {
SQLUnionQuery rightUnion = (SQLUnionQuery) right;
final SQLOrderBy orderBy = rightUnion.getOrderBy();
if (orderBy != null) {
union.setOrderBy(orderBy);
rightUnion.setOrderBy(null);
}
SQLLimit limit = rightUnion.getLimit();
if (limit != null) {
union.setLimit(limit);
rightUnion.setLimit(null);
}
}
}
return queryRest(union, true);
}
if (acceptUnion && lexer.token == Token.MINUS) {
lexer.nextToken();
SQLUnionQuery union = new SQLUnionQuery();
union.setLeft(selectQuery);
union.setOperator(SQLUnionOperator.MINUS);
if (lexer.token == Token.DISTINCT) {
union.setOperator(SQLUnionOperator.MINUS_DISTINCT);
lexer.nextToken();
} else if (lexer.token == Token.ALL) {
union.setOperator(SQLUnionOperator.MINUS_ALL);
lexer.nextToken();
}
SQLSelectQuery right = this.query(union, false);
union.setRight(right);
return queryRest(union, true);
}
return selectQuery;
}