use of io.debezium.relational.TableEditor in project debezium by debezium.
the class MySqlDdlParser method parseAlterTable.
protected void parseAlterTable(Marker start) {
tokens.canConsume("IGNORE");
tokens.consume("TABLE");
TableId tableId = parseQualifiedTableName(start);
TableEditor table = databaseTables.editTable(tableId);
TableId oldTableId = null;
if (table != null) {
AtomicReference<TableId> newTableName = new AtomicReference<>(null);
if (!tokens.matches(terminator()) && !tokens.matches("PARTITION")) {
parseAlterSpecificationList(start, table, newTableName::set);
}
if (tokens.matches("PARTITION")) {
parsePartitionOptions(start, table);
}
databaseTables.overwriteTable(table.create());
if (newTableName.get() != null) {
// the table was renamed ...
Table renamed = databaseTables.renameTable(tableId, newTableName.get());
if (renamed != null) {
oldTableId = tableId;
tableId = renamed.id();
}
}
} else {
Marker marker = tokens.mark();
try {
// We don't know about this table but we still have to parse the statement ...
table = TableEditor.noOp(tableId);
if (!tokens.matches(terminator()) && !tokens.matches("PARTITION")) {
parseAlterSpecificationList(start, table, str -> {
});
}
if (tokens.matches("PARTITION")) {
parsePartitionOptions(start, table);
}
parseTableOptions(start, table);
// do nothing with this
} catch (ParsingException e) {
tokens.rewind(marker);
consumeRemainingStatement(start);
}
}
signalAlterTable(tableId, oldTableId, start);
}
use of io.debezium.relational.TableEditor in project debezium by debezium.
the class MySqlDdlParser method parseCreateIndex.
protected void parseCreateIndex(Marker start) {
boolean unique = tokens.canConsume("UNIQUE");
tokens.canConsumeAnyOf("FULLTEXT", "SPATIAL");
tokens.consume("INDEX");
// index name
String indexName = tokens.consume();
if (tokens.matches("USING")) {
parseIndexType(start);
}
TableId tableId = null;
if (tokens.canConsume("ON")) {
// Usually this is required, but in some cases ON is not required
tableId = parseQualifiedTableName(start);
}
if (unique && tableId != null) {
// This is a unique index, and we can mark the index's columns as the primary key iff there is not already
// a primary key on the table. (Should a PK be created later via an alter, then it will overwrite this.)
TableEditor table = databaseTables.editTable(tableId);
if (table != null && !table.hasPrimaryKey()) {
List<String> names = parseIndexColumnNames(start);
if (table.columns().stream().allMatch(Column::isRequired)) {
databaseTables.overwriteTable(table.setPrimaryKeyNames(names).create());
}
}
}
// We don't care about any other statements or the rest of this statement ...
consumeRemainingStatement(start);
signalCreateIndex(indexName, tableId, start);
debugParsed(start);
}
use of io.debezium.relational.TableEditor in project debezium by debezium.
the class MySqlDdlParser method parseCreateTable.
protected void parseCreateTable(Marker start) {
tokens.canConsume("TEMPORARY");
tokens.consume("TABLE");
boolean onlyIfNotExists = tokens.canConsume("IF", "NOT", "EXISTS");
TableId tableId = parseQualifiedTableName(start);
if (tokens.canConsume("LIKE")) {
TableId originalId = parseQualifiedTableName(start);
Table original = databaseTables.forTable(originalId);
if (original != null) {
databaseTables.overwriteTable(tableId, original.columns(), original.primaryKeyColumnNames(), original.defaultCharsetName());
}
consumeRemainingStatement(start);
signalCreateTable(tableId, start);
debugParsed(start);
return;
}
if (onlyIfNotExists && databaseTables.forTable(tableId) != null) {
// The table does exist, so we should do nothing ...
consumeRemainingStatement(start);
signalCreateTable(tableId, start);
debugParsed(start);
return;
}
TableEditor table = databaseTables.editOrCreateTable(tableId);
// create_definition ...
if (tokens.matches('('))
parseCreateDefinitionList(start, table);
// table_options ...
parseTableOptions(start, table);
// partition_options ...
if (tokens.matches("PARTITION")) {
parsePartitionOptions(start, table);
}
// select_statement
if (tokens.canConsume("AS") || tokens.canConsume("IGNORE", "AS") || tokens.canConsume("REPLACE", "AS")) {
parseAsSelectStatement(start, table);
}
// Make sure that the table's character set has been set ...
if (!table.hasDefaultCharsetName()) {
table.setDefaultCharsetName(currentDatabaseCharset());
}
// Update the table definition ...
databaseTables.overwriteTable(table.create());
signalCreateTable(tableId, start);
debugParsed(start);
}
use of io.debezium.relational.TableEditor in project debezium by debezium.
the class MySqlDdlParser method parseCreateView.
protected void parseCreateView(Marker start) {
tokens.canConsume("OR", "REPLACE");
if (tokens.canConsume("ALGORITHM")) {
tokens.consume('=');
tokens.consumeAnyOf("UNDEFINED", "MERGE", "TEMPTABLE");
}
parseDefiner(tokens.mark());
if (tokens.canConsume("SQL", "SECURITY")) {
tokens.consumeAnyOf("DEFINER", "INVOKER");
}
tokens.consume("VIEW");
TableId tableId = parseQualifiedTableName(start);
if (skipViews) {
// We don't care about the rest ...
consumeRemainingStatement(start);
signalCreateView(tableId, start);
debugSkipped(start);
return;
}
TableEditor table = databaseTables.editOrCreateTable(tableId);
if (tokens.matches('(')) {
List<String> columnNames = parseColumnNameList(start);
// We know nothing other than the names ...
columnNames.forEach(name -> {
table.addColumn(Column.editor().name(name).create());
});
}
tokens.canConsume("AS");
// We should try to discover the types of the columns by looking at this select
if (tokens.canConsume("SELECT")) {
// If the SELECT clause is selecting qualified column names or columns names from a single table, then
// we can look up the columns and use those to set the type and nullability of the view's columns ...
Map<String, Column> selectedColumnsByAlias = parseColumnsInSelectClause(start);
if (table.columns().isEmpty()) {
selectedColumnsByAlias.forEach((columnName, fromTableColumn) -> {
if (fromTableColumn != null && columnName != null)
table.addColumn(fromTableColumn.edit().name(columnName).create());
});
} else {
List<Column> changedColumns = new ArrayList<>();
table.columns().forEach(column -> {
// Find the column from the SELECT statement defining the view ...
Column selectedColumn = selectedColumnsByAlias.get(column.name());
if (selectedColumn != null) {
changedColumns.add(column.edit().jdbcType(selectedColumn.jdbcType()).type(selectedColumn.typeName(), selectedColumn.typeExpression()).length(selectedColumn.length()).scale(selectedColumn.scale()).autoIncremented(selectedColumn.isAutoIncremented()).generated(selectedColumn.isGenerated()).optional(selectedColumn.isOptional()).create());
}
});
changedColumns.forEach(table::addColumn);
}
// Parse the FROM clause to see if the view is only referencing a single table, and if so then update the view
// with an equivalent primary key ...
Map<String, Table> fromTables = parseSelectFromClause(start);
if (fromTables.size() == 1) {
Table fromTable = fromTables.values().stream().findFirst().get();
List<String> fromTablePkColumnNames = fromTable.columnNames();
List<String> viewPkColumnNames = new ArrayList<>();
selectedColumnsByAlias.forEach((viewColumnName, fromTableColumn) -> {
if (fromTablePkColumnNames.contains(fromTableColumn.name())) {
viewPkColumnNames.add(viewColumnName);
}
});
if (viewPkColumnNames.size() == fromTablePkColumnNames.size()) {
table.setPrimaryKeyNames(viewPkColumnNames);
}
}
}
// We don't care about the rest ...
consumeRemainingStatement(start);
// Update the table definition ...
databaseTables.overwriteTable(table.create());
signalCreateView(tableId, start);
debugParsed(start);
}
use of io.debezium.relational.TableEditor in project debezium by debezium.
the class DdlParserSql2003 method parseAlterTable.
protected void parseAlterTable(Marker start) {
tokens.canConsume("IGNORE");
tokens.consume("TABLE");
TableId tableId = parseQualifiedTableName(start);
TableEditor table = databaseTables.editOrCreateTable(tableId);
if (tokens.matches("ADD", "CONSTRAINT") || tokens.matches("ADD", "UNIQUE") || tokens.matches("ADD", "PRIMARY") || tokens.matches("ADD", "FOREIGN") || tokens.matches("ADD", "CHECK")) {
tokens.consume("ADD");
parseTableConstraintDefinition(start, table);
} else if (tokens.canConsume("ADD", "COLUMN") || tokens.canConsume("ADD")) {
// Adding a column ...
String columnName = tokens.consume();
ColumnEditor column = Column.editor().name(columnName);
AtomicBoolean isPrimaryKey = new AtomicBoolean(false);
parseColumnDefinition(start, columnName, tokens, table, column, isPrimaryKey);
// Update the table ...
Column newColumnDefn = column.create();
table.addColumn(newColumnDefn);
if (isPrimaryKey.get()) {
table.setPrimaryKeyNames(newColumnDefn.name());
}
} else if (tokens.canConsume("ALTER", "COLUMN") || tokens.canConsume("ALTER")) {
// Altering a column ...
String columnName = tokens.consume();
Column existingColumn = table.columnWithName(columnName);
ColumnEditor column = existingColumn != null ? existingColumn.edit() : Column.editor().name(columnName);
parseAlterColumn(start, column);
// Update the table ...
Column newColumnDefn = column.create();
table.setColumns(newColumnDefn);
} else if (tokens.matches("DROP", "CONSTRAINT")) {
parseDropTableConstraint(start, table);
} else if (tokens.canConsume("DROP", "COLUMN") || tokens.canConsume("DROP")) {
parseDropColumn(start, table);
}
databaseTables.overwriteTable(table.create());
// rename is not supported
signalAlterTable(tableId, null, start);
}
Aggregations