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");
}
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();
}
}
}
}
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);
}
}
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);
}
Aggregations