diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlCreateTableSqlBuilder.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlCreateTableSqlBuilder.java
index d974b47e..fb6b7da0 100644
--- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlCreateTableSqlBuilder.java
+++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlCreateTableSqlBuilder.java
@@ -12,16 +12,18 @@
import org.hswebframework.ezorm.rdb.operator.builder.fragments.ddl.CreateIndexParameter;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.ddl.CreateIndexSqlBuilder;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.ddl.CreateTableSqlBuilder;
-import org.hswebframework.ezorm.rdb.supports.mysql.MysqlCreateTableSqlBuilder;
+
+import static org.hswebframework.ezorm.rdb.executor.SqlRequests.of;
/**
* KingbaseES MySQL 兼容模式的建表 SQL 构建器.
*
- * 与 {@link MysqlCreateTableSqlBuilder} 的区别:
+ * 与 {@link org.hswebframework.ezorm.rdb.supports.mysql.MysqlCreateTableSqlBuilder} 的区别:
*
* - 去掉了 {@code ENGINE=InnoDB DEFAULT CHARSET=utf8mb4} 等 MySQL 特有子句
+ * - comment 使用 PostgreSQL 标准的 {@code COMMENT ON COLUMN/TABLE} 语法,
+ * 而非 MySQL 的内联 {@code comment 'xxx'}
* - 保留了 {@code auto_increment}(KingbaseES MySQL 兼容版支持)
- * - 保留了 {@code comment} 语法
*
*
* @since 4.2
@@ -61,18 +63,21 @@ public SqlRequest build(RDBTableMetadata table) {
createTable.addSql("default", ((NativeSql) defaultValue).getSql());
}
}
- if (column.getComment() != null) {
- createTable.addSql(" comment ",
- StringUtils.concat("'", column.getComment(), "'"));
- }
+ }
+ // 使用 PostgreSQL 标准的 COMMENT ON COLUMN 语法(作为单独的批量 SQL)
+ if (column.getComment() != null) {
+ sql.addBatch(of(String.format("comment on column %s is '%s'",
+ column.getFullTableName(), column.getComment())));
}
}
// KingbaseES 不支持 ENGINE= 和 DEFAULT CHARSET=,直接关闭括号
createTable.addSql(")");
+ // 使用 PostgreSQL 标准的 COMMENT ON TABLE 语法
if (table.getComment() != null) {
- createTable.addSql("COMMENT=", StringUtils.concat("'", table.getComment(), "'"));
+ sql.addBatch(of(String.format("comment on table %s is '%s'",
+ table.getFullName(), table.getComment())));
}
sql.setSql(createTable.toRequest().getSql());
diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlDialect.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlDialect.java
index 21fdf6a3..c2cdfe3e 100644
--- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlDialect.java
+++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlDialect.java
@@ -16,7 +16,7 @@
* 因此:
*
* - 数据类型映射:复用 MySQL 的类型映射
- * - 标识符引用:使用双引号(PostgreSQL 风格),因为驱动层是 r2dbc-postgresql
+ * - 标识符引用:使用反引号(MySQL 风格),KingbaseES MySQL 兼容模式不支持双引号
*
*
* @since 4.2
@@ -66,12 +66,12 @@ public KingbaseMysqlDialect() {
@Override
public String getQuoteStart() {
- return "\"";
+ return "`";
}
@Override
public String getQuoteEnd() {
- return "\"";
+ return "`";
}
@Override
diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlSchemaMetadata.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlSchemaMetadata.java
index 36f832df..b2d56c61 100644
--- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlSchemaMetadata.java
+++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlSchemaMetadata.java
@@ -4,10 +4,10 @@
import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
import org.hswebframework.ezorm.rdb.operator.CompositeExceptionTranslation;
-import org.hswebframework.ezorm.rdb.supports.mysql.MysqlAlterTableSqlBuilder;
import org.hswebframework.ezorm.rdb.supports.mysql.MysqlEnumInFragmentBuilder;
import org.hswebframework.ezorm.rdb.supports.mysql.MysqlIndexMetadataParser;
import org.hswebframework.ezorm.rdb.supports.mysql.MysqlPaginator;
+import org.hswebframework.ezorm.rdb.supports.postgres.PostgresqlAlterTableSqlBuilder;
import org.hswebframework.ezorm.rdb.supports.postgres.PostgresqlR2DBCExceptionTranslation;
import org.hswebframework.ezorm.rdb.utils.FeatureUtils;
@@ -16,11 +16,12 @@
*
* KingbaseES 底层使用 PostgreSQL 协议通信,但 SQL 语法兼容 MySQL。因此:
*
- * - DDL 构建器:使用 KingbaseES 适配版(去掉 ENGINE=/CHARSET=)
+ * - DDL 构建器:使用 KingbaseES 适配版(去掉 ENGINE=/CHARSET=,COMMENT ON 语法)
+ * - ALTER TABLE:使用 PostgreSQL 风格(避免 MySQL 内联 comment 不兼容问题)
* - 分页器:复用 MySQL 的 LIMIT ?,? 语法
- * - 元数据解析器:复用 MySQL information_schema 查询
+ * - 元数据解析器:基于 MySQL information_schema 查询,增加 CAST 转换
* - 异常翻译:使用 PostgreSQL 异常翻译(因为驱动层是 r2dbc-postgresql)
- * - 方言:使用 {@link KingbaseMysqlDialect}(MySQL 类型映射 + 双引号引用)
+ * - 方言:使用 {@link KingbaseMysqlDialect}(MySQL 类型映射 + 反引号引用)
*
*
* @since 4.2
@@ -30,9 +31,9 @@ public class KingbaseMysqlSchemaMetadata extends RDBSchemaMetadata {
public KingbaseMysqlSchemaMetadata(String name) {
super(name);
- // DDL 构建器 - 去掉 ENGINE=/CHARSET=
+ // DDL 构建器 - 去掉 ENGINE=/CHARSET=,使用 COMMENT ON 语法
addFeature(new KingbaseMysqlCreateTableSqlBuilder());
- addFeature(new MysqlAlterTableSqlBuilder());
+ addFeature(new PostgresqlAlterTableSqlBuilder());
// 分页器 - 复用 MySQL 的 LIMIT ?,? 语法
addFeature(new MysqlPaginator());
diff --git a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlTableMetadataParser.java b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlTableMetadataParser.java
index 557f8233..f03b3f0c 100644
--- a/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlTableMetadataParser.java
+++ b/hsweb-easy-orm-rdb/src/main/java/org/hswebframework/ezorm/rdb/supports/kingbase/mysql/KingbaseMysqlTableMetadataParser.java
@@ -1,24 +1,81 @@
package org.hswebframework.ezorm.rdb.supports.kingbase.mysql;
import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
-import org.hswebframework.ezorm.rdb.supports.mysql.MysqlTableMetadataParser;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
+import org.hswebframework.ezorm.rdb.supports.commons.RDBTableMetadataParser;
+import reactor.core.publisher.Flux;
+
+import java.util.List;
/**
* KingbaseES MySQL 兼容模式的表元数据解析器.
*
- * KingbaseES MySQL 兼容模式的 {@code information_schema.columns} 和
- * {@code information_schema.tables} 与 MySQL 高度兼容,
- * 因此直接继承 {@link MysqlTableMetadataParser}。
- *
- * 如果后续发现字段差异(如 {@code column_type} 不存在等),
- * 可在此类中覆盖对应的 SQL 方法。
+ * 通过 r2dbc-postgresql 驱动查询 information_schema 时,
+ * {@code character_maximum_length}、{@code numeric_precision}、{@code numeric_scale}
+ * 等字段的返回类型为 varchar(而非 int),需要在 SQL 中进行显式 CAST 转换,
+ * 避免 {@code ClassCastException: Cannot cast String to Number}。
*
* @since 4.2
*/
-public class KingbaseMysqlTableMetadataParser extends MysqlTableMetadataParser {
+public class KingbaseMysqlTableMetadataParser extends RDBTableMetadataParser {
+
+ private static final String TABLE_META_SQL = String.join(" ",
+ "select",
+ "column_name as `name`,",
+ "data_type as `data_type`,",
+ "cast(character_maximum_length as integer) as `data_length`,",
+ "cast(numeric_precision as integer) as `data_precision`,",
+ "cast(numeric_scale as integer) as `data_scale`,",
+ "column_comment as `comment`,",
+ "table_name as `table_name`,",
+ "column_type as `column_type`,",
+ "case when is_nullable='YES' then 0 else 1 end as `not_null`",
+ "from information_schema.columns where table_schema=#{schema} and table_name like #{table}");
+
+ private static final String TABLE_COMMENT_SQL = String.join(" ",
+ "select ",
+ "table_comment as `comment`",
+ ",table_name as `table_name`",
+ "from information_schema.tables where table_schema=#{schema} and table_name like #{table}");
+
+ private static final String ALL_TABLE_SQL =
+ "select table_name as `name` from information_schema.`TABLES` where table_schema=#{schema}";
+
+ private static final String TABLE_EXISTS_SQL =
+ "select count(1) as `total` from information_schema.`TABLES` where table_schema=#{schema} and table_name=#{table}";
public KingbaseMysqlTableMetadataParser(RDBSchemaMetadata schema) {
super(schema);
}
+ @Override
+ protected String getTableMetaSql(String name) {
+ return TABLE_META_SQL;
+ }
+
+ @Override
+ protected String getTableCommentSql(String name) {
+ return TABLE_COMMENT_SQL;
+ }
+
+ @Override
+ protected String getAllTableSql() {
+ return ALL_TABLE_SQL;
+ }
+
+ @Override
+ public String getTableExistsSql() {
+ return TABLE_EXISTS_SQL;
+ }
+
+ @Override
+ public List parseAll() {
+ return super.fastParseAll();
+ }
+
+ @Override
+ public Flux parseAllReactive() {
+ return super.fastParseAllReactive();
+ }
+
}