Search in sources :

Example 1 with DataType

use of io.debezium.relational.ddl.DataType in project debezium by debezium.

the class MySqlDdlParser method parseColumnDefinition.

protected void parseColumnDefinition(Marker start, String columnName, TokenStream tokens, TableEditor table, ColumnEditor column, AtomicBoolean isPrimaryKey) {
    // Parse the data type, which must be at this location ...
    List<ParsingException> errors = new ArrayList<>();
    Marker dataTypeStart = tokens.mark();
    DataType dataType = dataTypeParser.parse(tokens, errors::addAll);
    if (dataType == null) {
        String dataTypeName = parseDomainName(start);
        if (dataTypeName != null)
            dataType = DataType.userDefinedType(dataTypeName);
    }
    if (dataType == null) {
        // No data type was found
        parsingFailed(dataTypeStart.position(), errors, "Unable to read the data type");
        return;
    }
    column.jdbcType(dataType.jdbcType());
    column.type(dataType.name(), dataType.expression());
    if ("ENUM".equals(dataType.name())) {
        column.length(1);
    } else if ("SET".equals(dataType.name())) {
        List<String> options = parseSetAndEnumOptions(dataType.expression());
        // After DBZ-132, it will always be comma seperated
        // number of options + number of commas
        column.length(Math.max(0, options.size() * 2 - 1));
    } else {
        if (dataType.length() > -1)
            column.length((int) dataType.length());
        if (dataType.scale() > -1)
            column.scale(dataType.scale());
    }
    if (Types.NCHAR == dataType.jdbcType() || Types.NVARCHAR == dataType.jdbcType()) {
        // NCHAR and NVARCHAR columns always uses utf8 as charset
        column.charsetName("utf8");
    }
    if (Types.DECIMAL == dataType.jdbcType()) {
        if (dataType.length() == -1) {
            column.length(10);
        }
        if (dataType.scale() == -1) {
            column.scale(0);
        }
    }
    if (tokens.canConsume("CHARSET") || tokens.canConsume("CHARACTER", "SET")) {
        String charsetName = tokens.consume();
        if (!"DEFAULT".equalsIgnoreCase(charsetName)) {
            // Only record it if not inheriting the character set from the table
            column.charsetName(charsetName);
        }
    }
    if (tokens.canConsume("COLLATE")) {
        // name of collation
        tokens.consume();
    }
    if (tokens.canConsume("AS") || tokens.canConsume("GENERATED", "ALWAYS", "AS")) {
        consumeExpression(start);
        tokens.canConsumeAnyOf("VIRTUAL", "STORED");
        if (tokens.canConsume("UNIQUE")) {
            tokens.canConsume("KEY");
        }
        if (tokens.canConsume("COMMENT")) {
            consumeQuotedString();
        }
        tokens.canConsume("NOT", "NULL");
        tokens.canConsume("NULL");
        tokens.canConsume("PRIMARY", "KEY");
        tokens.canConsume("KEY");
    } else {
        while (tokens.matchesAnyOf("NOT", "NULL", "DEFAULT", "AUTO_INCREMENT", "UNIQUE", "PRIMARY", "KEY", "COMMENT", "REFERENCES", "COLUMN_FORMAT", "ON", "COLLATE")) {
            // Nullability ...
            if (tokens.canConsume("NOT", "NULL")) {
                column.optional(false);
            } else if (tokens.canConsume("NULL")) {
                column.optional(true);
            }
            // Default value ...
            if (tokens.matches("DEFAULT")) {
                parseDefaultClause(start);
            }
            if (tokens.matches("ON", "UPDATE") || tokens.matches("ON", "DELETE")) {
                parseOnUpdateOrDelete(tokens.mark());
                column.autoIncremented(true);
            }
            // Other options ...
            if (tokens.canConsume("AUTO_INCREMENT")) {
                column.autoIncremented(true);
                column.generated(true);
            }
            if (tokens.canConsume("UNIQUE", "KEY") || tokens.canConsume("UNIQUE")) {
                if (table.primaryKeyColumnNames().isEmpty() && !column.isOptional()) {
                    // The table has no primary key (yet) but this is a non-null column and therefore will have all unique
                    // values (MySQL allows UNIQUE indexes with some nullable columns, but in that case allows duplicate
                    // rows),
                    // so go ahead and set it to this column as it's a unique key
                    isPrimaryKey.set(true);
                }
            }
            if (tokens.canConsume("PRIMARY", "KEY") || tokens.canConsume("KEY")) {
                // Always set this column as the primary key
                // MySQL primary key columns may not be null
                column.optional(false);
                isPrimaryKey.set(true);
            }
            if (tokens.canConsume("COMMENT")) {
                consumeQuotedString();
            }
            if (tokens.canConsume("COLUMN_FORMAT")) {
                tokens.consumeAnyOf("FIXED", "DYNAMIC", "DEFAULT");
            }
            if (tokens.matches("REFERENCES")) {
                parseReferenceDefinition(start);
            }
            if (tokens.canConsume("COLLATE")) {
                // name of collation
                tokens.consume();
            }
        }
    }
}
Also used : ParsingException(io.debezium.text.ParsingException) ArrayList(java.util.ArrayList) DataType(io.debezium.relational.ddl.DataType) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) Marker(io.debezium.text.TokenStream.Marker)

Aggregations

DataType (io.debezium.relational.ddl.DataType)1 ParsingException (io.debezium.text.ParsingException)1 Marker (io.debezium.text.TokenStream.Marker)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1