| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 305d12a commit c445c71
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | 6 | <groupId>com.github.Tencent</groupId> | |
| 7 | 7 | <artifactId>APIJSON</artifactId> | |
| 8 | - <version>5.3.0</version> | ||
| 8 | + <version>5.4.0</version> | ||
| 9 | 9 | <packaging>jar</packaging> | |
| 10 | 10 | ||
| 11 | 11 | <name>APIJSONORM</name> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -423,13 +423,20 @@ public abstract class AbstractSQLConfig implements SQLConfig { | |||
| 423 | 423 | SQL_FUNCTION_MAP.put("json_array", ""); // JSON_ARRAY(val1, val2...) 创建JSON数组 | |
| 424 | 424 | SQL_FUNCTION_MAP.put("json_array_append", ""); // JSON_ARRAY_APPEND(json_doc, val) 将数据附加到JSON文档 | |
| 425 | 425 | SQL_FUNCTION_MAP.put("json_array_insert", ""); // JSON_ARRAY_INSERT(json_doc, val) 插入JSON数组 | |
| 426 | + SQL_FUNCTION_MAP.put("json_array_get", ""); // JSON_ARRAY_GET(json_doc, position) 从JSON数组提取指定位置的元素 | ||
| 426 | 427 | SQL_FUNCTION_MAP.put("json_contains", ""); // JSON_CONTAINS(json_doc, val) JSON文档是否在路径中包含特定对象 | |
| 427 | - SQL_FUNCTION_MAP.put("json_contains_path", ""); // JSON_CONTAINS_PATH(json_doc, path) JSON文档是否在路径中包含任何数据 | ||
| 428 | + SQL_FUNCTION_MAP.put("json_array_contains", ""); // JSON_ARRAY_CONTAINS(json_doc, path) JSON文档是否在路径中包含特定对象 | ||
| 429 | + SQL_FUNCTION_MAP.put("json_contains_path", ""); // JSON_CONTAINS_PATH(json_doc, path) JSON文档是否在路径中包含任何数据 | ||
| 428 | 430 | SQL_FUNCTION_MAP.put("json_depth", ""); // JSON_DEPTH(json_doc) JSON文档的最大深度 | |
| 429 | 431 | SQL_FUNCTION_MAP.put("json_extract", ""); // JSON_EXTRACT(json_doc, path) 从JSON文档返回数据 | |
| 432 | + SQL_FUNCTION_MAP.put("json_extract_scalar", ""); // JSON_EXTRACT_SCALAR(json_doc, path) 从JSON文档返回基础类型数据,例如 Boolean, Number, String | ||
| 430 | 433 | SQL_FUNCTION_MAP.put("json_insert", ""); // JSON_INSERT(json_doc, val) 将数据插入JSON文档 | |
| 431 | 434 | SQL_FUNCTION_MAP.put("json_keys", ""); // JSON_KEYS(json_doc[, path]) JSON文档中的键数组 | |
| 432 | 435 | SQL_FUNCTION_MAP.put("json_length", ""); // JSON_LENGTH(json_doc) JSON文档中的元素数 | |
| 436 | + SQL_FUNCTION_MAP.put("json_size", ""); // JSON_SIZE(json_doc) JSON文档中的元素数 | ||
| 437 | + SQL_FUNCTION_MAP.put("json_array_length", ""); // JSON_ARRAY_LENGTH(json_doc) JSON文档中的元素数 | ||
| 438 | + SQL_FUNCTION_MAP.put("json_format", ""); // JSON_FORMAT(json_doc) 格式化 JSON | ||
| 439 | + SQL_FUNCTION_MAP.put("json_parse", ""); // JSON_PARSE(val) 转换为 JSON | ||
| 433 | 440 | SQL_FUNCTION_MAP.put("json_merge", ""); // JSON_MERGE(json_doc1, json_doc2) (已弃用) 合并JSON文档,保留重复的键。JSON_MERGE_PRESERVE()的已弃用同义词 | |
| 434 | 441 | SQL_FUNCTION_MAP.put("json_merge_patch", ""); // JSON_MERGE_PATCH(json_doc1, json_doc2) 合并JSON文档,替换重复键的值 | |
| 435 | 442 | SQL_FUNCTION_MAP.put("json_merge_preserve", ""); // JSON_MERGE_PRESERVE(json_doc1, json_doc2) 合并JSON文档,保留重复的键 | |
@@ -451,6 +458,7 @@ public abstract class AbstractSQLConfig implements SQLConfig { | |||
| 451 | 458 | SQL_FUNCTION_MAP.put("json_valid", ""); // JSON_VALID(json_doc) JSON值是否有效 | |
| 452 | 459 | SQL_FUNCTION_MAP.put("json_arrayagg", ""); // JSON_ARRAYAGG(key) 将每个表达式转换为 JSON 值,然后返回一个包含这些 JSON 值的 JSON 数组 | |
| 453 | 460 | SQL_FUNCTION_MAP.put("json_objectagg", ""); // JSON_OBJECTAGG(key, val)) 将每个表达式转换为 JSON 值,然后返回一个包含这些 JSON 值的 JSON 对象 | |
| 461 | + SQL_FUNCTION_MAP.put("is_json_scalar", ""); // IS_JSON_SCALAR(val)) 是否为JSON基本类型,例如 Boolean, Number, String | ||
| 454 | 462 | ||
| 455 | 463 | // MySQL 高级函数 | |
| 456 | 464 | // SQL_FUNCTION_MAP.put("bin", ""); // BIN(x) 返回 x 的二进制编码 | |
@@ -3553,7 +3561,10 @@ public String getRegExpString(String key, String column, String value, boolean i | |||
| 3553 | 3561 | if (isPostgreSQL() || isInfluxDB()) { | |
| 3554 | 3562 | return getKey(column) + " ~" + (ignoreCase ? "* " : " ") + getValue(key, column, value); | |
| 3555 | 3563 | } | |
| 3556 | - if (isPresto() || isTrino() || isOracle() || isDameng() || isKingBase() || (isMySQL() && getDBVersionNums()[0] >= 8)) { | ||
| 3564 | + if (isPresto() || isTrino()) { | ||
| 3565 | + return "regexp_like(" + getKey(column) + ", " + getValue(key, column, value) + ")"; | ||
| 3566 | + } | ||
| 3567 | + if (isOracle() || isDameng() || isKingBase() || (isMySQL() && getDBVersionNums()[0] >= 8)) { | ||
| 3557 | 3568 | return "regexp_like(" + getKey(column) + ", " + getValue(key, column, value) + (ignoreCase ? ", 'i'" : ", 'c'") + ")"; | |
| 3558 | 3569 | } | |
| 3559 | 3570 | if (isClickHouse()) { | |
@@ -3864,6 +3875,9 @@ public String getContainString(String key, String column, Object[] childs, int t | |||
| 3864 | 3875 | else if (isOracle() || isDameng() || isKingBase()) { | |
| 3865 | 3876 | condition += ("json_textcontains(" + getKey(column) + ", " + (StringUtil.isEmpty(path, true) ? "'$'" : getValue(key, column, path)) + ", " + getValue(key, column, c == null ? null : c.toString()) + ")"); | |
| 3866 | 3877 | } | |
| 3878 | + else if (isPresto() || isTrino()) { | ||
| 3879 | + condition += ("json_array_contains(cast(" + getKey(column) + " AS VARCHAR), " + getValue(key, column, c) + (StringUtil.isEmpty(path, true) ? "" : ", " + getValue(key, column, path)) + ")"); | ||
| 3880 | + } | ||
| 3867 | 3881 | else { | |
| 3868 | 3882 | String v = c == null ? "null" : (c instanceof Boolean || c instanceof Number ? c.toString() : "\"" + c + "\""); | |
| 3869 | 3883 | if (isClickHouse()) { | |
@@ -4158,7 +4172,6 @@ protected String getOraclePageSql(String sql) { | |||
| 4158 | 4172 | } | |
| 4159 | 4173 | ||
| 4160 | 4174 | /**获取条件SQL字符串 | |
| 4161 | - * @param column | ||
| 4162 | 4175 | * @param table | |
| 4163 | 4176 | * @param config | |
| 4164 | 4177 | * @return | |
@@ -4423,7 +4436,11 @@ else if (rt.endsWith("~")) { | |||
| 4423 | 4436 | sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + (isNot ? NOT : "") | |
| 4424 | 4437 | + " ~" + (ignoreCase ? "* " : " ") + quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote; | |
| 4425 | 4438 | } | |
| 4426 | - else if (isPresto() || isTrino() || isOracle() || isDameng() || isKingBase()) { | ||
| 4439 | + else if (isPresto() || isTrino()) { | ||
| 4440 | + sql += (first ? ON : AND) + "regexp_like(" + quote + jt + quote + "." + quote + on.getKey() + quote | ||
| 4441 | + + ", " + quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote + ")"; | ||
| 4442 | + } | ||
| 4443 | + else if (isOracle() || isDameng() || isKingBase()) { | ||
| 4427 | 4444 | sql += (first ? ON : AND) + "regexp_like(" + quote + jt + quote + "." + quote + on.getKey() + quote | |
| 4428 | 4445 | + ", " + quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote + (ignoreCase ? ", 'i'" : ", 'c'") + ")"; | |
| 4429 | 4446 | } | |
@@ -4490,6 +4507,11 @@ else if (isOracle() || isDameng() || isKingBase()) { | |||
| 4490 | 4507 | + " IS NOT NULL AND json_textcontains(" + arrKeyPath | |
| 4491 | 4508 | + ", '$', " + itemKeyPath + ")") + (isNot ? ") " : ""); | |
| 4492 | 4509 | } | |
| 4510 | + else if (isPresto() || isTrino()) { | ||
| 4511 | + sql += (first ? ON : AND) + (isNot ? "( " : "") + getCondition(isNot, arrKeyPath | ||
| 4512 | + + " IS NOT NULL AND json_array_contains(cast(" + arrKeyPath | ||
| 4513 | + + " AS VARCHAR), " + itemKeyPath + ")") + (isNot ? ") " : ""); | ||
| 4514 | + } | ||
| 4493 | 4515 | else if (isClickHouse()) { | |
| 4494 | 4516 | sql += (first ? ON : AND) + (isNot ? "( " : "") + getCondition(isNot, arrKeyPath | |
| 4495 | 4517 | + " IS NOT NULL AND has(JSONExtractArrayRaw(assumeNotNull(" + arrKeyPath + "))" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -427,6 +427,14 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) throws | |||
| 427 | 427 | sqlTable = rsmd.getTableName(i); // SQL 函数甚至部分字段都不返回表名,当然如果没传 @column 生成的 Table.* 则返回的所有字段都会带表名 | |
| 428 | 428 | sqlResultDuration += System.currentTimeMillis() - startTime3; | |
| 429 | 429 | ||
| 430 | + if (StringUtil.isEmpty(sqlTable, true)) { | ||
| 431 | + boolean isEmpty = curItem == null || curItem.isEmpty(); | ||
| 432 | + String label = isEmpty ? null : getKey(config, rs, rsmd, index, curItem, i, childMap); | ||
| 433 | + if (isEmpty || curItem.containsKey(label) == false) { // 重复字段几乎肯定不是一张表的,尤其是主副表同名主键 id | ||
| 434 | + sqlTable = i <= 1 ? config.getSQLTable() : lastTableName; // Presto 等引擎 JDBC 返回 rsmd.getTableName(i) 为空,主表如果一个字段都没有会导致 APISJON 主副表所有字段都不返回 | ||
| 435 | + } | ||
| 436 | + } | ||
| 437 | + | ||
| 430 | 438 | if (StringUtil.isEmpty(sqlTable, true)) { // hasJoin 已包含这个判断 && joinList != null) { | |
| 431 | 439 | ||
| 432 | 440 | int nextViceColumnStart = lastViceColumnStart; // 主表没有 @column 时会偏小 lastViceColumnStart | |
@@ -1219,10 +1227,13 @@ public void close() { | |||
| 1219 | 1227 | ||
| 1220 | 1228 | @Override | |
| 1221 | 1229 | public ResultSet executeQuery(@NotNull SQLConfig config, String sql) throws Exception { | |
| 1222 | - if (config.isTDengine()) { | ||
| 1230 | + if (config.isPresto() || config.isTrino() || config.isTDengine()) { | ||
| 1223 | 1231 | Connection conn = getConnection(config); | |
| 1224 | - Statement stt = conn.createStatement(); | ||
| 1225 | - return executeQuery(stt, StringUtil.isEmpty(sql) ? config.getSQL(false) : sql); | ||
| 1232 | + Statement stt = config.isTDengine() | ||
| 1233 | + ? conn.createStatement() // fix Presto: ResultSet: Exception: set type is TYPE_FORWARD_ONLY, Result set concurrency must be CONCUR_READ_ONLY | ||
| 1234 | + : conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); | ||
| 1235 | + | ||
| 1236 | + return executeQuery(stt, StringUtil.isEmpty(sql) ? config.getSQL(false) : sql); | ||
| 1226 | 1237 | } | |
| 1227 | 1238 | ||
| 1228 | 1239 | PreparedStatement stt = getStatement(config, sql); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments