Search in sources :

Example 1 with SQLCommentHint

use of com.alibaba.druid.sql.ast.SQLCommentHint in project Mycat-Server by MyCATApache.

the class MycatSchemaStatVisitor method parseSchema.

private String parseSchema(List<SQLCommentHint> hits) {
    String regx = "\\!mycat:schema\\s*=([\\s\\w]*)$";
    for (SQLCommentHint hit : hits) {
        Pattern pattern = Pattern.compile(regx);
        Matcher m = pattern.matcher(hit.getText());
        if (m.matches()) {
            return m.group(1).trim();
        }
    }
    return null;
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) SQLCommentHint(com.alibaba.druid.sql.ast.SQLCommentHint)

Example 2 with SQLCommentHint

use of com.alibaba.druid.sql.ast.SQLCommentHint in project druid by alibaba.

the class MySqlStatementParser method parseCreate.

public SQLStatement parseCreate() {
    char markChar = lexer.current();
    int markBp = lexer.bp();
    accept(Token.CREATE);
    boolean replace = false;
    if (lexer.token() == Token.OR) {
        lexer.nextToken();
        accept(Token.REPLACE);
        replace = true;
    }
    List<SQLCommentHint> hints = this.exprParser.parseHints();
    if (lexer.token() == Token.TABLE || identifierEquals(TEMPORARY)) {
        if (replace) {
            lexer.reset(markBp, markChar, Token.CREATE);
        }
        MySqlCreateTableParser parser = new MySqlCreateTableParser(this.exprParser);
        MySqlCreateTableStatement stmt = parser.parseCrateTable(false);
        stmt.setHints(hints);
        return stmt;
    }
    if (lexer.token() == Token.DATABASE) {
        if (replace) {
            lexer.reset(markBp, markChar, Token.CREATE);
        }
        return parseCreateDatabase();
    }
    if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX || identifierEquals(FULLTEXT) || identifierEquals(SPATIAL)) {
        if (replace) {
            lexer.reset(markBp, markChar, Token.CREATE);
        }
        return parseCreateIndex(false);
    }
    if (lexer.token() == Token.USER) {
        if (replace) {
            lexer.reset(markBp, markChar, Token.CREATE);
        }
        return parseCreateUser();
    }
    if (lexer.token() == Token.VIEW || identifierEquals("ALGORITHM")) {
        if (replace) {
            lexer.reset(markBp, markChar, Token.CREATE);
        }
        return parseCreateView();
    }
    if (lexer.token() == Token.TRIGGER) {
        if (replace) {
            lexer.reset(markBp, markChar, Token.CREATE);
        }
        return parseCreateTrigger();
    }
    // parse create procedure
    if (lexer.token() == Token.PROCEDURE || identifierEquals("DEFINER")) {
        if (replace) {
            lexer.reset(markBp, markChar, Token.CREATE);
        }
        return parseCreateProcedure();
    }
    throw new ParserException("TODO " + lexer.info());
}
Also used : ParserException(com.alibaba.druid.sql.parser.ParserException) SQLCommentHint(com.alibaba.druid.sql.ast.SQLCommentHint) MySqlCreateTableStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement) SQLCommentHint(com.alibaba.druid.sql.ast.SQLCommentHint)

Example 3 with SQLCommentHint

use of com.alibaba.druid.sql.ast.SQLCommentHint in project druid by alibaba.

the class MySqlOutputVisitor method visit.

public boolean visit(MySqlCreateTableStatement x) {
    print0(ucase ? "CREATE " : "create ");
    for (SQLCommentHint hint : x.getHints()) {
        hint.accept(this);
        print(' ');
    }
    if (SQLCreateTableStatement.Type.GLOBAL_TEMPORARY.equals(x.getType())) {
        print0(ucase ? "TEMPORARY TABLE " : "temporary table ");
    } else {
        print0(ucase ? "TABLE " : "table ");
    }
    if (x.isIfNotExiists()) {
        print0(ucase ? "IF NOT EXISTS " : "if not exists ");
    }
    printTableSourceExpr(x.getName());
    if (x.getLike() != null) {
        print0(ucase ? " LIKE " : " like ");
        x.getLike().accept(this);
    }
    int size = x.getTableElementList().size();
    if (size > 0) {
        print0(" (");
        incrementIndent();
        println();
        for (int i = 0; i < size; ++i) {
            if (i != 0) {
                print0(", ");
                println();
            }
            x.getTableElementList().get(i).accept(this);
        }
        decrementIndent();
        println();
        print(')');
    }
    for (Map.Entry<String, SQLObject> option : x.getTableOptions().entrySet()) {
        String key = option.getKey();
        print(' ');
        print0(ucase ? key : key.toLowerCase());
        if ("TABLESPACE".equals(key)) {
            print(' ');
            option.getValue().accept(this);
            continue;
        } else if ("UNION".equals(key)) {
            print0(" = (");
            option.getValue().accept(this);
            print(')');
            continue;
        }
        print0(" = ");
        option.getValue().accept(this);
    }
    if (x.getPartitioning() != null) {
        println();
        x.getPartitioning().accept(this);
    }
    if (x.getTableGroup() != null) {
        println();
        print0(ucase ? "TABLEGROUP " : "tablegroup ");
        x.getTableGroup().accept(this);
    }
    if (x.getSelect() != null) {
        incrementIndent();
        println();
        x.getSelect().accept(this);
        decrementIndent();
    }
    for (SQLCommentHint hint : x.getOptionHints()) {
        print(' ');
        hint.accept(this);
    }
    return false;
}
Also used : SQLObject(com.alibaba.druid.sql.ast.SQLObject) SQLCommentHint(com.alibaba.druid.sql.ast.SQLCommentHint) Map(java.util.Map) MySqlForceIndexHint(com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint) SQLCommentHint(com.alibaba.druid.sql.ast.SQLCommentHint) MySqlUseIndexHint(com.alibaba.druid.sql.dialect.mysql.ast.MySqlUseIndexHint) MySqlIgnoreIndexHint(com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint)

