@Override public void enterAlterByAddColumns(MySqlParser.AlterByAddColumnsContext ctx) { // multiple columns are added. Initialize a list of column editors for them parser.runIfNotNull(() -> { columnEditors = new ArrayList<>(ctx.uid().size()); for (MySqlParser.UidContext uidContext : ctx.uid()) { String columnName = parser.parseName(uidContext); columnEditors.add(Column.editor().name(columnName)); } columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditors.get(0), parser.dataTypeResolver(), parser.getConverters()); listeners.add(columnDefinitionListener); }, tableEditor); super.enterAlterByAddColumns(ctx); }
private void addColumnFromTable(TableEditor table, String columnName, String newColumnName, Table selectedTable) { for (Column column : selectedTable.columns()) { if (column.name().equals(columnName)) { table.addColumn(column.edit().name(newColumnName).create()); break; } } } }
@Override public void enterUniqueKeyColumnConstraint(MySqlParser.UniqueKeyColumnConstraintContext ctx) { if (!tableEditor.hasPrimaryKey()) { // take the first unique constrain if no primary key is set tableEditor.addColumn(columnEditor.create()); tableEditor.setPrimaryKeyNames(columnEditor.name()); } super.enterUniqueKeyColumnConstraint(ctx); }
@Override public void enterPrimaryKeyColumnConstraint(MySqlParser.PrimaryKeyColumnConstraintContext ctx) { // this rule will be parsed only if no primary key is set in a table // otherwise the statement can't be executed due to multiple primary key error columnEditor.optional(false); tableEditor.addColumn(columnEditor.create()); tableEditor.setPrimaryKeyNames(columnEditor.name()); super.enterPrimaryKeyColumnConstraint(ctx); }
@Override public void enterCreateView(MySqlParser.CreateViewContext ctx) { if (!parser.skipViews()) { tableEditor = parser.databaseTables().editOrCreateTable(parser.parseQualifiedTableId(ctx.fullId())); // create new columns just with specified name for now if (ctx.uidList() != null) { ctx.uidList().uid().stream().map(parser::parseName).forEach(columnName -> { tableEditor.addColumn(Column.editor().name(columnName).create()); }); } selectColumnsListener = new ViewSelectedColumnsParserListener(tableEditor, parser); listeners.add(selectColumnsListener); } super.enterCreateView(ctx); }
@Override public void enterAlterByAddColumn(MySqlParser.AlterByAddColumnContext ctx) { parser.runIfNotNull(() -> { String columnName = parser.parseName(ctx.uid(0)); ColumnEditor columnEditor = Column.editor().name(columnName); columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditor, parser.dataTypeResolver(), parser.getConverters()); listeners.add(columnDefinitionListener); }, tableEditor); super.exitAlterByAddColumn(ctx); }
@Override public void enterColumnDeclaration(MySqlParser.ColumnDeclarationContext ctx) { parser.runIfNotNull(() -> { String columnName = parser.parseName(ctx.uid()); ColumnEditor columnEditor = Column.editor().name(columnName); if (columnDefinitionListener == null) { columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditor, parser.dataTypeResolver(), parser.getConverters()); listeners.add(columnDefinitionListener); } else { columnDefinitionListener.setColumnEditor(columnEditor); } }, tableEditor); super.enterColumnDeclaration(ctx); }
@Override public void enterAlterView(MySqlParser.AlterViewContext ctx) { if (!parser.skipViews()) { TableId tableId = parser.parseQualifiedTableId(ctx.fullId()); tableEditor = parser.databaseTables().editTable(tableId); if (tableEditor == null) { throw new ParsingException(null, "Trying to alter view " + tableId.toString() + ", which does not exist. Query:" + AntlrDdlParser.getText(ctx)); } // alter view will override existing columns for a new one tableEditor.columnNames().forEach(tableEditor::removeColumn); // create new columns just with specified name for now if (ctx.uidList() != null) { ctx.uidList().uid().stream().map(parser::parseName).forEach(columnName -> { tableEditor.addColumn(Column.editor().name(columnName).create()); }); } selectColumnsListener = new ViewSelectedColumnsParserListener(tableEditor, parser); listeners.add(selectColumnsListener); } super.enterAlterView(ctx); }
@Override public TableEditor renameColumn(String existingName, String newName) { final Column existing = columnWithName(existingName); if (existing == null) throw new IllegalArgumentException("No column with name '" + existingName + "'"); Column newColumn = existing.edit().name(newName).create(); // Determine the primary key names ... List<String> newPkNames = null; if ( !hasUniqueValues() && primaryKeyColumnNames().contains(existing.name())) { newPkNames = new ArrayList<>(primaryKeyColumnNames()); newPkNames.replaceAll(name->existing.name().equals(name) ? newName : name); } // Add the new column, move it before the existing column, and remove the old column ... addColumn(newColumn); reorderColumn(newColumn.name(), existing.name()); removeColumn(existing.name()); if (newPkNames != null) { setPrimaryKeyNames(newPkNames); } return this; }
private Table tableFromFromMessage(List<ReplicationMessage.Column> columns, Table table) { return table.edit() .setColumns(columns.stream() .map(column -> { final PostgresType type = column.getType(); final ColumnEditor columnEditor = Column.editor() .name(column.getName()) .jdbcType(type.getJdbcId()) .type(type.getName()) .optional(column.isOptional()) .nativeType(type.getOid()); columnEditor.length(column.getTypeMetadata().getLength()); columnEditor.scale(column.getTypeMetadata().getScale()); return columnEditor.create(); }) .collect(Collectors.toList()) ) .setPrimaryKeyNames(table.filterColumnNames(c -> table.isPrimaryKeyColumn(c.name()))).create(); } }
@Test(expected = IllegalArgumentException.class) public void shouldNotAllowAddingPrimaryKeyColumnWhenNotFound() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).position(1).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).position(1).create(); editor.addColumns(c1, c2, c3); editor.setPrimaryKeyNames("C1", "WOOPS"); }
@Before public void beforeEach() { column = Column.editor().name("firstName").jdbcType(Types.VARCHAR).type("VARCHAR").position(1).create(); column2 = Column.editor().name("lastName").jdbcType(Types.VARCHAR).type("VARCHAR").position(2).create(); column3 = Column.editor().name("otherColumn").jdbcType(Types.VARCHAR).type("VARCHAR").position(3).create(); fullyQualifiedNames = tableId + "." + column.name() + "," + tableId + "." + column3.name() + ","; }
@Test(expected = IllegalArgumentException.class) public void shouldNotReorderColumnIfNameDoesNotMatch() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).autoIncremented(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).autoIncremented(true).create(); editor.addColumns(c1, c2, c3); editor.reorderColumn("WOOPS", "C2"); assertValidPositions(editor); }
@Test @FixFor("DBZ-644") public void shouldAddTypeInformation() { int length = 255; Column column = Column.editor() .name("col") .type("VARCHAR") .jdbcType(Types.VARCHAR) .length(length) .create(); SchemaBuilder schemaBuilder = SchemaBuilder.string(); new PropagateSourceTypeToSchemaParameter().alterFieldSchema(column, schemaBuilder); assertThat(schemaBuilder.parameters().get("__debezium.source.column.type")).isEqualTo("VARCHAR"); assertThat(schemaBuilder.parameters().get("__debezium.source.column.length")).isEqualTo(String.valueOf(length)); }
@Test public void shouldRemoveColumnByName() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).autoIncremented(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).autoIncremented(true).create(); editor.addColumns(c1, c2, c3); editor.removeColumn("C2"); assertThat(editor.columns()).containsExactly(editor.columnWithName("C1"), editor.columnWithName("C3")); assertValidPositions(editor); }
@Test public void shouldFindNonExistingColumnByNameIndependentOfCase() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).position(1).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).position(1).create(); editor.addColumns(c1, c2, c3); editor.columns().forEach(col -> { assertThat(editor.columnWithName(col.name())).isNotNull(); assertThat(editor.columnWithName(col.name().toUpperCase())).isNotNull(); assertThat(editor.columnWithName(col.name().toLowerCase())).isNotNull(); }); assertThat(editor.columnWithName("WOOPS")).isNull(); }
private ValueConverter createArrayConverter(Column column, Field fieldDefn) { PostgresType arrayType = typeRegistry.get(column.nativeType()); PostgresType elementType = arrayType.getElementType(); final String elementTypeName = elementType.getName(); final String elementColumnName = column.name() + "-element"; final Column elementColumn = Column.editor() .name(elementColumnName) .jdbcType(elementType.getJdbcId()) .nativeType(elementType.getOid()) .type(elementTypeName) .optional(true) .scale(column.scale().orElse(null)) .length(column.length()) .create(); Schema elementSchema = schemaBuilder(elementColumn) .optional() .build(); final Field elementField = new Field(elementColumnName, 0, elementSchema); final ValueConverter elementConverter = converter(elementColumn, elementField); return data -> convertArray(column, fieldDefn, elementConverter, data); }
protected void createColumnWithAllFieldsSetToNonDefaults() { column = editor.name("price") .type("NUMBER") .jdbcType(Types.DOUBLE) .length(5) .scale(2) .position(4) .optional(true) .autoIncremented(true) .generated(true) .create(); }
@Test public void shouldFindGeneratedColumns() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).generated(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).generated(true).create(); editor.addColumns(c1, c2, c3); editor.setPrimaryKeyNames("C1"); table = editor.create(); assertThat(table.retrieveColumnNames()).containsExactly("C1", "C2", "C3"); table.columns().forEach(col -> { assertThat(table.isGenerated(col.name())).isEqualTo(col.isGenerated()); }); assertValidPositions(editor); }
@Test public void shouldFindAutoIncrementedColumns() { editor.tableId(id); Column c1 = columnEditor.name("C1").type("VARCHAR").jdbcType(Types.VARCHAR).length(10).position(1).create(); Column c2 = columnEditor.name("C2").type("NUMBER").jdbcType(Types.NUMERIC).length(5).autoIncremented(true).create(); Column c3 = columnEditor.name("C3").type("DATE").jdbcType(Types.DATE).autoIncremented(true).create(); editor.addColumns(c1, c2, c3); editor.setPrimaryKeyNames("C1"); table = editor.create(); assertThat(table.retrieveColumnNames()).containsExactly("C1", "C2", "C3"); table.columns().forEach(col -> { assertThat(table.isAutoIncremented(col.name())).isEqualTo(col.isAutoIncremented()); }); assertValidPositions(editor); }