public SQLSelectQuery queryRest()

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;
    }