Example 4 with SQLCommentHint

use of com.alibaba.druid.sql.ast.SQLCommentHint in project druid by alibaba.

the class WallVisitorUtils method check.

public static void check(WallVisitor visitor, SQLCommentHint x) {
    if (!visitor.getConfig().isHintAllow()) {
        addViolation(visitor, ErrorCode.EVIL_HINTS, "hint not allow", x);
        return;
    }
    String text = x.getText();
    text = text.trim();
    if (text.startsWith("!")) {
        text = text.substring(1);
    }
    if (text.length() == 0) {
        return;
    }
    int pos = 0;
    for (; pos < text.length(); pos++) {
        char ch = text.charAt(pos);
        if (ch >= '0' && ch <= '9') {
            continue;
        } else {
            break;
        }
    }
    if (pos == 5) {
        text = text.substring(5);
        text = text.trim();
    }
    text = text.toUpperCase();
    boolean isWhite = false;
    for (String hint : whiteHints) {
        if (text.equals(hint)) {
            isWhite = true;
            break;
        }
    }
    if (!isWhite) {
        if (text.startsWith("FORCE INDEX") || text.startsWith("IGNORE INDEX")) {
            isWhite = true;
        }
    }
    if (!isWhite) {
        if (text.startsWith("SET")) {
            SQLStatementParser parser = new MySqlStatementParser(text);
            List<SQLStatement> statementList = parser.parseStatementList();
            if (statementList != null && statementList.size() > 0) {
                SQLStatement statement = statementList.get(0);
                if (statement instanceof SQLSetStatement || statement instanceof MySqlSetCharSetStatement || statement instanceof MySqlSetNamesStatement) {
                    isWhite = true;
                }
            }
        }
    }
    if (!isWhite) {
        addViolation(visitor, ErrorCode.EVIL_HINTS, "hint not allow", x);
    }
}
Also used : MySqlSetNamesStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement) SQLStatementParser(com.alibaba.druid.sql.parser.SQLStatementParser) MySqlSetCharSetStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement) MySqlStatementParser(com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) SQLCommentHint(com.alibaba.druid.sql.ast.SQLCommentHint)

Example 5 with SQLCommentHint

use of com.alibaba.druid.sql.ast.SQLCommentHint in project druid by alibaba.

the class MySqlStatementParser method parseStatementListDialect.

