DBZ-252 Rebase to master
This commit is contained in:
parent
5022933581
commit
9580c8c290
@ -73,6 +73,7 @@ public Object convert(Column column, String value) {
|
||||
|
||||
case Types.FLOAT:
|
||||
case Types.DOUBLE:
|
||||
case Types.REAL:
|
||||
return convertToDouble(value);
|
||||
case Types.BIGINT:
|
||||
return convertToBigInt(value);
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
package io.debezium.connector.mysql;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -98,18 +99,6 @@ public MySqlSchema(Configuration config, String serverName, Predicate<String> gt
|
||||
this.topicSelector = topicSelector;
|
||||
this.tableIdCaseInsensitive = tableIdCaseInsensitive;
|
||||
|
||||
String ddlParsingModeStr = config.getString(MySqlConnectorConfig.DDL_PARSER_MODE);
|
||||
DdlParsingMode parsingMode = DdlParsingMode.parse(ddlParsingModeStr, MySqlConnectorConfig.DDL_PARSER_MODE.defaultValueAsString());
|
||||
|
||||
try {
|
||||
this.ddlParser = parsingMode.getParserClass().newInstance();
|
||||
this.ddlChanges = this.ddlParser.getDdlChanges();
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException e) {
|
||||
// ddl parser constructors are not throwing any exceptions, so this should never happen
|
||||
throw new IllegalArgumentException("Unable to create new instance for ddl parser class " + parsingMode.getParserClass().getCanonicalName());
|
||||
}
|
||||
|
||||
// Use MySQL-specific converters and schemas for values ...
|
||||
String timePrecisionModeStr = config.getString(MySqlConnectorConfig.TIME_PRECISION_MODE);
|
||||
TemporalPrecisionMode timePrecisionMode = TemporalPrecisionMode.parse(timePrecisionModeStr);
|
||||
@ -122,9 +111,17 @@ public MySqlSchema(Configuration config, String serverName, Predicate<String> gt
|
||||
MySqlValueConverters valueConverters = new MySqlValueConverters(decimalMode, timePrecisionMode, bigIntUnsignedMode);
|
||||
this.schemaBuilder = new TableSchemaBuilder(valueConverters, schemaNameAdjuster, SourceInfo.SCHEMA);
|
||||
|
||||
this.ddlParser = new MySqlDdlParser(false, valueConverters);
|
||||
this.ddlChanges = new DdlChanges(this.ddlParser.terminator());
|
||||
this.ddlParser.addListener(ddlChanges);
|
||||
String ddlParsingModeStr = config.getString(MySqlConnectorConfig.DDL_PARSER_MODE);
|
||||
DdlParsingMode parsingMode = DdlParsingMode.parse(ddlParsingModeStr, MySqlConnectorConfig.DDL_PARSER_MODE.defaultValueAsString());
|
||||
|
||||
try {
|
||||
this.ddlParser = parsingMode.getParserClass().getConstructor(MySqlValueConverters.class).newInstance(valueConverters);
|
||||
this.ddlChanges = this.ddlParser.getDdlChanges();
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
// ddl parser constructors are not throwing any exceptions, so this should never happen
|
||||
throw new IllegalArgumentException("Unable to create new instance for ddl parser class " + parsingMode.getParserClass().getCanonicalName());
|
||||
}
|
||||
|
||||
// Set up the server name and schema prefix ...
|
||||
if (serverName != null) serverName = serverName.trim();
|
||||
|
@ -11,6 +11,7 @@
|
||||
import io.debezium.antlr.DataTypeResolver;
|
||||
import io.debezium.antlr.DataTypeResolver.DataTypeEntry;
|
||||
import io.debezium.connector.mysql.MySqlSystemVariables;
|
||||
import io.debezium.connector.mysql.MySqlValueConverters;
|
||||
import io.debezium.connector.mysql.antlr.listener.MySqlAntlrDdlParserListener;
|
||||
import io.debezium.ddl.parser.mysql.generated.MySqlLexer;
|
||||
import io.debezium.ddl.parser.mysql.generated.MySqlParser;
|
||||
@ -40,18 +41,24 @@
|
||||
public class MySqlAntlrDdlParser extends AntlrDdlParser<MySqlLexer, MySqlParser> {
|
||||
|
||||
private final ConcurrentMap<String, String> charsetNameForDatabase = new ConcurrentHashMap<>();
|
||||
private final MySqlValueConverters converters;
|
||||
|
||||
public MySqlAntlrDdlParser() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public MySqlAntlrDdlParser(boolean throwErrorsFromTreeWalk) {
|
||||
this(throwErrorsFromTreeWalk, false);
|
||||
public MySqlAntlrDdlParser(MySqlValueConverters converters) {
|
||||
this(true, false, converters);
|
||||
}
|
||||
|
||||
public MySqlAntlrDdlParser(boolean throwErrorsFromTreeWalk, boolean includeViews) {
|
||||
public MySqlAntlrDdlParser(boolean throwErrorsFromTreeWalk) {
|
||||
this(throwErrorsFromTreeWalk, false, null);
|
||||
}
|
||||
|
||||
public MySqlAntlrDdlParser(boolean throwErrorsFromTreeWalk, boolean includeViews, MySqlValueConverters converters) {
|
||||
super(throwErrorsFromTreeWalk, includeViews);
|
||||
systemVariables = new MySqlSystemVariables();
|
||||
this.converters = converters;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -291,4 +298,8 @@ public static List<String> parseSetAndEnumOptions(String typeExpression) {
|
||||
return options;
|
||||
}
|
||||
|
||||
public MySqlValueConverters getConverters() {
|
||||
return converters;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public void enterAlterByAddColumn(MySqlParser.AlterByAddColumnContext ctx) {
|
||||
parserCtx.runIfNotNull(() -> {
|
||||
String columnName = parserCtx.parseName(ctx.uid(0));
|
||||
ColumnEditor columnEditor = Column.editor().name(columnName);
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditor, parserCtx.dataTypeResolver());
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditor, parserCtx.dataTypeResolver(), parserCtx.getConverters());
|
||||
listeners.add(columnDefinitionListener);
|
||||
}, tableEditor);
|
||||
super.exitAlterByAddColumn(ctx);
|
||||
@ -103,7 +103,7 @@ public void enterAlterByAddColumns(MySqlParser.AlterByAddColumnsContext ctx) {
|
||||
String columnName = parserCtx.parseName(uidContext);
|
||||
columnEditors.add(Column.editor().name(columnName));
|
||||
}
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditors.get(0), parserCtx.dataTypeResolver());
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditors.get(0), parserCtx.dataTypeResolver(), parserCtx.getConverters());
|
||||
listeners.add(columnDefinitionListener);
|
||||
}, tableEditor);
|
||||
super.enterAlterByAddColumns(ctx);
|
||||
@ -143,7 +143,7 @@ public void enterAlterByChangeColumn(MySqlParser.AlterByChangeColumnContext ctx)
|
||||
String oldColumnName = parserCtx.parseName(ctx.oldColumn);
|
||||
Column existingColumn = tableEditor.columnWithName(oldColumnName);
|
||||
if (existingColumn != null) {
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, existingColumn.edit(), parserCtx.dataTypeResolver());
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, existingColumn.edit(), parserCtx.dataTypeResolver(), parserCtx.getConverters());
|
||||
listeners.add(columnDefinitionListener);
|
||||
}
|
||||
else {
|
||||
@ -178,7 +178,7 @@ public void enterAlterByModifyColumn(MySqlParser.AlterByModifyColumnContext ctx)
|
||||
String columnName = parserCtx.parseName(ctx.uid(0));
|
||||
Column column = tableEditor.columnWithName(columnName);
|
||||
if (column != null) {
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, column.edit(), parserCtx.dataTypeResolver());
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, column.edit(), parserCtx.dataTypeResolver(), parserCtx.getConverters());
|
||||
listeners.add(columnDefinitionListener);
|
||||
}
|
||||
else {
|
||||
|
@ -6,18 +6,26 @@
|
||||
|
||||
package io.debezium.connector.mysql.antlr.listener;
|
||||
|
||||
import io.debezium.antlr.DataTypeResolver;
|
||||
import io.debezium.ddl.parser.mysql.generated.MySqlParser;
|
||||
import io.debezium.ddl.parser.mysql.generated.MySqlParserBaseListener;
|
||||
import io.debezium.relational.Column;
|
||||
import io.debezium.relational.ColumnEditor;
|
||||
import io.debezium.relational.TableEditor;
|
||||
import io.debezium.relational.ddl.DataType;
|
||||
import static io.debezium.antlr.AntlrDdlParser.getText;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
|
||||
import static io.debezium.antlr.AntlrDdlParser.getText;
|
||||
import org.apache.kafka.connect.data.Field;
|
||||
import org.apache.kafka.connect.data.Schema;
|
||||
import org.apache.kafka.connect.data.SchemaBuilder;
|
||||
|
||||
import io.debezium.antlr.DataTypeResolver;
|
||||
import io.debezium.connector.mysql.MySqlDefaultValuePreConverter;
|
||||
import io.debezium.connector.mysql.MySqlValueConverters;
|
||||
import io.debezium.ddl.parser.mysql.generated.MySqlParser;
|
||||
import io.debezium.ddl.parser.mysql.generated.MySqlParser.DefaultValueContext;
|
||||
import io.debezium.ddl.parser.mysql.generated.MySqlParserBaseListener;
|
||||
import io.debezium.relational.Column;
|
||||
import io.debezium.relational.ColumnEditor;
|
||||
import io.debezium.relational.TableEditor;
|
||||
import io.debezium.relational.ValueConverter;
|
||||
import io.debezium.relational.ddl.DataType;
|
||||
|
||||
/**
|
||||
* Parser listeners that is parsing column definition part of MySQL statements.
|
||||
@ -30,10 +38,14 @@ public class ColumnDefinitionParserListener extends MySqlParserBaseListener {
|
||||
private final TableEditor tableEditor;
|
||||
private ColumnEditor columnEditor;
|
||||
|
||||
public ColumnDefinitionParserListener(TableEditor tableEditor, ColumnEditor columnEditor, DataTypeResolver dataTypeResolver) {
|
||||
private final MySqlValueConverters converters;
|
||||
private final MySqlDefaultValuePreConverter defaultValuePreConverter = new MySqlDefaultValuePreConverter();
|
||||
|
||||
public ColumnDefinitionParserListener(TableEditor tableEditor, ColumnEditor columnEditor, DataTypeResolver dataTypeResolver, MySqlValueConverters converters) {
|
||||
this.tableEditor = tableEditor;
|
||||
this.columnEditor = columnEditor;
|
||||
this.dataTypeResolver = dataTypeResolver;
|
||||
this.converters = converters;
|
||||
}
|
||||
|
||||
public void setColumnEditor(ColumnEditor columnEditor) {
|
||||
@ -80,6 +92,44 @@ public void enterNullNotnull(MySqlParser.NullNotnullContext ctx) {
|
||||
super.enterNullNotnull(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterDefaultValue(DefaultValueContext ctx) {
|
||||
String sign = "";
|
||||
if (ctx.NULL_LITERAL() != null) {
|
||||
return;
|
||||
}
|
||||
if (ctx.unaryOperator() != null) {
|
||||
sign = ctx.unaryOperator().getText();
|
||||
}
|
||||
if (ctx.constant() != null) {
|
||||
if (ctx.constant().stringLiteral() != null) {
|
||||
columnEditor.defaultValue(sign + unquote(ctx.constant().stringLiteral().getText()));
|
||||
}
|
||||
else if (ctx.constant().decimalLiteral() != null) {
|
||||
columnEditor.defaultValue(sign + ctx.constant().decimalLiteral().getText());
|
||||
}
|
||||
else if (ctx.constant().BIT_STRING() != null) {
|
||||
columnEditor.defaultValue(unquoteBinary(ctx.constant().BIT_STRING().getText()));
|
||||
}
|
||||
else if (ctx.constant().booleanLiteral() != null) {
|
||||
columnEditor.defaultValue(ctx.constant().booleanLiteral().getText());
|
||||
}
|
||||
else if (ctx.constant().REAL_LITERAL() != null) {
|
||||
columnEditor.defaultValue(ctx.constant().REAL_LITERAL().getText());
|
||||
}
|
||||
}
|
||||
else if (ctx.timeDefinition() != null) {
|
||||
if (ctx.timeDefinition().CURRENT_TIMESTAMP() != null || ctx.timeDefinition().NOW() != null) {
|
||||
columnEditor.defaultValue("1970-01-01 00:00:00");
|
||||
}
|
||||
else {
|
||||
columnEditor.defaultValue(ctx.timeDefinition().getText());
|
||||
}
|
||||
}
|
||||
convertDefaultValueToSchemaType(columnEditor);
|
||||
super.enterDefaultValue(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterAutoIncrementColumnConstraint(MySqlParser.AutoIncrementColumnConstraintContext ctx) {
|
||||
columnEditor.autoIncremented(true);
|
||||
@ -191,4 +241,35 @@ else if (dataTypeContext instanceof MySqlParser.CollectionDataTypeContext) {
|
||||
columnEditor.charsetName(charsetName);
|
||||
}
|
||||
}
|
||||
|
||||
private void convertDefaultValueToSchemaType(ColumnEditor columnEditor) {
|
||||
final Column column = columnEditor.create();
|
||||
// if converters is not null and the default value is not null, we need to convert default value
|
||||
if (converters != null && columnEditor.defaultValue() != null) {
|
||||
Object defaultValue = columnEditor.defaultValue();
|
||||
final SchemaBuilder schemaBuilder = converters.schemaBuilder(column);
|
||||
if (schemaBuilder == null) {
|
||||
return;
|
||||
}
|
||||
final Schema schema = schemaBuilder.build();
|
||||
//In order to get the valueConverter for this column, we have to create a field;
|
||||
//The index value -1 in the field will never used when converting default value;
|
||||
//So we can set any number here;
|
||||
final Field field = new Field(column.name(), -1, schema);
|
||||
final ValueConverter valueConverter = converters.converter(column, field);
|
||||
if (defaultValue instanceof String) {
|
||||
defaultValue = defaultValuePreConverter.convert(column, (String)defaultValue);
|
||||
}
|
||||
defaultValue = valueConverter.convert(defaultValue);
|
||||
columnEditor.defaultValue(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
private String unquote(String stringLiteral) {
|
||||
return stringLiteral.substring(1, stringLiteral.length() - 1);
|
||||
}
|
||||
|
||||
private String unquoteBinary(String stringLiteral) {
|
||||
return stringLiteral.substring(2, stringLiteral.length() - 1);
|
||||
}
|
||||
}
|
@ -77,7 +77,7 @@ public void enterColumnDeclaration(MySqlParser.ColumnDeclarationContext ctx) {
|
||||
String columnName = parserCtx.parseName(ctx.uid());
|
||||
ColumnEditor columnEditor = Column.editor().name(columnName);
|
||||
if (columnDefinitionListener == null) {
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditor, parserCtx.dataTypeResolver());
|
||||
columnDefinitionListener = new ColumnDefinitionParserListener(tableEditor, columnEditor, parserCtx.dataTypeResolver(), parserCtx.getConverters());
|
||||
listeners.add(columnDefinitionListener);
|
||||
} else {
|
||||
columnDefinitionListener.setColumnEditor(columnEditor);
|
||||
|
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright Debezium Authors.
|
||||
*
|
||||
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package io.debezium.connector.mysql;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import io.debezium.jdbc.JdbcValueConverters;
|
||||
import io.debezium.jdbc.TemporalPrecisionMode;
|
||||
import io.debezium.relational.Table;
|
||||
import io.debezium.relational.TableId;
|
||||
import io.debezium.relational.Tables;
|
||||
import io.debezium.relational.ddl.AbstractDdlParser;
|
||||
|
||||
/**
|
||||
* @author laomei
|
||||
*/
|
||||
public abstract class AbstractMysqlDefaultValueTest {
|
||||
|
||||
private AbstractDdlParser parser;
|
||||
private Tables tables;
|
||||
private MySqlValueConverters converters;
|
||||
protected Function<MySqlValueConverters, AbstractDdlParser> parserProducer;
|
||||
|
||||
@Before
|
||||
public void beforeEach() {
|
||||
converters = new MySqlValueConverters(JdbcValueConverters.DecimalMode.DOUBLE,
|
||||
TemporalPrecisionMode.CONNECT,
|
||||
JdbcValueConverters.BigIntUnsignedMode.LONG);
|
||||
parser = parserProducer.apply(converters);
|
||||
tables = new Tables();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedTinyintDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_TINYINT_TABLE (" +
|
||||
" A TINYINT UNSIGNED NULL DEFAULT 0," +
|
||||
" B TINYINT UNSIGNED NULL DEFAULT '10'," +
|
||||
" C TINYINT UNSIGNED NULL," +
|
||||
" D TINYINT UNSIGNED NOT NULL," +
|
||||
" E TINYINT UNSIGNED NOT NULL DEFAULT 0," +
|
||||
" F TINYINT UNSIGNED NOT NULL DEFAULT '0'" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_TINYINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo((short) 0);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo((short) 10);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("C").defaultValue()).isNull();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo((short) 0);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo((short) 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedSmallintDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_SMALLINT_TABLE (\n" +
|
||||
" A SMALLINT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B SMALLINT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C SMALLINT UNSIGNED NULL,\n" +
|
||||
" D SMALLINT UNSIGNED NOT NULL,\n" +
|
||||
" E SMALLINT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F SMALLINT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_SMALLINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedMediumintDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_MEDIUMINT_TABLE (\n" +
|
||||
" A MEDIUMINT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B MEDIUMINT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C MEDIUMINT UNSIGNED NULL,\n" +
|
||||
" D MEDIUMINT UNSIGNED NOT NULL,\n" +
|
||||
" E MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F MEDIUMINT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_MEDIUMINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedIntDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_INT_TABLE (\n" +
|
||||
" A INT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B INT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C INT UNSIGNED NULL,\n" +
|
||||
" D INT UNSIGNED NOT NULL,\n" +
|
||||
" E INT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F INT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_INT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0L);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10L);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0L);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedBigIntDefaultValueToLong() {
|
||||
String sql = "CREATE TABLE UNSIGNED_BIGINT_TABLE (\n" +
|
||||
" A BIGINT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B BIGINT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C BIGINT UNSIGNED NULL,\n" +
|
||||
" D BIGINT UNSIGNED NOT NULL,\n" +
|
||||
" E BIGINT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F BIGINT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_BIGINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0L);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10L);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0L);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedBigIntDefaultValueToBigDecimal() {
|
||||
final MySqlValueConverters converters = new MySqlValueConverters(JdbcValueConverters.DecimalMode.DOUBLE,
|
||||
TemporalPrecisionMode.CONNECT,
|
||||
JdbcValueConverters.BigIntUnsignedMode.PRECISE);
|
||||
final AbstractDdlParser parser = parserProducer.apply(converters);
|
||||
String sql = "CREATE TABLE UNSIGNED_BIGINT_TABLE (\n" +
|
||||
" A BIGINT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B BIGINT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C BIGINT UNSIGNED NULL,\n" +
|
||||
" D BIGINT UNSIGNED NOT NULL,\n" +
|
||||
" E BIGINT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F BIGINT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_BIGINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(BigDecimal.ZERO);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(new BigDecimal(10));
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(BigDecimal.ZERO);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseStringDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_STRING_TABLE (\n" +
|
||||
" A CHAR NULL DEFAULT 'A',\n" +
|
||||
" B CHAR NULL DEFAULT 'b',\n" +
|
||||
" C VARCHAR(10) NULL DEFAULT 'CC',\n" +
|
||||
" D NCHAR(10) NULL DEFAULT '10',\n" +
|
||||
" E NVARCHAR NULL DEFAULT '0',\n" +
|
||||
" F CHAR DEFAULT NULL,\n" +
|
||||
" G VARCHAR(10) DEFAULT NULL,\n" +
|
||||
" H NCHAR(10) DEFAULT NULL\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_STRING_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo("A");
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo("b");
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo("CC");
|
||||
assertThat(table.columnWithName("D").defaultValue()).isEqualTo("10");
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo("0");
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("G").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("H").defaultValue()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseBitDefaultValue() {
|
||||
String sql = "CREATE TABLE BIT_TABLE (\n" +
|
||||
" A BIT(1) NULL DEFAULT NULL,\n" +
|
||||
" B BIT(1) DEFAULT 0,\n" +
|
||||
" C BIT(1) DEFAULT 1,\n" +
|
||||
" D BIT(1) DEFAULT b'0',\n" +
|
||||
" E BIT(1) DEFAULT b'1',\n" +
|
||||
" F BIT(1) DEFAULT TRUE,\n" +
|
||||
" G BIT(1) DEFAULT FALSE,\n" +
|
||||
" H BIT(10) DEFAULT b'101000010',\n" +
|
||||
" I BIT(10) DEFAULT NULL,\n" +
|
||||
" J BIT(25) DEFAULT b'10110000100001111'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "BIT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("D").defaultValue()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("G").defaultValue()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("H").defaultValue()).isEqualTo(new byte[] {66, 1});
|
||||
assertThat(table.columnWithName("I").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("J").defaultValue()).isEqualTo(new byte[] {15, 97, 1, 0});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseBooleanDefaultValue() {
|
||||
String sql = "CREATE TABLE BOOLEAN_TABLE (\n" +
|
||||
" A BOOLEAN NULL DEFAULT 0,\n" +
|
||||
" B BOOLEAN NOT NULL DEFAULT '1',\n" +
|
||||
" C BOOLEAN NOT NULL DEFAULT '9',\n" +
|
||||
" D BOOLEAN NOT NULL DEFAULT TRUE,\n" +
|
||||
" E BOOLEAN DEFAULT NULL\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "BOOLEAN_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("D").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseNumberDefaultValue() {
|
||||
String sql = "CREATE TABLE NUMBER_TABLE (\n" +
|
||||
" A TINYINT NULL DEFAULT 10,\n" +
|
||||
" B SMALLINT NOT NULL DEFAULT '5',\n" +
|
||||
" C INTEGER NOT NULL DEFAULT 0,\n" +
|
||||
" D BIGINT NOT NULL DEFAULT 20,\n" +
|
||||
" E INT NULL DEFAULT NULL,\n" +
|
||||
" F FLOAT NULL DEFAULT 0,\n" +
|
||||
" G DOUBLE NOT NULL DEFAULT 1.0\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "NUMBER_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo((short) 10);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo((short) 5);
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("D").defaultValue()).isEqualTo(20L);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0d);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseRealDefaultValue() {
|
||||
String sql = "CREATE TABLE REAL_TABLE (\n" +
|
||||
" A REAL NOT NULL DEFAULT 1,\n" +
|
||||
" B REAL NULL DEFAULT NULL \n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "REAL_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(1f);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseNumericAndDecimalToDoubleDefaultValue() {
|
||||
String sql = "CREATE TABLE NUMERIC_DECIMAL_TABLE (\n" +
|
||||
" A NUMERIC NOT NULL DEFAULT 1.23,\n" +
|
||||
" B DECIMAL NOT NULL DEFAULT 2.321,\n" +
|
||||
" C NUMERIC NULL DEFAULT '12.678'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "NUMERIC_DECIMAL_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(1.23d);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(2.321d);
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(12.678d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseNumericAndDecimalToDecimalDefaultValue() {
|
||||
final MySqlValueConverters converters = new MySqlValueConverters(JdbcValueConverters.DecimalMode.PRECISE,
|
||||
TemporalPrecisionMode.CONNECT,
|
||||
JdbcValueConverters.BigIntUnsignedMode.LONG);
|
||||
final AbstractDdlParser parser = parserProducer.apply(converters);
|
||||
String sql = "CREATE TABLE NUMERIC_DECIMAL_TABLE (\n" +
|
||||
" A NUMERIC NOT NULL DEFAULT 1.23,\n" +
|
||||
" B DECIMAL NOT NULL DEFAULT 2.321,\n" +
|
||||
" C NUMERIC NULL DEFAULT '12.678'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "NUMERIC_DECIMAL_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(BigDecimal.valueOf(1.23));
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(BigDecimal.valueOf(2.321));
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(BigDecimal.valueOf(12.678));
|
||||
}
|
||||
}
|
@ -253,7 +253,7 @@ public MysqlDdlParserWithSimpleTestListener(DdlChanges changesListener) {
|
||||
}
|
||||
|
||||
public MysqlDdlParserWithSimpleTestListener(DdlChanges changesListener, boolean includeViews) {
|
||||
super(false, includeViews);
|
||||
super(false, includeViews, null);
|
||||
this.ddlChanges = changesListener;
|
||||
}
|
||||
}
|
||||
|
@ -156,14 +156,20 @@ public void shouldParseCreateTableStatementWithCollate() {
|
||||
@Test
|
||||
@FixFor("DBZ-646")
|
||||
public void shouldParseTokuDBTable() {
|
||||
String ddl = "CREATE TABLE foo ( " + System.lineSeparator()
|
||||
String ddl1 = "CREATE TABLE foo ( " + System.lineSeparator()
|
||||
+ " c1 INTEGER NOT NULL, " + System.lineSeparator()
|
||||
+ " c2 VARCHAR(22) " + System.lineSeparator()
|
||||
+ ") engine=TokuDB `compression`=tokudb_zlib;";
|
||||
parser.parse(ddl, tables);
|
||||
assertThat(tables.size()).isEqualTo(1);
|
||||
+ ") engine=TokuDB compression=tokudb_zlib;";
|
||||
String ddl2 = "CREATE TABLE bar ( " + System.lineSeparator()
|
||||
+ " c1 INTEGER NOT NULL, " + System.lineSeparator()
|
||||
+ " c2 VARCHAR(22) " + System.lineSeparator()
|
||||
+ ") engine=TokuDB compression='tokudb_zlib';";
|
||||
parser.parse(ddl1 + ddl2, tables);
|
||||
assertThat(tables.size()).isEqualTo(2);
|
||||
listener.assertNext().createTableNamed("foo").ddlStartsWith("CREATE TABLE foo (");
|
||||
listener.assertNext().createTableNamed("bar").ddlStartsWith("CREATE TABLE bar (");
|
||||
parser.parse("DROP TABLE foo", tables);
|
||||
parser.parse("DROP TABLE bar", tables);
|
||||
assertThat(tables.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@ -490,22 +496,22 @@ public void shouldParseAlterTableStatementAddConstraintUniqueKey() {
|
||||
parser.parse(ddl, tables);
|
||||
assertThat(tables.size()).isEqualTo(1);
|
||||
|
||||
ddl = "ALTER TABLE t ADD CONSTRAINT UNIQUE KEY col_key ('col1');";
|
||||
ddl = "ALTER TABLE t ADD CONSTRAINT UNIQUE KEY col_key (col1);";
|
||||
parser.parse(ddl, tables);
|
||||
|
||||
ddl = "ALTER TABLE t ADD CONSTRAINT UNIQUE KEY ('col1');";
|
||||
ddl = "ALTER TABLE t ADD CONSTRAINT UNIQUE KEY (col1);";
|
||||
parser.parse(ddl, tables);
|
||||
|
||||
ddl = "ALTER TABLE t ADD UNIQUE KEY col_key ('col1');";
|
||||
ddl = "ALTER TABLE t ADD UNIQUE KEY col_key (col1);";
|
||||
parser.parse(ddl, tables);
|
||||
|
||||
ddl = "ALTER TABLE t ADD UNIQUE KEY ('col1');";
|
||||
ddl = "ALTER TABLE t ADD UNIQUE KEY (col1);";
|
||||
parser.parse(ddl, tables);
|
||||
|
||||
ddl = "ALTER TABLE t ADD CONSTRAINT 'xx' UNIQUE KEY col_key ('col1');";
|
||||
ddl = "ALTER TABLE t ADD CONSTRAINT xx UNIQUE KEY col_key (col1);";
|
||||
parser.parse(ddl, tables);
|
||||
|
||||
ddl = "ALTER TABLE t ADD CONSTRAINT 'xx' UNIQUE KEY ('col1');";
|
||||
ddl = "ALTER TABLE t ADD CONSTRAINT xy UNIQUE KEY (col1);";
|
||||
parser.parse(ddl, tables);
|
||||
}
|
||||
|
||||
@ -819,11 +825,11 @@ public void shouldParseAndIgnoreCreateFunction() {
|
||||
@FixFor("DBZ-667")
|
||||
@Test
|
||||
public void shouldParseScientificNotationNumber() {
|
||||
String ddl = "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1E-10, PRIMARY KEY (`id`));"
|
||||
String ddl = "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1E10, PRIMARY KEY (`id`));"
|
||||
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1.3E-10, PRIMARY KEY (`id`));"
|
||||
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1.3E+10, PRIMARY KEY (`id`));"
|
||||
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1.4E+10, PRIMARY KEY (`id`));"
|
||||
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 3E10, PRIMARY KEY (`id`));"
|
||||
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1.3e10, PRIMARY KEY (`id`))";
|
||||
+ "CREATE TABLE t (id INT NOT NULL, myvalue DOUBLE DEFAULT 1.5e10, PRIMARY KEY (`id`))";
|
||||
parser.parse(ddl, tables);
|
||||
assertThat(tables.size()).isEqualTo(1);
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright Debezium Authors.
|
||||
*
|
||||
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package io.debezium.connector.mysql;
|
||||
|
||||
import io.debezium.connector.mysql.antlr.MySqlAntlrDdlParser;
|
||||
|
||||
/**
|
||||
* @author Jiri Pechanec <jpechane@redhat.com>
|
||||
*/
|
||||
public class MysqlAntlrDefaultValueTest extends AbstractMysqlDefaultValueTest {
|
||||
|
||||
{
|
||||
parserProducer = MySqlAntlrDdlParser::new;
|
||||
}
|
||||
}
|
@ -5,322 +5,20 @@
|
||||
*/
|
||||
package io.debezium.connector.mysql;
|
||||
|
||||
import io.debezium.jdbc.JdbcValueConverters;
|
||||
import io.debezium.jdbc.TemporalPrecisionMode;
|
||||
import io.debezium.relational.Table;
|
||||
import io.debezium.relational.TableId;
|
||||
import io.debezium.relational.Tables;
|
||||
import io.debezium.relational.ddl.SimpleDdlParserListener;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author laomei
|
||||
*/
|
||||
public class MysqlDefaultValueTest {
|
||||
public class MysqlDefaultValueTest extends AbstractMysqlDefaultValueTest {
|
||||
|
||||
private MySqlDdlParser parser;
|
||||
private Tables tables;
|
||||
private SimpleDdlParserListener listener;
|
||||
private MySqlValueConverters converters;
|
||||
|
||||
@Before
|
||||
public void beforeEach() {
|
||||
converters = new MySqlValueConverters(JdbcValueConverters.DecimalMode.DOUBLE,
|
||||
TemporalPrecisionMode.CONNECT,
|
||||
JdbcValueConverters.BigIntUnsignedMode.LONG);
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
tables = new Tables();
|
||||
listener = new SimpleDdlParserListener();
|
||||
parser.addListener(listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedTinyintDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_TINYINT_TABLE (" +
|
||||
" A TINYINT UNSIGNED NULL DEFAULT 0," +
|
||||
" B TINYINT UNSIGNED NULL DEFAULT '10'," +
|
||||
" C TINYINT UNSIGNED NULL," +
|
||||
" D TINYINT UNSIGNED NOT NULL," +
|
||||
" E TINYINT UNSIGNED NOT NULL DEFAULT 0," +
|
||||
" F TINYINT UNSIGNED NOT NULL DEFAULT '0'" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_TINYINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo((short) 0);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo((short) 10);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("C").defaultValue()).isNull();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo((short) 0);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo((short) 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedSmallintDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_SMALLINT_TABLE (\n" +
|
||||
" A SMALLINT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B SMALLINT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C SMALLINT UNSIGNED NULL,\n" +
|
||||
" D SMALLINT UNSIGNED NOT NULL,\n" +
|
||||
" E SMALLINT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F SMALLINT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_SMALLINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedMediumintDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_MEDIUMINT_TABLE (\n" +
|
||||
" A MEDIUMINT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B MEDIUMINT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C MEDIUMINT UNSIGNED NULL,\n" +
|
||||
" D MEDIUMINT UNSIGNED NOT NULL,\n" +
|
||||
" E MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F MEDIUMINT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_MEDIUMINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedIntDefaultValue() {
|
||||
String sql = "CREATE TABLE UNSIGNED_INT_TABLE (\n" +
|
||||
" A INT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B INT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C INT UNSIGNED NULL,\n" +
|
||||
" D INT UNSIGNED NOT NULL,\n" +
|
||||
" E INT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F INT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_INT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0L);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10L);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0L);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedBigIntDefaultValueToLong() {
|
||||
String sql = "CREATE TABLE UNSIGNED_BIGINT_TABLE (\n" +
|
||||
" A BIGINT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B BIGINT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C BIGINT UNSIGNED NULL,\n" +
|
||||
" D BIGINT UNSIGNED NOT NULL,\n" +
|
||||
" E BIGINT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F BIGINT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_BIGINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(0L);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(10L);
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(0L);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseUnsignedBigIntDefaultValueToBigDecimal() {
|
||||
converters = new MySqlValueConverters(JdbcValueConverters.DecimalMode.DOUBLE,
|
||||
TemporalPrecisionMode.CONNECT,
|
||||
JdbcValueConverters.BigIntUnsignedMode.PRECISE);
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
String sql = "CREATE TABLE UNSIGNED_BIGINT_TABLE (\n" +
|
||||
" A BIGINT UNSIGNED NULL DEFAULT 0,\n" +
|
||||
" B BIGINT UNSIGNED NULL DEFAULT '10',\n" +
|
||||
" C BIGINT UNSIGNED NULL,\n" +
|
||||
" D BIGINT UNSIGNED NOT NULL,\n" +
|
||||
" E BIGINT UNSIGNED NOT NULL DEFAULT 0,\n" +
|
||||
" F BIGINT UNSIGNED NOT NULL DEFAULT '0'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_BIGINT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(BigDecimal.ZERO);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(new BigDecimal(10));
|
||||
assertThat(table.columnWithName("C").isOptional()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").hasDefaultValue()).isTrue();
|
||||
assertThat(table.columnWithName("D").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("D").hasDefaultValue()).isFalse();
|
||||
assertThat(table.columnWithName("E").isOptional()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(BigDecimal.ZERO);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseStringDefaultValue() {
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
String sql = "CREATE TABLE UNSIGNED_STRING_TABLE (\n" +
|
||||
" A CHAR NULL DEFAULT 'A',\n" +
|
||||
" B CHAR NULL DEFAULT 'b',\n" +
|
||||
" C VARCHAR(10) NULL DEFAULT 'CC',\n" +
|
||||
" D NCHAR(10) NULL DEFAULT '10',\n" +
|
||||
" E NVARCHAR NULL DEFAULT '0',\n" +
|
||||
" F CHAR DEFAULT NULL,\n" +
|
||||
" G VARCHAR(10) DEFAULT NULL,\n" +
|
||||
" H NCHAR(10) DEFAULT NULL\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "UNSIGNED_STRING_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo("A");
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo("b");
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo("CC");
|
||||
assertThat(table.columnWithName("D").defaultValue()).isEqualTo("10");
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo("0");
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("G").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("H").defaultValue()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseBitDefaultValue() {
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
String sql = "CREATE TABLE BIT_TABLE (\n" +
|
||||
" A BIT(1) NULL DEFAULT NULL,\n" +
|
||||
" B BIT(1) DEFAULT 0,\n" +
|
||||
" C BIT(1) DEFAULT 1,\n" +
|
||||
" D BIT(1) DEFAULT b'0',\n" +
|
||||
" E BIT(1) DEFAULT b'1',\n" +
|
||||
" F BIT(1) DEFAULT TRUE,\n" +
|
||||
" G BIT(1) DEFAULT FALSE,\n" +
|
||||
" H BIT(10) DEFAULT b'101000010',\n" +
|
||||
" I BIT(10) DEFAULT NULL,\n" +
|
||||
" J BIT(25) DEFAULT b'10110000100001111'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "BIT_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("D").defaultValue()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("G").defaultValue()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("H").defaultValue()).isEqualTo(new byte[] {66, 1});
|
||||
assertThat(table.columnWithName("I").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("J").defaultValue()).isEqualTo(new byte[] {15, 97, 1, 0});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseBooleanDefaultValue() {
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
String sql = "CREATE TABLE BOOLEAN_TABLE (\n" +
|
||||
" A BOOLEAN NULL DEFAULT 0,\n" +
|
||||
" B BOOLEAN NOT NULL DEFAULT '1',\n" +
|
||||
" C BOOLEAN NOT NULL DEFAULT '9',\n" +
|
||||
" D BOOLEAN NOT NULL DEFAULT TRUE,\n" +
|
||||
" E BOOLEAN DEFAULT NULL\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "BOOLEAN_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(false);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("D").defaultValue()).isEqualTo(true);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseNumberDefaultValue() {
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
String sql = "CREATE TABLE NUMBER_TABLE (\n" +
|
||||
" A TINYINT NULL DEFAULT 10,\n" +
|
||||
" B SMALLINT NOT NULL DEFAULT '5',\n" +
|
||||
" C INTEGER NOT NULL DEFAULT 0,\n" +
|
||||
" D BIGINT NOT NULL DEFAULT 20,\n" +
|
||||
" E INT NULL DEFAULT NULL,\n" +
|
||||
" F FLOAT NULL DEFAULT 0,\n" +
|
||||
" G DOUBLE NOT NULL DEFAULT 1.0\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "NUMBER_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo((short) 10);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo((short) 5);
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(0);
|
||||
assertThat(table.columnWithName("D").defaultValue()).isEqualTo(20L);
|
||||
assertThat(table.columnWithName("E").defaultValue()).isEqualTo(null);
|
||||
assertThat(table.columnWithName("F").defaultValue()).isEqualTo(0d);
|
||||
assertThat(table.columnWithName("G").defaultValue()).isEqualTo(1.0d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseRealDefaultValue() {
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
String sql = "CREATE TABLE REAL_TABLE (\n" +
|
||||
" A REAL NOT NULL DEFAULT 1,\n" +
|
||||
" B REAL NULL DEFAULT NULL \n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "REAL_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(1f);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseNumericAndDecimalToDoubleDefaultValue() {
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
String sql = "CREATE TABLE NUMERIC_DECIMAL_TABLE (\n" +
|
||||
" A NUMERIC NOT NULL DEFAULT 1.23,\n" +
|
||||
" B DECIMAL NOT NULL DEFAULT 2.321,\n" +
|
||||
" C NUMERIC NULL DEFAULT '12.678'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "NUMERIC_DECIMAL_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(1.23d);
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(2.321d);
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(12.678d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseNumericAndDecimalToDecimalDefaultValue() {
|
||||
converters = new MySqlValueConverters(JdbcValueConverters.DecimalMode.PRECISE,
|
||||
TemporalPrecisionMode.CONNECT,
|
||||
JdbcValueConverters.BigIntUnsignedMode.LONG);
|
||||
parser = new MySqlDdlParser(false, converters);
|
||||
String sql = "CREATE TABLE NUMERIC_DECIMAL_TABLE (\n" +
|
||||
" A NUMERIC NOT NULL DEFAULT 1.23,\n" +
|
||||
" B DECIMAL NOT NULL DEFAULT 2.321,\n" +
|
||||
" C NUMERIC NULL DEFAULT '12.678'\n" +
|
||||
");";
|
||||
parser.parse(sql, tables);
|
||||
Table table = tables.forTable(new TableId(null, null, "NUMERIC_DECIMAL_TABLE"));
|
||||
assertThat(table.columnWithName("A").defaultValue()).isEqualTo(BigDecimal.valueOf(1.23));
|
||||
assertThat(table.columnWithName("B").defaultValue()).isEqualTo(BigDecimal.valueOf(2.321));
|
||||
assertThat(table.columnWithName("C").defaultValue()).isEqualTo(BigDecimal.valueOf(12.678));
|
||||
{
|
||||
parserProducer = (converters) -> {
|
||||
MySqlDdlParser parser = new MySqlDdlParser(false, converters);
|
||||
listener = new SimpleDdlParserListener();
|
||||
parser.addListener(listener);
|
||||
return parser;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -621,15 +621,16 @@ protected Object parseNumericLiteral(Marker start, boolean signed) {
|
||||
sb.append(tokens.consumeInteger());
|
||||
}
|
||||
if (tokens.canConsume('.')) {
|
||||
sb.append('.');
|
||||
sb.append(tokens.consumeInteger());
|
||||
decimal = true;
|
||||
}
|
||||
if (!tokens.canConsume('E')) {
|
||||
if (!tokens.canConsumeAnyOf("E", "e")) {
|
||||
if (decimal) return Double.parseDouble(sb.toString());
|
||||
return Integer.parseInt(sb.toString());
|
||||
}
|
||||
sb.append('E');
|
||||
if (tokens.matches("+", "-")) {
|
||||
if (tokens.matchesAnyOf("+", "-")) {
|
||||
sb.append(tokens.consumeAnyOf("+", "-"));
|
||||
}
|
||||
sb.append(tokens.consumeInteger());
|
||||
|
@ -61,6 +61,10 @@ protected static LocalDate toLocalDate(Object obj) {
|
||||
// Assume the value is the epoch day number
|
||||
return LocalDate.ofEpochDay((Long)obj);
|
||||
}
|
||||
if ( obj instanceof Integer) {
|
||||
// Assume the value is the epoch day number
|
||||
return LocalDate.ofEpochDay((Integer)obj);
|
||||
}
|
||||
throw new IllegalArgumentException("Unable to convert to LocalDate from unexpected value '" + obj + "' of type " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,9 @@ public static Schema schema() {
|
||||
* @throws IllegalArgumentException if the value is not an instance of the acceptable types
|
||||
*/
|
||||
public static long toEpochMillis(Object value, TemporalAdjuster adjuster) {
|
||||
if (value instanceof Long) {
|
||||
return (Long)value;
|
||||
}
|
||||
LocalDateTime dateTime = Conversions.toLocalDateTime(value);
|
||||
if (adjuster != null) {
|
||||
dateTime = dateTime.with(adjuster);
|
||||
|
@ -78,6 +78,9 @@ public static Schema schema() {
|
||||
* @throws IllegalArgumentException if the value is not an instance of the acceptable types
|
||||
*/
|
||||
public static String toIsoString(Object value, ZoneId defaultZone, TemporalAdjuster adjuster) {
|
||||
if (value instanceof String) {
|
||||
return (String)value;
|
||||
}
|
||||
if (value instanceof OffsetDateTime) {
|
||||
return toIsoString((OffsetDateTime) value, adjuster);
|
||||
}
|
||||
|
@ -705,6 +705,7 @@ MYISAM: 'MYISAM';
|
||||
NDB: 'NDB';
|
||||
NDBCLUSTER: 'NDBCLUSTER';
|
||||
PERFORMANCE_SCHEMA: 'PERFORMANCE_SCHEMA';
|
||||
TOKUDB: 'TOKUDB';
|
||||
|
||||
|
||||
// Transaction Levels
|
||||
@ -1162,7 +1163,7 @@ fragment CHARSET_NAME: ARMSCII8 | ASCII | BIG5 | BINARY | CP1250
|
||||
| UCS2 | UJIS | UTF16 | UTF16LE | UTF32
|
||||
| UTF8 | UTF8MB4;
|
||||
|
||||
fragment EXPONENT_NUM_PART: 'E' '-'? DEC_DIGIT+;
|
||||
fragment EXPONENT_NUM_PART: 'E' [\-+]? DEC_DIGIT+;
|
||||
fragment ID_LITERAL: [A-Z_$0-9]*?[A-Z_$]+?[A-Z_$0-9]*;
|
||||
fragment DQUOTA_STRING: '"' ( '\\'. | '""' | ~('"'| '\\') )* '"';
|
||||
fragment SQUOTA_STRING: '\'' ('\\'. | '\'\'' | ~('\'' | '\\'))* '\'';
|
||||
|
@ -409,7 +409,7 @@ tableOption
|
||||
| (CHECKSUM | PAGE_CHECKSUM) '='? boolValue=('0' | '1') #tableOptionChecksum
|
||||
| DEFAULT? COLLATE '='? collationName #tableOptionCollate
|
||||
| COMMENT '='? STRING_LITERAL #tableOptionComment
|
||||
| COMPRESSION '='? STRING_LITERAL #tableOptionCompression
|
||||
| COMPRESSION '='? (STRING_LITERAL | ID) #tableOptionCompression
|
||||
| CONNECTION '='? STRING_LITERAL #tableOptionConnection
|
||||
| DATA DIRECTORY '='? STRING_LITERAL #tableOptionDataDirectory
|
||||
| DELAY_KEY_WRITE '='? boolValue=('0' | '1') #tableOptionDelay
|
||||
@ -1877,6 +1877,7 @@ collationName
|
||||
engineName
|
||||
: ARCHIVE | BLACKHOLE | CSV | FEDERATED | INNODB | MEMORY
|
||||
| MRG_MYISAM | MYISAM | NDB | NDBCLUSTER | PERFORMANCE_SCHEMA
|
||||
| TOKUDB
|
||||
;
|
||||
|
||||
uuidSet
|
||||
|
@ -296,7 +296,7 @@ public void taskStarted() {
|
||||
engine.run();
|
||||
});
|
||||
try {
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
if (!latch.await(1000, TimeUnit.SECONDS)) {
|
||||
// maybe it takes more time to start up, so just log a warning and continue
|
||||
logger.warn("The connector did not finish starting its task(s) or complete in the expected amount of time");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user