Search in sources :

Example 6 with ParsingException

use of io.debezium.text.ParsingException in project debezium by debezium.

the class MySqlDdlParser method sequentially.

/**
 * Try calling the supplied functions in sequence, stopping as soon as one of them succeeds.
 *
 * @param functions the functions
 */
@SuppressWarnings("unchecked")
protected void sequentially(Consumer<Marker>... functions) {
    if (functions == null || functions.length == 0)
        return;
    Collection<ParsingException> errors = new ArrayList<>();
    Marker marker = tokens.mark();
    for (Consumer<Marker> function : functions) {
        try {
            function.accept(marker);
            return;
        } catch (ParsingException e) {
            errors.add(e);
            tokens.rewind(marker);
        }
    }
    parsingFailed(marker.position(), errors, "One or more errors trying to parse statement");
}
Also used : ParsingException(io.debezium.text.ParsingException) ArrayList(java.util.ArrayList) Marker(io.debezium.text.TokenStream.Marker)

Example 7 with ParsingException

use of io.debezium.text.ParsingException 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)

Example 8 with ParsingException

use of io.debezium.text.ParsingException in project debezium by debezium.

the class DdlParser method parse.

/**
 * Examine the stream starting at its current position for DDL statements, and apply those statements to the specified
 * database table definitions.
 *
 * @param ddlContent the stream of tokens containing the DDL statements; may not be null
 * @param databaseTables the database's table definitions, which should be used by this method to create, change, or remove
 *            tables as defined in the DDL content; may not be null
 * @throws ParsingException if there is a problem parsing the supplied content
 * @throws IllegalStateException if the supplied token stream is in an invalid state
 */
public final void parse(TokenStream ddlContent, Tables databaseTables) throws ParsingException, IllegalStateException {
    this.tokens = ddlContent;
    this.databaseTables = databaseTables;
    Marker marker = ddlContent.mark();
    try {
        while (ddlContent.hasNext()) {
            parseNextStatement(ddlContent.mark());
            // Consume the statement terminator if it is still there ...
            tokens.canConsume(DdlTokenizer.STATEMENT_TERMINATOR);
        }
    } catch (ParsingException e) {
        ddlContent.rewind(marker);
        throw new ParsingException(e.getPosition(), "Failed to parse statement '" + ddlContent.getInputString() + "'", e);
    } catch (Throwable t) {
        parsingFailed(ddlContent.nextPosition(), "Unexpected exception while parsing statement " + ddlContent.getInputString(), t);
    }
}
Also used : ParsingException(io.debezium.text.ParsingException) Marker(io.debezium.text.TokenStream.Marker)

Example 9 with ParsingException

use of io.debezium.text.ParsingException in project debezium by debezium.

the class DdlParserSql2003 method parseCreateTable.

protected void parseCreateTable(Marker start) {
    tokens.canConsumeAnyOf("GLOBAL", "LOCAL", "TEMPORARY");
    tokens.consume("TABLE");
    TableId tableId = parseQualifiedTableName(start);
    TableEditor table = databaseTables.editOrCreateTable(tableId);
    if (tokens.matches('(')) {
        // Is either a subquery clause preceded by column name list, or table element list...
        Marker tableContentStart = tokens.mark();
        try {
            parseAsSubqueryClause(start, table);
        } catch (ParsingException e) {
            tokens.rewind(tableContentStart);
            parseTableElementList(start, table);
        }
    } else if (tokens.canConsume("OF")) {
        // Read the qualified name ...
        parseSchemaQualifiedName(start);
        if (tokens.canConsume("UNDER")) {
            // parent table name ...
            parseSchemaQualifiedName(start);
        }
        if (tokens.matches('(')) {
            parseTableElementList(start, table);
        }
    } else if (tokens.canConsume("AS")) {
        parseAsSubqueryClause(start, table);
    }
    if (tokens.canConsume("ON", "COMMIT")) {
        tokens.canConsume("PRESERVE");
        tokens.canConsume("DELETE");
        tokens.consume("ROWS");
    }
    // Update the table definition ...
    databaseTables.overwriteTable(table.create());
    signalCreateTable(tableId, start);
}
Also used : TableId(io.debezium.relational.TableId) ParsingException(io.debezium.text.ParsingException) Marker(io.debezium.text.TokenStream.Marker) TableEditor(io.debezium.relational.TableEditor)

Aggregations

ParsingException (io.debezium.text.ParsingException)9 Marker (io.debezium.text.TokenStream.Marker)7 TableId (io.debezium.relational.TableId)3 ArrayList (java.util.ArrayList)3 Table (io.debezium.relational.Table)2 TableEditor (io.debezium.relational.TableEditor)2 Column (io.debezium.relational.Column)1 TableSchema (io.debezium.relational.TableSchema)1 DataType (io.debezium.relational.ddl.DataType)1 MultipleParsingExceptions (io.debezium.text.MultipleParsingExceptions)1 Position (io.debezium.text.Position)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 ConnectException (org.apache.kafka.connect.errors.ConnectException)1