Visitar URL original
feat: 支持 KingbaseES MySQL、Oracle、SQL Server 三种兼容模式 by fuziran · Pull Request #868 · APIJSON/APIJSON · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: improve Kingbase compatibility
  • Loading branch information
fuziran authored and xiaoaozz committed Jul 28, 2026
commit 6d4fc16f5bd81a8719001a5c4d8389067cc348ab
39 changes: 26 additions & 13 deletions APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -1185,31 +1185,31 @@ public boolean isKingBase() {
return isKingBase(gainSQLDatabase());
}
public static boolean isKingBase(String db) {
return DATABASE_KINGBASE.equals(db) || isKingBaseMySQL(db) || isKingBaseOracle(db) || isKingBaseSQLServer(db);
return KingbaseSQLDialect.from(db).isKingbase();
}

@Override
public boolean isKingBaseMySQL() {
return isKingBaseMySQL(gainSQLDatabase());
}
public static boolean isKingBaseMySQL(String db) {
return DATABASE_KINGBASE_MYSQL.equals(db);
return KingbaseSQLDialect.from(db).isMySQL();
}

@Override
public boolean isKingBaseOracle() {
return isKingBaseOracle(gainSQLDatabase());
}
public static boolean isKingBaseOracle(String db) {
return DATABASE_KINGBASE_ORACLE.equals(db);
return KingbaseSQLDialect.from(db).isOracle();
}

@Override
public boolean isKingBaseSQLServer() {
return isKingBaseSQLServer(gainSQLDatabase());
}
public static boolean isKingBaseSQLServer(String db) {
return DATABASE_KINGBASE_SQLSERVER.equals(db);
return KingbaseSQLDialect.from(db).isSQLServer();
}

@Override
Expand Down Expand Up @@ -1426,7 +1426,11 @@ public String getQuote() { // MongoDB 同时支持 `tbl` 反引号 和 "col"
if(isElasticsearch() || isManticore() || isIoTDB() || isSurrealDB()) {
return "";
}
return isMySQL() || isMariaDB() || isTiDB() || isClickHouse() || isTDengine() || isMilvus() || isDoris() || isStarRocks() || isKingBaseMySQL() ? "`" : "\"";
KingbaseSQLDialect kingbaseDialect = KingbaseSQLDialect.from(gainSQLDatabase());
if (kingbaseDialect.isKingbase()) {
return kingbaseDialect.getIdentifierQuote();
}
return isMySQL() || isMariaDB() || isTiDB() || isClickHouse() || isTDengine() || isMilvus() || isDoris() || isStarRocks() ? "`" : "\"";
}

public String quote(String s) {
Expand Down Expand Up @@ -3110,6 +3114,12 @@ else if (isSurrealDB()) {
}
}

KingbaseSQLDialect kingbaseDialect = KingbaseSQLDialect.from(gainSQLDatabase());
String kingbaseLimit = kingbaseDialect.getSelectLimit(getOffset(page, count), count);
if (kingbaseLimit != null) {
return kingbaseLimit;
}

boolean isOracle = isOracle();
return gainLimitString(page, count, isTSQL(), isOracle || isDameng() || isKingBaseOracle(), isPresto() || isTrino());
}
Expand Down Expand Up @@ -4662,10 +4672,10 @@ public String gainContainString(String key, String column, Object[] childs, int
condition += (gainKey(column) + " @> " + gainValue(key, column, newJSONArray(c)));
// operator does not exist: jsonb @> character varying "[" + c + "]");
}
else if (isKingBase()) {
else if (isKingBase() && isKingBaseOracle() == false) {
condition += (gainKey(column) + "::jsonb @> " + gainValue(key, column, newJSONArray(c)) + "::jsonb");
}
else if (isOracle() || isDameng()) {
else if (isOracle() || isDameng() || isKingBaseOracle()) {
condition += ("json_textcontains(" + gainKey(column) + ", " + (StringUtil.isEmpty(path, true)
? "'$'" : gainValue(key, column, path)) + ", " + gainValue(key, column, c == null ? null : c.toString()) + ")");
}
Expand Down Expand Up @@ -5029,20 +5039,23 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> String
return "ALTER TABLE " + tablePath + " UPDATE" + config.gainSetString() + config.gainWhereString(true);
}
cSql = "UPDATE " + tablePath + config.gainSetString() + config.gainWhereString(true)
+ (config.isMySQL() || config.isKingBaseMySQL() ? config.gainLimitString() : "");
+ (config.isMySQL() || KingbaseSQLDialect.from(config.gainSQLDatabase()).supportsDmlLimit() ? config.gainLimitString() : "");
cSql = buildWithAsExprSql(config, cSql);
return cSql;
case DELETE:
if(config.isClickHouse()){
return "ALTER TABLE " + tablePath + " DELETE" + config.gainWhereString(true);
}
cSql = "DELETE FROM " + tablePath + config.gainWhereString(true)
+ (config.isMySQL() || config.isKingBaseMySQL() ? config.gainLimitString() : ""); // PostgreSQL 不允许 LIMIT
+ (config.isMySQL() || KingbaseSQLDialect.from(config.gainSQLDatabase()).supportsDmlLimit() ? config.gainLimitString() : ""); // PostgreSQL 不允许 LIMIT
cSql = buildWithAsExprSql(config, cSql);
return cSql;
default:
String explain = config.isExplain() ? (config.isSQLServer() || config.isKingBaseSQLServer() ? "SET STATISTICS PROFILE ON "
: (config.isOracle() || config.isDameng() || config.isKingBaseOracle() ? "EXPLAIN PLAN FOR " : "EXPLAIN ")) : "";
KingbaseSQLDialect kingbaseDialect = KingbaseSQLDialect.from(config.gainSQLDatabase());
String kingbaseExplain = kingbaseDialect.getExplainPrefix();
String explain = config.isExplain() ? (kingbaseExplain != null ? kingbaseExplain
: (config.isSQLServer() ? "SET STATISTICS PROFILE ON "
: (config.isOracle() || config.isDameng() ? "EXPLAIN PLAN FOR " : "EXPLAIN "))) : "";
if (config.isTest() && RequestMethod.isGetMethod(config.getMethod(), true)) { // FIXME 为啥是 code 而不是 count ?
String q = config.getQuote(); // 生成 SELECT ( (24 >=0 AND 24 <3) ) AS `code` LIMIT 1 OFFSET 0
return explain + "SELECT " + config.gainWhereString(false)
Expand Down Expand Up @@ -5459,11 +5472,11 @@ else if ("{}".equals(rt) || "<>".equals(rt)) {
sql += (first ? ON : AND) + (isNot ? "( " : "") + gainCondition(isNot, arrKeyPath
+ " IS NOT NULL AND " + arrKeyPath + " @> " + itemKeyPath) + (isNot ? ") " : "");
}
else if (isKingBase()) {
else if (isKingBase() && isKingBaseOracle() == false) {
sql += (first ? ON : AND) + (isNot ? "( " : "") + gainCondition(isNot, arrKeyPath
+ " IS NOT NULL AND " + arrKeyPath + "::jsonb @> " + itemKeyPath + "::jsonb") + (isNot ? ") " : "");
}
else if (isOracle() || isDameng()) {
else if (isOracle() || isDameng() || isKingBaseOracle()) {
sql += (first ? ON : AND) + (isNot ? "( " : "") + gainCondition(isNot, arrKeyPath
+ " IS NOT NULL AND json_textcontains(" + arrKeyPath
+ ", '$', " + itemKeyPath + ")") + (isNot ? ") " : "");
Expand Down
Loading