Search in sources :

Example 1 with DataType

use of com.alibaba.cobar.parser.ast.fragment.ddl.datatype.DataType in project cobar by alibaba.

the class MySQLDDLParser method dataType.

// data_type:
// | DATE
// | TIME
// | TIMESTAMP
// | DATETIME
// | YEAR
// | spatial_type
private DataType dataType() throws SQLSyntaxErrorException {
    DataType.DataTypeName typeName = null;
    boolean unsigned = false;
    boolean zerofill = false;
    /** for text only */
    boolean binary = false;
    Expression length = null;
    Expression decimals = null;
    Identifier charSet = null;
    Identifier collation = null;
    List<Expression> collectionVals = null;
    typeName: switch(lexer.token()) {
        case KW_TINYINT:
            // | TINYINT[(length)] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.TINYINT;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_SMALLINT:
            // | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.SMALLINT;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_MEDIUMINT:
            // | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.MEDIUMINT;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_INTEGER:
        case KW_INT:
            // | INT[(length)] [UNSIGNED] [ZEROFILL]
            // | INTEGER[(length)] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.INT;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_BIGINT:
            // | BIGINT[(length)] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.BIGINT;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_REAL:
            // | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.REAL;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_COMMA);
                decimals = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_DOUBLE:
            // | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.DOUBLE;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_COMMA);
                decimals = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_FLOAT:
            // | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.FLOAT;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_COMMA);
                decimals = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_NUMERIC:
        case KW_DECIMAL:
        case KW_DEC:
            // | DECIMAL[(length[,decimals])] [UNSIGNED] [ZEROFILL]
            // | NUMERIC[(length[,decimals])] [UNSIGNED] [ZEROFILL]
            typeName = DataType.DataTypeName.DECIMAL;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                if (lexer.token() == PUNC_COMMA) {
                    match(PUNC_COMMA);
                    decimals = exprParser.expression();
                }
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_UNSIGNED) {
                unsigned = true;
                lexer.nextToken();
            }
            if (lexer.token() == KW_ZEROFILL) {
                zerofill = true;
                lexer.nextToken();
            }
            break typeName;
        case KW_CHAR:
            // | CHAR[(length)] [CHARACTER SET charset_name] [COLLATE
            // collation_name]
            typeName = DataType.DataTypeName.CHAR;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            if (lexer.token() == KW_CHARACTER) {
                lexer.nextToken();
                match(KW_SET);
                charSet = identifier();
            }
            if (lexer.token() == KW_COLLATE) {
                lexer.nextToken();
                collation = identifier();
            }
            break typeName;
        case KW_VARCHAR:
            // | VARCHAR(length) [CHARACTER SET charset_name] [COLLATE
            // collation_name]
            typeName = DataType.DataTypeName.VARCHAR;
            lexer.nextToken();
            match(PUNC_LEFT_PAREN);
            length = exprParser.expression();
            match(PUNC_RIGHT_PAREN);
            if (lexer.token() == KW_CHARACTER) {
                lexer.nextToken();
                match(KW_SET);
                charSet = identifier();
            }
            if (lexer.token() == KW_COLLATE) {
                lexer.nextToken();
                collation = identifier();
            }
            break typeName;
        case KW_BINARY:
            // | BINARY[(length)]
            typeName = DataType.DataTypeName.BINARY;
            if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                lexer.nextToken();
                length = exprParser.expression();
                match(PUNC_RIGHT_PAREN);
            }
            break typeName;
        case KW_VARBINARY:
            // | VARBINARY(length)
            typeName = DataType.DataTypeName.VARBINARY;
            lexer.nextToken();
            match(PUNC_LEFT_PAREN);
            length = exprParser.expression();
            match(PUNC_RIGHT_PAREN);
            break typeName;
        case KW_TINYBLOB:
            typeName = DataType.DataTypeName.TINYBLOB;
            lexer.nextToken();
            break typeName;
        case KW_BLOB:
            typeName = DataType.DataTypeName.BLOB;
            lexer.nextToken();
            break typeName;
        case KW_MEDIUMBLOB:
            typeName = DataType.DataTypeName.MEDIUMBLOB;
            lexer.nextToken();
            break typeName;
        case KW_LONGBLOB:
            typeName = DataType.DataTypeName.LONGBLOB;
            lexer.nextToken();
            break typeName;
        case KW_TINYTEXT:
            // | TINYTEXT [BINARY] [CHARACTER SET charset_name] [COLLATE
            // collation_name]
            typeName = DataType.DataTypeName.TINYTEXT;
            if (lexer.nextToken() == KW_BINARY) {
                lexer.nextToken();
                binary = true;
            }
            if (lexer.token() == KW_CHARACTER) {
                lexer.nextToken();
                match(KW_SET);
                charSet = identifier();
            }
            if (lexer.token() == KW_COLLATE) {
                lexer.nextToken();
                collation = identifier();
            }
            break typeName;
        case KW_MEDIUMTEXT:
            // | MEDIUMTEXT [BINARY] [CHARACTER SET charset_name] [COLLATE
            // collation_name]
            typeName = DataType.DataTypeName.MEDIUMTEXT;
            if (lexer.nextToken() == KW_BINARY) {
                lexer.nextToken();
                binary = true;
            }
            if (lexer.token() == KW_CHARACTER) {
                lexer.nextToken();
                match(KW_SET);
                charSet = identifier();
            }
            if (lexer.token() == KW_COLLATE) {
                lexer.nextToken();
                collation = identifier();
            }
            break typeName;
        case KW_LONGTEXT:
            // | LONGTEXT [BINARY] [CHARACTER SET charset_name] [COLLATE
            // collation_name]
            typeName = DataType.DataTypeName.LONGTEXT;
            if (lexer.nextToken() == KW_BINARY) {
                lexer.nextToken();
                binary = true;
            }
            if (lexer.token() == KW_CHARACTER) {
                lexer.nextToken();
                match(KW_SET);
                charSet = identifier();
            }
            if (lexer.token() == KW_COLLATE) {
                lexer.nextToken();
                collation = identifier();
            }
            break typeName;
        case KW_SET:
            // | SET(value1,value2,value3,...) [CHARACTER SET charset_name]
            // [COLLATE collation_name]
            typeName = DataType.DataTypeName.SET;
            lexer.nextToken();
            match(PUNC_LEFT_PAREN);
            for (int i = 0; lexer.token() != PUNC_RIGHT_PAREN; ++i) {
                if (i > 0)
                    match(PUNC_COMMA);
                else
                    collectionVals = new ArrayList<Expression>(2);
                collectionVals.add(exprParser.expression());
            }
            match(PUNC_RIGHT_PAREN);
            if (lexer.token() == KW_CHARACTER) {
                lexer.nextToken();
                match(KW_SET);
                charSet = identifier();
            }
            if (lexer.token() == KW_COLLATE) {
                lexer.nextToken();
                collation = identifier();
            }
            break typeName;
        case IDENTIFIER:
            SpecialIdentifier si = specialIdentifiers.get(lexer.stringValueUppercase());
            if (si != null) {
                switch(si) {
                    case BIT:
                        // BIT[(length)]
                        typeName = DataType.DataTypeName.BIT;
                        if (lexer.nextToken() == PUNC_LEFT_PAREN) {
                            lexer.nextToken();
                            length = exprParser.expression();
                            match(PUNC_RIGHT_PAREN);
                        }
                        break typeName;
                    case DATE:
                        typeName = DataType.DataTypeName.DATE;
                        lexer.nextToken();
                        break typeName;
                    case TIME:
                        typeName = DataType.DataTypeName.TIME;
                        lexer.nextToken();
                        break typeName;
                    case TIMESTAMP:
                        typeName = DataType.DataTypeName.TIMESTAMP;
                        lexer.nextToken();
                        break typeName;
                    case DATETIME:
                        typeName = DataType.DataTypeName.DATETIME;
                        lexer.nextToken();
                        break typeName;
                    case YEAR:
                        typeName = DataType.DataTypeName.YEAR;
                        lexer.nextToken();
                        break typeName;
                    case TEXT:
                        // | TEXT [BINARY] [CHARACTER SET charset_name] [COLLATE
                        // collation_name]
                        typeName = DataType.DataTypeName.TEXT;
                        if (lexer.nextToken() == KW_BINARY) {
                            lexer.nextToken();
                            binary = true;
                        }
                        if (lexer.token() == KW_CHARACTER) {
                            lexer.nextToken();
                            match(KW_SET);
                            charSet = identifier();
                        }
                        if (lexer.token() == KW_COLLATE) {
                            lexer.nextToken();
                            collation = identifier();
                        }
                        break typeName;
                    case ENUM:
                        // | ENUM(value1,value2,value3,...) [CHARACTER SET
                        // charset_name] [COLLATE collation_name]
                        typeName = DataType.DataTypeName.ENUM;
                        lexer.nextToken();
                        match(PUNC_LEFT_PAREN);
                        for (int i = 0; lexer.token() != PUNC_RIGHT_PAREN; ++i) {
                            if (i > 0)
                                match(PUNC_COMMA);
                            else
                                collectionVals = new ArrayList<Expression>(2);
                            collectionVals.add(exprParser.expression());
                        }
                        match(PUNC_RIGHT_PAREN);
                        if (lexer.token() == KW_CHARACTER) {
                            lexer.nextToken();
                            match(KW_SET);
                            charSet = identifier();
                        }
                        if (lexer.token() == KW_COLLATE) {
                            lexer.nextToken();
                            collation = identifier();
                        }
                        break typeName;
                }
            }
        default:
            return null;
    }
    return new DataType(typeName, unsigned, zerofill, binary, length, decimals, charSet, collation, collectionVals);
}
Also used : Identifier(com.alibaba.cobar.parser.ast.expression.primary.Identifier) Expression(com.alibaba.cobar.parser.ast.expression.Expression) DataType(com.alibaba.cobar.parser.ast.fragment.ddl.datatype.DataType)

Example 2 with DataType

use of com.alibaba.cobar.parser.ast.fragment.ddl.datatype.DataType in project cobar by alibaba.

the class MySQLDDLParser method columnDefinition.

// column_definition:
// data_type [NOT NULL | NULL] [DEFAULT default_value]
// [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
// [COMMENT 'string']
// [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]
// [reference_definition]
private ColumnDefinition columnDefinition() throws SQLSyntaxErrorException {
    DataType dataType = dataType();
    boolean notNull = false;
    Expression defaultVal = null;
    boolean autoIncrement = false;
    ColumnDefinition.SpecialIndex sindex = null;
    ColumnDefinition.ColumnFormat format = null;
    LiteralString comment = null;
    if (lexer.token() == KW_NOT) {
        lexer.nextToken();
        match(LITERAL_NULL);
        notNull = true;
    } else if (lexer.token() == LITERAL_NULL) {
        lexer.nextToken();
    }
    if (lexer.token() == KW_DEFAULT) {
        lexer.nextToken();
        defaultVal = exprParser.expression();
        if (!(defaultVal instanceof Literal)) {
            throw new SQLSyntaxErrorException("default value of column must be a literal: " + defaultVal);
        }
    }
    if (lexer.token() == IDENTIFIER && "AUTO_INCREMENT".equals(lexer.stringValueUppercase())) {
        lexer.nextToken();
        autoIncrement = true;
    }
    switch(lexer.token()) {
        case KW_UNIQUE:
            if (lexer.nextToken() == KW_KEY) {
                lexer.nextToken();
            }
            sindex = ColumnDefinition.SpecialIndex.UNIQUE;
            break;
        case KW_PRIMARY:
            lexer.nextToken();
        case KW_KEY:
            match(KW_KEY);
            sindex = ColumnDefinition.SpecialIndex.PRIMARY;
            break;
    }
    if (lexer.token() == IDENTIFIER && "COMMENT".equals(lexer.stringValueUppercase())) {
        lexer.nextToken();
        comment = (LiteralString) exprParser.expression();
    }
    if (lexer.token() == IDENTIFIER && "COLUMN_FORMAT".equals(lexer.stringValueUppercase())) {
        switch(lexer.nextToken()) {
            case KW_DEFAULT:
                lexer.nextToken();
                format = ColumnDefinition.ColumnFormat.DEFAULT;
                break;
            case IDENTIFIER:
                SpecialIdentifier si = specialIdentifiers.get(lexer.stringValueUppercase());
                if (si != null) {
                    switch(si) {
                        case FIXED:
                            lexer.nextToken();
                            format = ColumnDefinition.ColumnFormat.FIXED;
                            break;
                        case DYNAMIC:
                            lexer.nextToken();
                            format = ColumnDefinition.ColumnFormat.DYNAMIC;
                            break;
                    }
                }
        }
    }
    return new ColumnDefinition(dataType, notNull, defaultVal, autoIncrement, sindex, comment, format);
}
Also used : LiteralString(com.alibaba.cobar.parser.ast.expression.primary.literal.LiteralString) Expression(com.alibaba.cobar.parser.ast.expression.Expression) Literal(com.alibaba.cobar.parser.ast.expression.primary.literal.Literal) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) DataType(com.alibaba.cobar.parser.ast.fragment.ddl.datatype.DataType) ColumnDefinition(com.alibaba.cobar.parser.ast.fragment.ddl.ColumnDefinition)

Aggregations

Expression (com.alibaba.cobar.parser.ast.expression.Expression)2 DataType (com.alibaba.cobar.parser.ast.fragment.ddl.datatype.DataType)2 Identifier (com.alibaba.cobar.parser.ast.expression.primary.Identifier)1 Literal (com.alibaba.cobar.parser.ast.expression.primary.literal.Literal)1 LiteralString (com.alibaba.cobar.parser.ast.expression.primary.literal.LiteralString)1 ColumnDefinition (com.alibaba.cobar.parser.ast.fragment.ddl.ColumnDefinition)1 SQLSyntaxErrorException (java.sql.SQLSyntaxErrorException)1