Skip to content

Commit 0751900

Browse files
committed
Make first unique key as primary key if possible. Fix 0000 year problem.
1 parent 6eee34a commit 0751900

9 files changed

Lines changed: 95 additions & 10 deletions

File tree

innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/TableReaderImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public TableReaderImpl(String ibdFilePath, TableDef tableDef, KeyComparator keyC
7575
this.ibdFilePath = ibdFilePath;
7676
this.tableDef = tableDef;
7777
this.keyComparator = keyComparator;
78-
this.tableDef.validate();
78+
this.tableDef.prepare();
7979
}
8080

8181
@Override

innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/column/ColumnFactory.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,11 @@ public Class<?> typeClass() {
595595

596596
@Override
597597
public Short readFrom(SliceInput input, Column column) {
598-
return (short) (input.readUnsignedByte() + 1900);
598+
int b = input.readUnsignedByte();
599+
if (b == 0) {
600+
return (short) 0;
601+
}
602+
return (short) (b + 1900);
599603
}
600604

601605
@Override

innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/schema/TableDef.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Map;
2424
import java.util.Optional;
2525
import java.util.function.Function;
26+
import java.util.function.Predicate;
2627
import java.util.stream.Collectors;
2728

2829
import lombok.Data;
@@ -37,6 +38,8 @@
3738
import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.FOREIGN_KEY;
3839
import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.FULLTEXT_KEY;
3940
import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.PRIMARY_KEY;
41+
import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.UNIQUE_INDEX;
42+
import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.UNIQUE_KEY;
4043
import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.isValidSk;
4144
import static com.alibaba.innodb.java.reader.util.Utils.sanitize;
4245
import static com.google.common.base.Preconditions.checkArgument;
@@ -125,8 +128,9 @@ public TableDef() {
125128
this.variableLengthColumnList = new ArrayList<>();
126129
}
127130

128-
public void validate() {
131+
public void prepare() {
129132
checkState(CollectionUtils.isNotEmpty(columnList), "No column is specified");
133+
makeFirstUniqueKeyAsPrimaryKeyIfPossible();
130134
}
131135

132136
public boolean containsVariableLengthColumn() {
@@ -491,6 +495,22 @@ public static Column createRowIdColumn() {
491495
return new Column().setName(COLUMN_ROW_ID).setType(ColumnType.ROW_ID).setNullable(false);
492496
}
493497

498+
/**
499+
* If no primary key provided, make first unique key as primary key.
500+
*/
501+
private void makeFirstUniqueKeyAsPrimaryKeyIfPossible() {
502+
if (primaryKeyMeta == null) {
503+
Predicate<KeyMeta> predicate = k -> k.getType() == UNIQUE_KEY || k.getType() == UNIQUE_INDEX;
504+
if (secondaryKeyMetaList != null) {
505+
if (secondaryKeyMetaList.stream().anyMatch(predicate)) {
506+
KeyMeta pkMeta = secondaryKeyMetaList.stream().filter(predicate).findFirst().get();
507+
setPrimaryKeyColumns(pkMeta.getKeyColumnNames());
508+
secondaryKeyMetaList.remove(pkMeta);
509+
}
510+
}
511+
}
512+
}
513+
494514
@Data
495515
public class Field {
496516
private int ordinal;

innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/column/ColumnYearDateTableReaderTest.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,17 @@ public void testYearDateColumnMysql80() {
5555
public Consumer<List<GenericRecord>> expected() {
5656
return recordList -> {
5757

58-
assertThat(recordList.size(), is(6));
58+
assertThat(recordList.size(), is(8));
5959

6060
List<Object[]> expected = Arrays.asList(
61-
new Object[]{1, (short) 1901, "1900-01-01"},
62-
new Object[]{2, (short) 1999, "1901-12-31"},
63-
new Object[]{3, (short) 1969, "1969-10-02"},
64-
new Object[]{4, (short) 2020, "2020-12-31"},
65-
new Object[]{5, (short) 2100, "0069-01-10"},
66-
new Object[]{6, (short) 2155, "0001-01-01"}
61+
new Object[]{1, (short) 0, "2100-11-11"},
62+
new Object[]{2, (short) 2001, "2155-01-01"},
63+
new Object[]{3, (short) 1901, "1900-01-01"},
64+
new Object[]{4, (short) 1999, "1901-12-31"},
65+
new Object[]{5, (short) 1969, "1969-10-02"},
66+
new Object[]{6, (short) 2020, "2020-12-31"},
67+
new Object[]{7, (short) 2100, "0069-01-10"},
68+
new Object[]{8, (short) 2155, "0001-01-01"}
6769
);
6870

6971
for (int i = 0; i < recordList.size(); i++) {

innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/schema/TableDefUtilTest.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,4 +515,61 @@ public void testTableFullyQualifiedName() {
515515
assertThat(tableDef.getFullyQualifiedName(), is("test.tb02"));
516516
}
517517

518+
@Test
519+
public void testMakeUniqueKeyAsPrimaryKey() {
520+
String sql = "CREATE TABLE `type_newdecimaltest59` (\n"
521+
+ " `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,\n"
522+
+ " `d` decimal(65,30) DEFAULT NULL,\n"
523+
+ " UNIQUE KEY `id` (`id`)\n"
524+
+ ") ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8";
525+
TableDef tableDef = TableDefUtil.covertToTableDef(sql);
526+
// have to prepare
527+
tableDef.prepare();
528+
System.out.println(tableDef);
529+
530+
assertThat(tableDef.getName(), is("type_newdecimaltest59"));
531+
assertThat(tableDef.getFullyQualifiedName(), is("type_newdecimaltest59"));
532+
assertThat(tableDef.getDefaultCharset(), is("utf8"));
533+
assertThat(tableDef.getDefaultJavaCharset(), is("UTF-8"));
534+
assertThat(tableDef.getCollation(), is("utf8_general_ci"));
535+
assertThat(tableDef.isCollationCaseSensitive(), is(false));
536+
537+
List<Column> columnList = tableDef.getColumnList();
538+
assertThat(columnList.size(), is(2));
539+
assertThat(tableDef.getColumnNum(), is(2));
540+
541+
assertThat(columnList.get(0).getOrdinal(), is(0));
542+
assertThat(columnList.get(0).getName(), is("id"));
543+
assertThat(columnList.get(0).getType(), is(ColumnType.UNSIGNED_BIGINT));
544+
assertThat(columnList.get(0).getFullType(), is("bigint(20) UNSIGNED"));
545+
assertThat(columnList.get(0).getLength(), is(20));
546+
assertThat(columnList.get(0).getPrecision(), is(0));
547+
assertThat(columnList.get(0).getScale(), is(0));
548+
assertThat(columnList.get(0).isPrimaryKey(), is(false));
549+
assertThat(columnList.get(0).isNullable(), is(false));
550+
551+
assertThat(columnList.get(1).getOrdinal(), is(1));
552+
assertThat(columnList.get(1).getName(), is("d"));
553+
assertThat(columnList.get(1).getType(), is(ColumnType.DECIMAL));
554+
assertThat(columnList.get(1).getFullType(), is("decimal(65,30)"));
555+
assertThat(columnList.get(1).getLength(), is(0));
556+
assertThat(columnList.get(1).getPrecision(), is(65));
557+
assertThat(columnList.get(1).getScale(), is(30));
558+
assertThat(columnList.get(1).isPrimaryKey(), is(false));
559+
assertThat(columnList.get(1).isNullable(), is(true));
560+
561+
assertThat(tableDef.getPrimaryKeyColumns(), is(ImmutableList.of(columnList.get(0))));
562+
assertThat(tableDef.getPrimaryKeyColumnNum(), is(1));
563+
assertThat(tableDef.getPrimaryKeyColumnNames(), is(ImmutableList.of("id")));
564+
assertThat(tableDef.getPrimaryKeyVarLenColumns(), is(ImmutableList.of()));
565+
assertThat(tableDef.getPrimaryKeyVarLenColumnNames(), is(ImmutableList.of()));
566+
assertThat(tableDef.isColumnPrimaryKey(columnList.get(0)), is(true));
567+
for (int i = 1; i < 10; i++) {
568+
assertThat(tableDef.isColumnPrimaryKey(columnList.get(1)), is(false));
569+
}
570+
571+
assertThat(tableDef.getSecondaryKeyMetaList().size(), is(0));
572+
assertThat(tableDef.getSecondaryKeyMetaMap().size(), is(0));
573+
}
574+
518575
}
Binary file not shown.

innodb-java-reader/src/test/resources/testsuite/mysql56/column/time/tb16.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ CREATE TABLE `tb16`
66
PRIMARY KEY (`id`))
77
ENGINE=InnoDB;
88

9+
insert into tb16 values(null, 0, '2100-11-11');
10+
insert into tb16 values(null, 1, '2155-01-01');
911
insert into tb16 values(null, 1901, '1900-01-01');
1012
insert into tb16 values(null, 1999, '1901-12-31');
1113
insert into tb16 values(null, 1969, '1969-10-02');
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)