From 1b35967eafae6ab1f68cf06bc50fe2bc3bc1bda7 Mon Sep 17 00:00:00 2001 From: CaptHua <57092586+capthua@users.noreply.github.com> Date: Mon, 31 Jul 2023 17:24:55 +0800 Subject: [PATCH 1/2] bugfix: case of the pk col-name in the business sql is inconsistent with the case in the table metadata, resulting in a rollback failure (#5749) --- changes/en-us/develop.md | 4 +++- changes/zh-cn/develop.md | 3 ++- .../datasource/sql/struct/TableRecords.java | 5 ++-- .../io/seata/sqlparser/struct/TableMeta.java | 23 +++++++++++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/changes/en-us/develop.md b/changes/en-us/develop.md index 08cfcdac45f..301c631b468 100644 --- a/changes/en-us/develop.md +++ b/changes/en-us/develop.md @@ -6,7 +6,8 @@ Add changes here for all PR submitted to the develop branch. - [[#XXX](https://github.com/seata/seata/pull/XXX)] XXX ### bugfix: -- [[#XXX](https://github.com/seata/seata/pull/XXX)] XXX +- [[#5749](https://github.com/seata/seata/pull/5749)] case of the pk col-name in the business sql is inconsistent with the case in the table metadata, resulting in a rollback failure + ### optimize: - [[#XXX](https://github.com/seata/seata/pull/XXX)] XXX @@ -21,6 +22,7 @@ Thanks to these contributors for their code commits. Please report an unintended - [slievrly](https://github.com/slievrly) +- [capthua](https://github.com/capthua) - [XXX](https://github.com/XXX) diff --git a/changes/zh-cn/develop.md b/changes/zh-cn/develop.md index 488d2680a3b..3ba57b1ed3c 100644 --- a/changes/zh-cn/develop.md +++ b/changes/zh-cn/develop.md @@ -6,7 +6,7 @@ - [[#XXX](https://github.com/seata/seata/pull/XXX)] XXX ### bugfix: -- [[#XXX](https://github.com/seata/seata/pull/XXX)] XXX +- [[#5749](https://github.com/seata/seata/pull/5749)] 修复在某些情况下,业务sql中主键字段名大小写与表元数据中的不一致,导致回滚失败 ### optimize: - [[#XXX](https://github.com/seata/seata/pull/XXX)] XXX @@ -21,6 +21,7 @@ - [slievrly](https://github.com/slievrly) +- [capthua](https://github.com/capthua) - [XXX](https://github.com/XXX) diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableRecords.java b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableRecords.java index 219ceb6db1a..6dcada792e7 100755 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableRecords.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableRecords.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import javax.sql.rowset.serial.SerialBlob; import javax.sql.rowset.serial.SerialClob; import javax.sql.rowset.serial.SerialDatalink; @@ -193,7 +194,7 @@ public static TableRecords empty(TableMeta tableMeta) { public static TableRecords buildRecords(TableMeta tmeta, ResultSet resultSet) throws SQLException { TableRecords records = new TableRecords(tmeta); ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); - Map primaryKeyMap = tmeta.getPrimaryKeyMap(); + Set ignoreCasePKs = tmeta.getCaseInsensitivePKs(); int columnCount = resultSetMetaData.getColumnCount(); while (resultSet.next()) { @@ -204,7 +205,7 @@ public static TableRecords buildRecords(TableMeta tmeta, ResultSet resultSet) th int dataType = col.getDataType(); Field field = new Field(); field.setName(col.getColumnName()); - if (primaryKeyMap.containsKey(colName)) { + if (ignoreCasePKs.contains(colName)) { field.setKeyType(KeyType.PRIMARY_KEY); } field.setType(dataType); diff --git a/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/struct/TableMeta.java b/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/struct/TableMeta.java index 2e093b78e51..67a6b5f04be 100644 --- a/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/struct/TableMeta.java +++ b/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/struct/TableMeta.java @@ -20,6 +20,9 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeSet; +import java.util.Collections; import java.util.Objects; import java.util.stream.Collectors; @@ -150,6 +153,26 @@ public Map getPrimaryKeyMap() { return pk; } + /** + * Gets case-insensitive primary key set + * + * @return case-insensitive, unmodifiable primary key set + */ + public Set getCaseInsensitivePKs() { + Set pks = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + allIndexes.forEach((key, index) -> { + if (index.getIndextype().value() == IndexType.PRIMARY.value()) { + for (ColumnMeta col : index.getValues()) { + pks.add(col.getColumnName()); + } + } + }); + if (pks.size() < 1) { + throw new NotSupportYetException(String.format("%s needs to contain the primary key.", tableName)); + } + return Collections.unmodifiableSet(pks); + } + /** * Gets primary key only name. * From d8c88d4e5b1c771ff581f3f9bfbd68a0908751e9 Mon Sep 17 00:00:00 2001 From: Ron Robyn Date: Sun, 6 Aug 2023 21:53:05 +0800 Subject: [PATCH 2/2] bugfix: change some fields type of TableMetaCache to avoid integer overflow (#5762) --- changes/en-us/develop.md | 2 ++ changes/zh-cn/develop.md | 2 ++ .../rm/datasource/sql/struct/cache/MysqlTableMetaCache.java | 2 +- .../datasource/sql/struct/cache/OracleTableMetaCache.java | 2 +- .../sql/struct/cache/PostgresqlTableMetaCache.java | 2 +- .../sql/struct/cache/MysqlTableMetaCacheTest.java | 6 +++--- .../src/main/java/io/seata/sqlparser/struct/IndexMeta.java | 6 +++--- 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/changes/en-us/develop.md b/changes/en-us/develop.md index 301c631b468..62483302f78 100644 --- a/changes/en-us/develop.md +++ b/changes/en-us/develop.md @@ -7,6 +7,7 @@ Add changes here for all PR submitted to the develop branch. ### bugfix: - [[#5749](https://github.com/seata/seata/pull/5749)] case of the pk col-name in the business sql is inconsistent with the case in the table metadata, resulting in a rollback failure +- [[#5762](https://github.com/seata/seata/pull/5762)] change some fields type of TableMetaCache to avoid integer overflow ### optimize: @@ -23,6 +24,7 @@ Thanks to these contributors for their code commits. Please report an unintended - [slievrly](https://github.com/slievrly) - [capthua](https://github.com/capthua) +- [robynron](https://github.com/robynron) - [XXX](https://github.com/XXX) diff --git a/changes/zh-cn/develop.md b/changes/zh-cn/develop.md index 3ba57b1ed3c..36130f22894 100644 --- a/changes/zh-cn/develop.md +++ b/changes/zh-cn/develop.md @@ -7,6 +7,7 @@ ### bugfix: - [[#5749](https://github.com/seata/seata/pull/5749)] 修复在某些情况下,业务sql中主键字段名大小写与表元数据中的不一致,导致回滚失败 +- [[#5762](https://github.com/seata/seata/pull/5762)] 修复TableMetaCache的一些字段类型,避免溢出 ### optimize: - [[#XXX](https://github.com/seata/seata/pull/XXX)] XXX @@ -22,6 +23,7 @@ - [slievrly](https://github.com/slievrly) - [capthua](https://github.com/capthua) +- [robynron](https://github.com/robynron) - [XXX](https://github.com/XXX) diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/MysqlTableMetaCache.java b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/MysqlTableMetaCache.java index fdce71e3e32..a2817697f20 100755 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/MysqlTableMetaCache.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/MysqlTableMetaCache.java @@ -169,7 +169,7 @@ private TableMeta resultSetMetaToSchema(ResultSetMetaData rsmd, DatabaseMetaData index.setType(rsIndex.getShort("TYPE")); index.setOrdinalPosition(rsIndex.getShort("ORDINAL_POSITION")); index.setAscOrDesc(rsIndex.getString("ASC_OR_DESC")); - index.setCardinality(rsIndex.getInt("CARDINALITY")); + index.setCardinality(rsIndex.getLong("CARDINALITY")); index.getValues().add(col); if ("PRIMARY".equalsIgnoreCase(indexName)) { index.setIndextype(IndexType.PRIMARY); diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/OracleTableMetaCache.java b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/OracleTableMetaCache.java index b00bc9bfb76..bea9afe6f59 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/OracleTableMetaCache.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/OracleTableMetaCache.java @@ -142,7 +142,7 @@ private TableMeta resultSetMetaToSchema(DatabaseMetaData dbmd, String tableName) index.setType(rsIndex.getShort("TYPE")); index.setOrdinalPosition(rsIndex.getShort("ORDINAL_POSITION")); index.setAscOrDesc(rsIndex.getString("ASC_OR_DESC")); - index.setCardinality(rsIndex.getInt("CARDINALITY")); + index.setCardinality(rsIndex.getLong("CARDINALITY")); index.getValues().add(col); if (!index.isNonUnique()) { index.setIndextype(IndexType.UNIQUE); diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/PostgresqlTableMetaCache.java b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/PostgresqlTableMetaCache.java index a87c2f6adff..0a8a14ce0ed 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/PostgresqlTableMetaCache.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/cache/PostgresqlTableMetaCache.java @@ -160,7 +160,7 @@ private TableMeta resultSetMetaToSchema(Connection connection, String tableName) index.setType(rsIndex.getShort("type")); index.setOrdinalPosition(rsIndex.getShort("ordinal_position")); index.setAscOrDesc(rsIndex.getString("asc_or_desc")); - index.setCardinality(rsIndex.getInt("cardinality")); + index.setCardinality(rsIndex.getLong("cardinality")); index.getValues().add(col); if (!index.isNonUnique()) { index.setIndextype(IndexType.UNIQUE); diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/sql/struct/cache/MysqlTableMetaCacheTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/sql/struct/cache/MysqlTableMetaCacheTest.java index 4a24a2b143a..56928aa6d70 100644 --- a/rm-datasource/src/test/java/io/seata/rm/datasource/sql/struct/cache/MysqlTableMetaCacheTest.java +++ b/rm-datasource/src/test/java/io/seata/rm/datasource/sql/struct/cache/MysqlTableMetaCacheTest.java @@ -55,9 +55,9 @@ public class MysqlTableMetaCacheTest { private static Object[][] indexMetas = new Object[][] { - new Object[] {"PRIMARY", "id", false, "", 3, 0, "A", 34}, - new Object[] {"name1", "name1", false, "", 3, 1, "A", 34}, - new Object[] {"name2", "name2", true, "", 3, 2, "A", 34}, + new Object[] {"PRIMARY", "id", false, "", 3, 0, "A", 34L}, + new Object[] {"name1", "name1", false, "", 3, 1, "A", 34L}, + new Object[] {"name2", "name2", true, "", 3, 2, "A", 34L}, }; @Test diff --git a/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/struct/IndexMeta.java b/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/struct/IndexMeta.java index a55055c3ad0..18ba58fb1fa 100644 --- a/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/struct/IndexMeta.java +++ b/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/struct/IndexMeta.java @@ -35,7 +35,7 @@ public class IndexMeta { private short type; private IndexType indextype; private String ascOrDesc; - private int cardinality; + private long cardinality; private int ordinalPosition; /** @@ -157,7 +157,7 @@ public void setAscOrDesc(String ascOrDesc) { * * @return the cardinality */ - public int getCardinality() { + public long getCardinality() { return cardinality; } @@ -166,7 +166,7 @@ public int getCardinality() { * * @param cardinality the cardinality */ - public void setCardinality(int cardinality) { + public void setCardinality(long cardinality) { this.cardinality = cardinality; }