public boolean parseStatementListDialect(List<SQLStatement> statementList) {
    if (lexer.token() == Token.KILL) {
        SQLStatement stmt = parseKill();
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals("PREPARE")) {
        MySqlPrepareStatement stmt = parsePrepare();
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals("EXECUTE")) {
        MySqlExecuteStatement stmt = parseExecute();
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals("DEALLOCATE")) {
        MysqlDeallocatePrepareStatement stmt = parseDeallocatePrepare();
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals("LOAD")) {
        SQLStatement stmt = parseLoad();
        statementList.add(stmt);
        return true;
    }
    if (lexer.token() == Token.REPLACE) {
        MySqlReplaceStatement stmt = parseReplicate();
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals("START")) {
        SQLStartTransactionStatement stmt = parseStart();
        statementList.add(stmt);
        return true;
    }
    if (lexer.token() == Token.SHOW) {
        SQLStatement stmt = parseShow();
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals(BINLOG)) {
        SQLStatement stmt = parseBinlog();
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals(RESET)) {
        SQLStatement stmt = parseReset();
        statementList.add(stmt);
        return true;
    }
    if (lexer.token() == Token.ANALYZE) {
        SQLStatement stmt = parseAnalyze();
        statementList.add(stmt);
        return true;
    }
    if (lexer.token() == Token.OPTIMIZE) {
        SQLStatement stmt = parseOptimize();
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals("HELP")) {
        lexer.nextToken();
        MySqlHelpStatement stmt = new MySqlHelpStatement();
        stmt.setContent(this.exprParser.primary());
        statementList.add(stmt);
        return true;
    }
    if (lexer.token() == Token.DESC || identifierEquals(DESCRIBE)) {
        SQLStatement stmt = parseDescribe();
        statementList.add(stmt);
        return true;
    }
    if (lexer.token() == Token.LOCK) {
        lexer.nextToken();
        String val = lexer.stringVal();
        boolean isLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER;
        boolean isLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == Token.TABLE;
        if (isLockTables || isLockTable) {
            lexer.nextToken();
        } else {
            setErrorEndPos(lexer.pos());
            throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token());
        }
        MySqlLockTableStatement stmt = new MySqlLockTableStatement();
        stmt.setTableSource(this.exprParser.name());
        if (identifierEquals(READ)) {
            lexer.nextToken();
            if (identifierEquals(LOCAL)) {
                lexer.nextToken();
                stmt.setLockType(LockType.READ_LOCAL);
            } else {
                stmt.setLockType(LockType.READ);
            }
        } else if (identifierEquals(WRITE)) {
            stmt.setLockType(LockType.WRITE);
        } else if (identifierEquals(LOW_PRIORITY)) {
            lexer.nextToken();
            acceptIdentifier(WRITE);
            stmt.setLockType(LockType.LOW_PRIORITY_WRITE);
        } else {
            throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token());
        }
        if (lexer.token() == Token.HINT) {
            stmt.setHints(this.exprParser.parseHints());
        }
        statementList.add(stmt);
        return true;
    }
    if (identifierEquals("UNLOCK")) {
        lexer.nextToken();
        String val = lexer.stringVal();
        boolean isUnLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER;
        boolean isUnLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == Token.TABLE;
        statementList.add(new MySqlUnlockTablesStatement());
        if (isUnLockTables || isUnLockTable) {
            lexer.nextToken();
        } else {
            setErrorEndPos(lexer.pos());
            throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token());
        }
        return true;
    }
    if (lexer.token() == Token.HINT) {
        List<SQLCommentHint> hints = this.exprParser.parseHints();
        boolean tddlSelectHints = false;
        if (hints.size() == 1 && statementList.size() == 0 && lexer.token() == Token.SELECT) {
            SQLCommentHint hint = hints.get(0);
            String hintText = hint.getText();
            if (hintText.startsWith("+TDDL")) {
                tddlSelectHints = true;
            }
        }
        if (tddlSelectHints) {
            SQLSelectStatement stmt = (SQLSelectStatement) this.parseStatement();
            stmt.setHeadHints(hints);
            statementList.add(stmt);
            return true;
        }
        MySqlHintStatement stmt = new MySqlHintStatement();
        stmt.setHints(hints);
        statementList.add(stmt);
        return true;
    }
    if (lexer.token() == Token.BEGIN) {
        statementList.add(this.parseBlock());
        return true;
    }
    return false;
}
Also used : ParserException(com.alibaba.druid.sql.parser.ParserException) MySqlUnlockTablesStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement) MySqlLockTableStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement) MySqlHintStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement) MySqlExecuteStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) MySqlReplaceStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement) SQLCommentHint(com.alibaba.druid.sql.ast.SQLCommentHint) MysqlDeallocatePrepareStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MysqlDeallocatePrepareStatement) MySqlHelpStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHelpStatement) MySqlPrepareStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement)

Aggregations

SQLCommentHint (com.alibaba.druid.sql.ast.SQLCommentHint)7 MySqlForceIndexHint (com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint)3 MySqlIgnoreIndexHint (com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint)3 MySqlUseIndexHint (com.alibaba.druid.sql.dialect.mysql.ast.MySqlUseIndexHint)3 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)2 ParserException (com.alibaba.druid.sql.parser.ParserException)2 SQLObject (com.alibaba.druid.sql.ast.SQLObject)1 MySqlCreateTableStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement)1 MySqlExecuteStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement)1 MySqlHelpStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHelpStatement)1 MySqlHintStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlHintStatement)1 MySqlLockTableStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement)1 MySqlPrepareStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement)1 MySqlReplaceStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement)1 MySqlSetCharSetStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement)1 MySqlSetNamesStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement)1 MySqlUnlockTablesStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement)1 MysqlDeallocatePrepareStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MysqlDeallocatePrepareStatement)1 MySqlStatementParser (com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)1 SQLStatementParser (com.alibaba.druid.sql.parser.SQLStatementParser)1