accept(Token.BY);
            SQLSelectGroupByClause groupBy = new SQLSelectGroupByClause();
            for (;;) {
                if (identifierEquals("GROUPING")) {
                    GroupingSetExpr groupingSet = new GroupingSetExpr();
                    lexer.nextToken();
                    acceptIdentifier("SETS");
                    accept(Token.LPAREN);
                    exprParser.exprList(groupingSet.getParameters(), groupingSet);
                    accept(Token.RPAREN);
                    groupBy.addItem(groupingSet);
                } else {
                    groupBy.addItem(this.exprParser.expr());
                }
                if (!(lexer.token() == (Token.COMMA))) {
                    break;
                }
                lexer.nextToken();
            }
            if (lexer.token() == (Token.HAVING)) {
                lexer.nextToken();
                groupBy.setHaving(this.exprParser.expr());
            }
            queryBlock.setGroupBy(groupBy);
        } else if (lexer.token() == (Token.HAVING)) {
            lexer.nextToken();
            SQLSelectGroupByClause groupBy = new SQLSelectGroupByClause();
            groupBy.setHaving(this.exprParser.expr());
            if (lexer.token() == (Token.GROUP)) {
                lexer.nextToken();
                accept(Token.BY);
                for (;;) {
                    if (identifierEquals("GROUPING")) {
                        GroupingSetExpr groupingSet = new GroupingSetExpr();
                        lexer.nextToken();
                        acceptIdentifier("SETS");
                        accept(Token.LPAREN);
                        exprParser.exprList(groupingSet.getParameters(), groupingSet);
                        accept(Token.RPAREN);
                        groupBy.addItem(groupingSet);
                    } else {
                        groupBy.addItem(this.exprParser.expr());
                    }