DBZ-6185 Zerofill property failed for different int types

This commit is contained in:
harveyyue 2023-03-18 11:28:20 +08:00 committed by Jiri Pechanec
parent 1db806d3d1
commit c9c1ce8a2f
3 changed files with 40 additions and 12 deletions

View File

@ -251,7 +251,7 @@ public void shouldProcessLargeColumn() {
} }
@Test @Test
@FixFor("DBZ-4497") @FixFor({ "DBZ-4497", "DBZ-6185" })
public void shouldProcessMultipleSignedUnsignedForTable() { public void shouldProcessMultipleSignedUnsignedForTable() {
String ddl = "create table if not exists tbl_signed_unsigned(\n" String ddl = "create table if not exists tbl_signed_unsigned(\n"
+ "`id` bigint(20) ZEROFILL signed UNSIGNED signed ZEROFILL unsigned ZEROFILL NOT NULL AUTO_INCREMENT COMMENT 'ID',\n" + "`id` bigint(20) ZEROFILL signed UNSIGNED signed ZEROFILL unsigned ZEROFILL NOT NULL AUTO_INCREMENT COMMENT 'ID',\n"
@ -259,6 +259,8 @@ public void shouldProcessMultipleSignedUnsignedForTable() {
+ "c2 decimal(10, 2) SIGNED UNSIGNED ZEROFILL,\n" + "c2 decimal(10, 2) SIGNED UNSIGNED ZEROFILL,\n"
+ "c3 float SIGNED ZEROFILL,\n" + "c3 float SIGNED ZEROFILL,\n"
+ "c4 double precision(18, 4) UNSIGNED SIGNED ZEROFILL,\n" + "c4 double precision(18, 4) UNSIGNED SIGNED ZEROFILL,\n"
+ "c5 smallint zerofill null,\n"
+ "c6 tinyint unsigned zerofill null,\n"
+ "PRIMARY KEY (`id`)\n" + "PRIMARY KEY (`id`)\n"
+ ")"; + ")";
parser.parse(ddl, tables); parser.parse(ddl, tables);
@ -275,12 +277,15 @@ public void shouldProcessMultipleSignedUnsignedForTable() {
assertThat(c2.length()).isEqualTo(10); assertThat(c2.length()).isEqualTo(10);
assertThat(c2.scale().get()).isEqualTo(2); assertThat(c2.scale().get()).isEqualTo(2);
assertThat(table.columnWithName("c3").typeName()).isEqualTo("FLOAT SIGNED ZEROFILL"); assertThat(table.columnWithName("c3").typeName()).isEqualTo("FLOAT UNSIGNED ZEROFILL");
Column c4 = table.columnWithName("c4"); Column c4 = table.columnWithName("c4");
assertThat(c4.typeName()).isEqualTo("DOUBLE PRECISION UNSIGNED ZEROFILL"); assertThat(c4.typeName()).isEqualTo("DOUBLE PRECISION UNSIGNED ZEROFILL");
assertThat(c4.length()).isEqualTo(18); assertThat(c4.length()).isEqualTo(18);
assertThat(c4.scale().get()).isEqualTo(4); assertThat(c4.scale().get()).isEqualTo(4);
assertThat(table.columnWithName("c5").typeName()).isEqualTo("SMALLINT UNSIGNED ZEROFILL");
assertThat(table.columnWithName("c6").typeName()).isEqualTo("TINYINT UNSIGNED ZEROFILL");
} }
@Test @Test

View File

@ -22,7 +22,8 @@ public class DataTypeBuilder {
private int scale = -1; private int scale = -1;
private int arrayDimsLength = 0; private int arrayDimsLength = 0;
private final int[] arrayDims = new int[40]; private final int[] arrayDims = new int[40];
private static final Pattern SIGNED_UNSIGNED_PATTERN = Pattern.compile("(.*)SIGNED UNSIGNED(.*)", Pattern.CASE_INSENSITIVE); private static final Pattern SIGNED_UNSIGNED_ZEROFILL_PATTERN = Pattern
.compile("(.*)\\s+(SIGNED UNSIGNED ZEROFILL|SIGNED UNSIGNED|SIGNED ZEROFILL)", Pattern.CASE_INSENSITIVE);
public void addToName(String str) { public void addToName(String str) {
if (length == -1) { if (length == -1) {
@ -105,19 +106,41 @@ else if (parameters != null) {
name.append(' '); name.append(' ');
name.append(suffix); name.append(suffix);
} }
return new DataType(cleanSignedUnsigned(expression), cleanSignedUnsigned(name), jdbcType, length, scale, arrayDims, arrayDimsLength); return new DataType(
adjustSignedUnsignedZerofill(expression),
adjustSignedUnsignedZerofill(name),
jdbcType,
length,
scale,
arrayDims,
arrayDimsLength);
} }
/** /**
* Replace "signed unsigned" to "unsigned" when ddl statements contain multiple signed/unsigned keywords * This method will adjust the suffix names of numeric data type.
* In connector streaming phase, the ddl parser maybe meet the invalid definition of suffix names with numeric data type,
* will adjust to appropriate values.
* e.g. replace "SIGNED UNSIGNED ZEROFILL" or "SIGNED ZEROFILL" to "UNSIGNED ZEROFILL", "SIGNED UNSIGNED" to "UNSIGNED"
* and adjust to "UNSIGNED ZEROFILL" if "zerofill" appears alone.
*/ */
private String cleanSignedUnsigned(StringBuilder origin) { private String adjustSignedUnsignedZerofill(StringBuilder origin) {
Matcher matcher = SIGNED_UNSIGNED_PATTERN.matcher(origin.toString()); Matcher matcher = SIGNED_UNSIGNED_ZEROFILL_PATTERN.matcher(origin.toString());
if (matcher.matches()) { if (matcher.matches()) {
return matcher.replaceFirst("$1UNSIGNED$2"); String suffix = matcher.group(2).toUpperCase();
switch (suffix) {
case "SIGNED UNSIGNED ZEROFILL":
case "SIGNED ZEROFILL":
return matcher.replaceFirst("$1 UNSIGNED ZEROFILL");
case "SIGNED UNSIGNED":
return matcher.replaceFirst("$1 UNSIGNED");
default:
return origin.toString();
}
} }
else { if (origin.toString().toUpperCase().contains("ZEROFILL")
return origin.toString(); && !origin.toString().toUpperCase().contains("UNSIGNED")) {
return origin.toString().toUpperCase().replaceFirst("ZEROFILL", "UNSIGNED ZEROFILL");
} }
return origin.toString();
} }
} }

View File

@ -48,13 +48,13 @@ public class ZonedTimestamp {
/** /**
* Returns a {@link DateTimeFormatter} that ensures that exactly fractionalWidth number of digits are present * Returns a {@link DateTimeFormatter} that ensures that exactly fractionalWidth number of digits are present
* in the nanosecond part of the datetime. If fractionWidth is null, then * in the nanosecond part of the datetime. If fractionWidth is null, then
* {@link DateTimeFormatter.ISO_OFFSET_DATE_TIME} formatter is used, which can have anywhere from 0-9 digits in the * {@link DateTimeFormatter#ISO_OFFSET_DATE_TIME} formatter is used, which can have anywhere from 0-9 digits in the
* nanosecond part. * nanosecond part.
* *
* @param fractionalWidth the optional component that specifies the exact number of digits to be present in a zoneddatetime * @param fractionalWidth the optional component that specifies the exact number of digits to be present in a zoneddatetime
* formatted string. * formatted string.
* @return {@link DateTimeFormatter} containing exactly fractionalWidth number of digits in nanosecond part of the * @return {@link DateTimeFormatter} containing exactly fractionalWidth number of digits in nanosecond part of the
* datetime. If null, {@link DateTimeFormatter.ISO_OFFSET_DATE_TIME} formatter is used, which can have anywhere * datetime. If null, {@link DateTimeFormatter#ISO_OFFSET_DATE_TIME} formatter is used, which can have anywhere
* from 0-9 digits in the nanosecond part. * from 0-9 digits in the nanosecond part.
*/ */
private static DateTimeFormatter getDateTimeFormatter(Integer fractionalWidth) { private static DateTimeFormatter getDateTimeFormatter(Integer fractionalWidth) {