From 07519004c54e21d63c3a7187cfaec5038531c81d Mon Sep 17 00:00:00 2001 From: xu Date: Thu, 21 May 2020 19:18:25 +0800 Subject: [PATCH] Make first unique key as primary key if possible. Fix 0000 year problem. --- .../innodb/java/reader/TableReaderImpl.java | 2 +- .../java/reader/column/ColumnFactory.java | 6 +- .../innodb/java/reader/schema/TableDef.java | 22 ++++++- .../column/ColumnYearDateTableReaderTest.java | 16 ++--- .../java/reader/schema/TableDefUtilTest.java | 57 ++++++++++++++++++ .../testsuite/mysql56/column/time/tb16.ibd | Bin 98304 -> 98304 bytes .../testsuite/mysql56/column/time/tb16.sql | 2 + .../testsuite/mysql57/column/time/tb16.ibd | Bin 98304 -> 98304 bytes .../testsuite/mysql80/column/time/tb16.ibd | Bin 114688 -> 114688 bytes 9 files changed, 95 insertions(+), 10 deletions(-) diff --git a/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/TableReaderImpl.java b/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/TableReaderImpl.java index cfacd84..3a2fd32 100644 --- a/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/TableReaderImpl.java +++ b/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/TableReaderImpl.java @@ -75,7 +75,7 @@ public TableReaderImpl(String ibdFilePath, TableDef tableDef, KeyComparator keyC this.ibdFilePath = ibdFilePath; this.tableDef = tableDef; this.keyComparator = keyComparator; - this.tableDef.validate(); + this.tableDef.prepare(); } @Override diff --git a/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/column/ColumnFactory.java b/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/column/ColumnFactory.java index 21a20fc..c0035d5 100644 --- a/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/column/ColumnFactory.java +++ b/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/column/ColumnFactory.java @@ -595,7 +595,11 @@ public Class typeClass() { @Override public Short readFrom(SliceInput input, Column column) { - return (short) (input.readUnsignedByte() + 1900); + int b = input.readUnsignedByte(); + if (b == 0) { + return (short) 0; + } + return (short) (b + 1900); } @Override diff --git a/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/schema/TableDef.java b/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/schema/TableDef.java index fcc3552..9c03bb4 100644 --- a/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/schema/TableDef.java +++ b/innodb-java-reader/src/main/java/com/alibaba/innodb/java/reader/schema/TableDef.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import lombok.Data; @@ -37,6 +38,8 @@ import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.FOREIGN_KEY; import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.FULLTEXT_KEY; import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.PRIMARY_KEY; +import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.UNIQUE_INDEX; +import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.UNIQUE_KEY; import static com.alibaba.innodb.java.reader.schema.KeyMeta.Type.isValidSk; import static com.alibaba.innodb.java.reader.util.Utils.sanitize; import static com.google.common.base.Preconditions.checkArgument; @@ -125,8 +128,9 @@ public TableDef() { this.variableLengthColumnList = new ArrayList<>(); } - public void validate() { + public void prepare() { checkState(CollectionUtils.isNotEmpty(columnList), "No column is specified"); + makeFirstUniqueKeyAsPrimaryKeyIfPossible(); } public boolean containsVariableLengthColumn() { @@ -491,6 +495,22 @@ public static Column createRowIdColumn() { return new Column().setName(COLUMN_ROW_ID).setType(ColumnType.ROW_ID).setNullable(false); } + /** + * If no primary key provided, make first unique key as primary key. + */ + private void makeFirstUniqueKeyAsPrimaryKeyIfPossible() { + if (primaryKeyMeta == null) { + Predicate predicate = k -> k.getType() == UNIQUE_KEY || k.getType() == UNIQUE_INDEX; + if (secondaryKeyMetaList != null) { + if (secondaryKeyMetaList.stream().anyMatch(predicate)) { + KeyMeta pkMeta = secondaryKeyMetaList.stream().filter(predicate).findFirst().get(); + setPrimaryKeyColumns(pkMeta.getKeyColumnNames()); + secondaryKeyMetaList.remove(pkMeta); + } + } + } + } + @Data public class Field { private int ordinal; diff --git a/innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/column/ColumnYearDateTableReaderTest.java b/innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/column/ColumnYearDateTableReaderTest.java index 8f2c03c..d2f4524 100644 --- a/innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/column/ColumnYearDateTableReaderTest.java +++ b/innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/column/ColumnYearDateTableReaderTest.java @@ -55,15 +55,17 @@ public void testYearDateColumnMysql80() { public Consumer> expected() { return recordList -> { - assertThat(recordList.size(), is(6)); + assertThat(recordList.size(), is(8)); List expected = Arrays.asList( - new Object[]{1, (short) 1901, "1900-01-01"}, - new Object[]{2, (short) 1999, "1901-12-31"}, - new Object[]{3, (short) 1969, "1969-10-02"}, - new Object[]{4, (short) 2020, "2020-12-31"}, - new Object[]{5, (short) 2100, "0069-01-10"}, - new Object[]{6, (short) 2155, "0001-01-01"} + new Object[]{1, (short) 0, "2100-11-11"}, + new Object[]{2, (short) 2001, "2155-01-01"}, + new Object[]{3, (short) 1901, "1900-01-01"}, + new Object[]{4, (short) 1999, "1901-12-31"}, + new Object[]{5, (short) 1969, "1969-10-02"}, + new Object[]{6, (short) 2020, "2020-12-31"}, + new Object[]{7, (short) 2100, "0069-01-10"}, + new Object[]{8, (short) 2155, "0001-01-01"} ); for (int i = 0; i < recordList.size(); i++) { diff --git a/innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/schema/TableDefUtilTest.java b/innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/schema/TableDefUtilTest.java index 7422641..15b3ff0 100644 --- a/innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/schema/TableDefUtilTest.java +++ b/innodb-java-reader/src/test/java/com/alibaba/innodb/java/reader/schema/TableDefUtilTest.java @@ -515,4 +515,61 @@ public void testTableFullyQualifiedName() { assertThat(tableDef.getFullyQualifiedName(), is("test.tb02")); } + @Test + public void testMakeUniqueKeyAsPrimaryKey() { + String sql = "CREATE TABLE `type_newdecimaltest59` (\n" + + " `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,\n" + + " `d` decimal(65,30) DEFAULT NULL,\n" + + " UNIQUE KEY `id` (`id`)\n" + + ") ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8"; + TableDef tableDef = TableDefUtil.covertToTableDef(sql); + // have to prepare + tableDef.prepare(); + System.out.println(tableDef); + + assertThat(tableDef.getName(), is("type_newdecimaltest59")); + assertThat(tableDef.getFullyQualifiedName(), is("type_newdecimaltest59")); + assertThat(tableDef.getDefaultCharset(), is("utf8")); + assertThat(tableDef.getDefaultJavaCharset(), is("UTF-8")); + assertThat(tableDef.getCollation(), is("utf8_general_ci")); + assertThat(tableDef.isCollationCaseSensitive(), is(false)); + + List columnList = tableDef.getColumnList(); + assertThat(columnList.size(), is(2)); + assertThat(tableDef.getColumnNum(), is(2)); + + assertThat(columnList.get(0).getOrdinal(), is(0)); + assertThat(columnList.get(0).getName(), is("id")); + assertThat(columnList.get(0).getType(), is(ColumnType.UNSIGNED_BIGINT)); + assertThat(columnList.get(0).getFullType(), is("bigint(20) UNSIGNED")); + assertThat(columnList.get(0).getLength(), is(20)); + assertThat(columnList.get(0).getPrecision(), is(0)); + assertThat(columnList.get(0).getScale(), is(0)); + assertThat(columnList.get(0).isPrimaryKey(), is(false)); + assertThat(columnList.get(0).isNullable(), is(false)); + + assertThat(columnList.get(1).getOrdinal(), is(1)); + assertThat(columnList.get(1).getName(), is("d")); + assertThat(columnList.get(1).getType(), is(ColumnType.DECIMAL)); + assertThat(columnList.get(1).getFullType(), is("decimal(65,30)")); + assertThat(columnList.get(1).getLength(), is(0)); + assertThat(columnList.get(1).getPrecision(), is(65)); + assertThat(columnList.get(1).getScale(), is(30)); + assertThat(columnList.get(1).isPrimaryKey(), is(false)); + assertThat(columnList.get(1).isNullable(), is(true)); + + assertThat(tableDef.getPrimaryKeyColumns(), is(ImmutableList.of(columnList.get(0)))); + assertThat(tableDef.getPrimaryKeyColumnNum(), is(1)); + assertThat(tableDef.getPrimaryKeyColumnNames(), is(ImmutableList.of("id"))); + assertThat(tableDef.getPrimaryKeyVarLenColumns(), is(ImmutableList.of())); + assertThat(tableDef.getPrimaryKeyVarLenColumnNames(), is(ImmutableList.of())); + assertThat(tableDef.isColumnPrimaryKey(columnList.get(0)), is(true)); + for (int i = 1; i < 10; i++) { + assertThat(tableDef.isColumnPrimaryKey(columnList.get(1)), is(false)); + } + + assertThat(tableDef.getSecondaryKeyMetaList().size(), is(0)); + assertThat(tableDef.getSecondaryKeyMetaMap().size(), is(0)); + } + } diff --git a/innodb-java-reader/src/test/resources/testsuite/mysql56/column/time/tb16.ibd b/innodb-java-reader/src/test/resources/testsuite/mysql56/column/time/tb16.ibd index 3c4c3c7e993f4c7a42279c32bed261c3a6e3e67a..de1f744f47ed04d9bc8a654195899fa9224301ca 100644 GIT binary patch delta 513 zcmZo@U~6b#)4FMRH;Mrj@YVQ7v@viX1bO)w7P0mEsAWL4$=w?Tmhija*LG=O*^ FBLG1}cSQgI delta 464 zcmZo@U~6b#)AIVnFo^*b@YUFV@MYjY2=aVmVBq<-QR|$&o^|`z4oeqh z4}s(?Q-9q6$}<0l0w5cx=a-G^eq=oiOpGE85GVf!n$OC>hLDA@#2$b=0c0~Ve1fx# z7=c`=%)GSB+|pbIb_Q++hT_tKqSV~d$>j(5>L1=QA)UfMtNb0LrK=2g-b96macNc4A=A0L!p|WmH!HL#&ojprZdI zP>%sv1{hvIJ!&g~GIfjsCmOo67#J-67Xs~JV-NsIsjmV`)iVnGZ(vf~c<`YecL784 UuG zW?)4UIlA$nx&6cov-Lo#L9!gj%D8~?Oh{^gx`383BZ(Z{tk!VJz8<6&Bp1f~bsJEY z`9BnZRI;6C?Q`9atcQV_(W3!mHUpzE(0q0j=R*|!0a753Ffn|Bvy2#lT&c{ww9MSn zT%g;z85oL73yM;6ODC5f;H!T>_Y}~;U`7Fk37Odp3=#}d4G`BezMpp*C=O#$%#!m!nFvOKsV0u}uyftnn^QtV(&%P#?Cq8SBFG<0b(FnIj8 qZD0Uf(8&TWCQ@^LwXAU delta 464 zcmZo@U~6b#(+X&g6lFjIY-jkcFmNCVZUC}3Y}7huuLn{NlAeB*!2>ABh@^;t?F?fw z11plqhK&c!?I&KCtp`#Kl8wLlg9|9ngro+j3uqZLlE{Y5Y7Lj{>p^Nka!gjq+CW+6 z|4;x@$#zDj(se(w9tI{xkp_s9{{ziuWne>+g)pB3DUe5)7(T&SMvOqNRAydUW^QRN z13LpZ14D6XK~ZXM>E!YQeD&|bo&f!r!zjSmcSDhZL4rZ50pfbbci~TgGP#Tb$$huy zGcYKCWk9}Qd>8WqNX}#waP3caVqnk!%dmiDVqXGfW-$s>^q&OkF#yYe!i(`;+$$hi z$S824p-YQ_!Qy`*&>l7h0gzPuYam&~DDc05Npa)Bhj!cr49TD{0fhl5d^cXu0OEy= E02RGx5dZ)H diff --git a/innodb-java-reader/src/test/resources/testsuite/mysql80/column/time/tb16.ibd b/innodb-java-reader/src/test/resources/testsuite/mysql80/column/time/tb16.ibd index bbfcfc3b15cde950a967bdb1205070bc8283e636..768d09a1c677dab262ce143cb6102cc762e2919a 100644 GIT binary patch delta 1959 zcmY*a2~<;88onedlBX^|2gl!|NFo1JNMoD&iQ_UKv5u2 zG|ia8EdVqiS}vN=5;J4b4wTSpEm+9PsxobNHb?0wjNRQ`gf!*!brxnu*8||!-{g{i zGfb+UrjyN4Itp(OFK9pj%m&iu-LM-vtQsRhmotoV(XCWgUJfECR<;%>6EovJNpIY! z0T_IW0Ec#)|vu zvDd)}PSJYdZKrG4ZLqSZs8Cn)9!WFPckmb2d8Y)?Za<=$daGq-^V4ze{;7io%0)i? zj)d!VX<62h$@Tsf=Z*Ki^xv4gg3N$Uhq3=TBW`oEozw3S>f`gUv36^m&7{%>ggB1V1;w@MRzgznf9p zmZrZymp8U)Ub2g#@m8($>Jx=Gb>2QB1bd6KUxxC?&x}7PnsvfrPdeVC_Cotl-2AUk zd_Pg*Q+t_SeuLdV7^&VM@hTEK*-&f5?>!UDD^?YKfO?hN)nXL06c4hhzG=a+20%J=5$`DO{D z-;XV)FJ}sLa4LEGt}HSR*lEV(l3f3h*LA=wCIUftmc*qcJ#i?#QQ>+l*BYEV?w zd<|{4&D5rt_0$@DXTbFw+>X7iNWiO=Q4$9&hYs>MF%NDQ(7yMBXa#MrX58BUoYmbY zyT5wUwzKDW#X_rC{KpS8C)(>pUUl8K_E~PJWkY$F>2#X7&qS?0^=96@G^zYtgAV&K zl#rpIQT%EEo-1LhO?1-Il`7*8C>TCE`y-{l+Jgvn&mLOo0*k|V!aYXrOt8h#O9uaW zcj~lRwD?L$X?$c$lF2q|nfsBU!w)~TS!FwpwnS?#^nA=n?7TR;xNwM3ID>WZYC;g#++5-@ z6hrt!2y6QlH|CT@m}W98wW`LvKIx1{gemro_&+O%{)%elmfWeu5ymB#)E$b$!VV&?X!{+37-~JT%VnD)rA6h+q??sJL%^uJ4 z&9@rOyC3S{beg%w{ylXb3vOR^+W@I~{_Ei1F^=Nixf@|a*VUd-d!AcQ57)k?mQhqrC-K->Vg!DtbSKH5yb zhnmD%umBeF6sVwYkQHLWivKra@~ delta 1914 zcmYjS3piA17(QnhY*QMyFs;ihQ@PAgXi;J{V`ys2q_8M8DvHGzW-{zK#pE&~A||7Y zN9n3XnaXv|irjTUqMKwTO>Kx&v*!%<@jcJ^{_lL>`=0+l-~T-C2g9l`tZF{(v8o+F z4YbcfJsM&f*2My9Xf$UGWM!0^w>wi%I9hJwMqEdd3ivz<(_k?OVCUZyl)o6ON;{Ku zDJUE*Ul=g6L<*P%pxND&7GxOZE8qvt5Q;^&dNWh-BT`k8&l!ruG%)|7RWIZK7_0zR zMl)b4ax8G+9t)W0pJ0H05kDKPL4e@Okl*)*ghht|N&pT3qM{?%`@*83ut69A@bZre z2I3IghB|uR5yY2b)RC=1k!X-74$EjeD7D5XKHt|tOgVQeK|mqp?uu zX?>?dZ%2-{6=YvJLnRmNm?$^h+&U>OZpQiAuifh2Ty;LqJz*qw&p3Bj_ma0vIxQ&3 zXT=7WXe9;}{9K)W#GjJeK!D`EMindhJy0LC+S@ko`S3K(a4I&SF987bzE2?kJ9p=x z7>WOHh8X~8TOpU!#}kj``Gr4Ss}0MAXB_KXNWL`d-*}&`sk7@X zRp?Q)$T7QZ%(irf%051Rc}15mN5D;^I?*^W%Om~u3!agpw)qwl&)zZh(b6l9BsAJg z?SFX3)B2ii{bnuw2Zq6(cr`N-wXi#I`w^=+%S>&E=*GLeG@rMHN7;Hy81?DXm($|T z^pvjzGw6#5HdJ1u<0YEH>GkMwvR=EM&V1lwk+__kwz#~%MZ4sn+qUD3LKn5^p`&&= zKfL0ebue{E@fVbNP<37{VO1~>@LRP@%Q~p3PW!G|9lBje`q`JeW;s^Cai`fo@@~0j zmhSadg*!SU$ixoio&Rmsl`)m0*3N-XmZ{w{ez66jnYMW@abQY1Jo-~~Ow~0qNNe?F zH(~Oln?J>yM7sA=lq9N)u^N|*`Tf=dzHAof?`!%Fo=njGdh3vk+U^Yzz2yCWtj!M& zE$^Bcs%zS4XDK5`#X0zH&ljr{`g{G(Xgy~tb`Q-??sw_lG=2D&9UTEltA_w5Y680} zVhoyMUQ8Yj7H?GU{n0W(GpN=hYoux;9()+#|Fsj~$*_x&%-KN7o>L~$QKK01s7%q` zi{&B`t}w{9m~c3{QirS6VLzF?a_gS{?N5pCX{`FniQNL8qw9K{=J%jFKWa^Z41ef( z;^&Oi7)|O7_0PDI)uw%w>SIrY64`-z$jRWdY)ZcA^YpaEfWg3uNvm_!acg>YWu1>F zy*Y=wKtnkWE+*EMYrOa*OO!#pbtBTRUN!QB&|2;0-F3VT-w5fF+A1hx!>%x=`&VVy z*H6@5H&`^?Fkb3%Ovl{$#3JbsJKWWH(^8hr{>|%OBnPV|u5Cp`Ica zKGAb~uBL8KL_<1#f}bZjZxEP7-%;7_bhDL2NZaY-S9Qqp*3jMR4~_9%yp^t}>uP2~ zvU9r&55|DbN+Z3GO`2iJ_f~#Vw(jd=i%Z@aNpg+aCAGAHm+#XdhR+SZL|MHXS0=?Q>VaUEbbo^VjxTGxl^Y|HRUXCj>{?fY`5hcdz z1E9W6R9NA3*W}BI62o4}OIv=AMWyg+-znQK1p3?iI5B@f7qcwJVA~%qnY(ZW< zVbEff(nw)&xsX!t*F~+R3Q;F%LJVLs&`CkA4