Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 处理自关联查询时,对Table:alias的写法sql表名拼写异常的问题 #750

Merged
merged 2 commits into from
Aug 11, 2024
Merged
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
106 changes: 56 additions & 50 deletions APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public abstract class AbstractSQLConfig<T extends Object> implements SQLConfig<T
TABLE_KEY_MAP.put(AllTableComment.class.getSimpleName(), AllTableComment.TABLE_NAME);
TABLE_KEY_MAP.put(AllColumnComment.class.getSimpleName(), AllColumnComment.TABLE_NAME);

ALLOW_PARTIAL_UPDATE_FAIL_TABLE_MAP = new HashMap<>();
ALLOW_PARTIAL_UPDATE_FAIL_TABLE_MAP = new HashMap<>();

CONFIG_TABLE_LIST = new ArrayList<>(); // Table, Column 等是系统表 AbstractVerifier.SYSTEM_ACCESS_MAP.keySet());
CONFIG_TABLE_LIST.add(Function.class.getSimpleName());
Expand Down Expand Up @@ -492,8 +492,8 @@ public abstract class AbstractSQLConfig<T extends Object> implements SQLConfig<T
SQL_FUNCTION_MAP.put("json_array_insert", ""); // JSON_ARRAY_INSERT(json_doc, val) 插入JSON数组
SQL_FUNCTION_MAP.put("json_array_get", ""); // JSON_ARRAY_GET(json_doc, position) 从JSON数组提取指定位置的元素
SQL_FUNCTION_MAP.put("json_contains", ""); // JSON_CONTAINS(json_doc, val) JSON文档是否在路径中包含特定对象
SQL_FUNCTION_MAP.put("json_array_contains", ""); // JSON_ARRAY_CONTAINS(json_doc, path) JSON文档是否在路径中包含特定对象
SQL_FUNCTION_MAP.put("json_contains_path", ""); // JSON_CONTAINS_PATH(json_doc, path) JSON文档是否在路径中包含任何数据
SQL_FUNCTION_MAP.put("json_array_contains", ""); // JSON_ARRAY_CONTAINS(json_doc, path) JSON文档是否在路径中包含特定对象
SQL_FUNCTION_MAP.put("json_contains_path", ""); // JSON_CONTAINS_PATH(json_doc, path) JSON文档是否在路径中包含任何数据
SQL_FUNCTION_MAP.put("json_depth", ""); // JSON_DEPTH(json_doc) JSON文档的最大深度
SQL_FUNCTION_MAP.put("json_extract", ""); // JSON_EXTRACT(json_doc, path) 从JSON文档返回数据
SQL_FUNCTION_MAP.put("json_extract_scalar", ""); // JSON_EXTRACT_SCALAR(json_doc, path) 从JSON文档返回基础类型数据,例如 Boolean, Number, String
Expand Down Expand Up @@ -1384,6 +1384,12 @@ public String getSQLTable() {
String nt = TABLE_KEY_MAP.get(ot);
return StringUtil.isEmpty(nt) ? ot : nt;
}

@JSONField(serialize = false)
public String getSQLTableWithAlias(String table,String alias) {
return StringUtil.isEmpty(alias) ? table : alias ;
}

@JSONField(serialize = false)
@Override
public String getTablePath() {
Expand Down Expand Up @@ -1547,7 +1553,7 @@ public String getHavingString(boolean hasPrefix) throws Exception {
}

List<String> raw = getRaw();
// 提前把 @having& 转为 @having,或者干脆不允许 @raw:"@having&" boolean containRaw = raw != null && (raw.contains(KEY_HAVING) || raw.contains(KEY_HAVING_AND));
// 提前把 @having& 转为 @having,或者干脆不允许 @raw:"@having&" boolean containRaw = raw != null && (raw.contains(KEY_HAVING) || raw.contains(KEY_HAVING_AND));
boolean containRaw = raw != null && raw.contains(KEY_HAVING);

// 直接把 having 类型从 Map<String, String> 定改为 Map<String, Object>,避免额外拷贝
Expand Down Expand Up @@ -2657,12 +2663,12 @@ public String getLimitString() {
}

return getLimitString(
getPage()
, getCount()
, isOracle() || isSQLServer() || isDb2()
, isOracle() || isDameng() || isKingBase()
, isPresto() || isTrino()
);
getPage()
, getCount()
, isOracle() || isSQLServer() || isDb2()
, isOracle() || isDameng() || isKingBase()
, isPresto() || isTrino()
);
}
/**获取限制数量及偏移量
* @param page
Expand All @@ -2672,7 +2678,7 @@ public String getLimitString() {
* @return
*/
public static String getLimitString(int page, int count, boolean isTSQL, boolean isOracle) {
return getLimitString(page, count, isTSQL, isOracle, false);
return getLimitString(page, count, isTSQL, isOracle, false);
}
/**获取限制数量及偏移量
* @param page
Expand All @@ -2685,17 +2691,17 @@ public static String getLimitString(int page, int count, boolean isTSQL, boolean
public static String getLimitString(int page, int count, boolean isTSQL, boolean isOracle, boolean isPresto) {
int offset = getOffset(page, count);

if (isOracle) { // TODO 判断版本,高版本可以用 OFFSET FETCH
return " WHERE ROWNUM BETWEEN " + offset + " AND " + (offset + count);
}
if (isOracle) { // TODO 判断版本,高版本可以用 OFFSET FETCH
return " WHERE ROWNUM BETWEEN " + offset + " AND " + (offset + count);
}

if (isTSQL) { // OFFSET FECTH 中所有关键词都不可省略, 另外 Oracle 数据库使用子查询加 where 分页
return " OFFSET " + offset + " ROWS FETCH FIRST " + count + " ROWS ONLY";
}

if (isPresto) { // https://prestodb.io/docs/current/sql/select.html
return (offset <= 0 ? "" : " OFFSET " + offset) + " LIMIT " + count;
}
if (isPresto) { // https://prestodb.io/docs/current/sql/select.html
return (offset <= 0 ? "" : " OFFSET " + offset) + " LIMIT " + count;
}

return " LIMIT " + count + (offset <= 0 ? "" : " OFFSET " + offset); // DELETE, UPDATE 不支持 OFFSET
}
Expand Down Expand Up @@ -3868,17 +3874,17 @@ public String getRegExpString(String key, String column, String value, boolean i
if (isOracle() || isDameng() || isKingBase() || (isMySQL() && getDBVersionNums()[0] >= 8)) {
return "regexp_like(" + getKey(column) + ", " + getValue(key, column, value) + (ignoreCase ? ", 'i'" : ", 'c'") + ")";
}
if (isPresto() || isTrino()) {
return "regexp_like(" + (ignoreCase ? "lower(" : "") + getKey(column) + (ignoreCase ? ")" : "")
+ ", " + (ignoreCase ? "lower(" : "") + getValue(key, column, value) + (ignoreCase ? ")" : "") + ")";
}
if (isPresto() || isTrino()) {
return "regexp_like(" + (ignoreCase ? "lower(" : "") + getKey(column) + (ignoreCase ? ")" : "")
+ ", " + (ignoreCase ? "lower(" : "") + getValue(key, column, value) + (ignoreCase ? ")" : "") + ")";
}
if (isClickHouse()) {
return "match(" + (ignoreCase ? "lower(" : "") + getKey(column) + (ignoreCase ? ")" : "")
+ ", " + (ignoreCase ? "lower(" : "") + getValue(key, column, value) + (ignoreCase ? ")" : "") + ")";
}
if (isElasticsearch()) {
return getKey(column) + " RLIKE " + getValue(key, column, value);
}
if (isElasticsearch()) {
return getKey(column) + " RLIKE " + getValue(key, column, value);
}
if (isHive()) {
return (ignoreCase ? "lower(" : "") + getKey(column) + (ignoreCase ? ")" : "")
+ " REGEXP " + (ignoreCase ? "lower(" : "") + getValue(key, column, value) + (ignoreCase ? ")" : "");
Expand Down Expand Up @@ -4135,7 +4141,7 @@ public String getExistsString(String key, String column, Object value, String ra
/**WHERE key contains value
* @param key
* @param value
* @return {@link #getContainString(String, String, Object[], int)}
* @return {@link #getContainString(String, String, Object[], int)}
* @throws NotExistException
*/
@JSONField(serialize = false)
Expand Down Expand Up @@ -4196,11 +4202,11 @@ else if (isOracle() || isDameng() || isKingBase()) {
condition += ("json_textcontains(" + getKey(column) + ", " + (StringUtil.isEmpty(path, true)
? "'$'" : getValue(key, column, path)) + ", " + getValue(key, column, c == null ? null : c.toString()) + ")");
}
else if (isPresto() || isTrino()) {
condition += ("json_array_contains(cast(" + getKey(column) + " AS VARCHAR), "
else if (isPresto() || isTrino()) {
condition += ("json_array_contains(cast(" + getKey(column) + " AS VARCHAR), "
+ getValue(key, column, c) + (StringUtil.isEmpty(path, true)
? "" : ", " + getValue(key, column, path)) + ")");
}
}
else {
String v = c == null ? "null" : (c instanceof Boolean || c instanceof Number ? c.toString() : "\"" + c + "\"");
if (isClickHouse()) {
Expand Down Expand Up @@ -4613,7 +4619,7 @@ protected String getOraclePageSql(String sql) {
}
int offset = getOffset(getPage(), count);
String alias = getAliasWithQuote();
String quote = getQuote();
String quote = getQuote();
return "SELECT * FROM (SELECT " + alias + ".*, ROWNUM "+ quote + "RN" + quote +" FROM (" + sql + ") " + alias
+ " WHERE ROWNUM <= " + (offset + count) + ") WHERE "+ quote + "RN" + quote +" > " + offset;
}
Expand Down Expand Up @@ -4816,7 +4822,7 @@ protected String concatJoinOn(@NotNull String sql, @NotNull String quote, @NotNu
String rt = on.getRelateType();
if (StringUtil.isEmpty(rt, false)) {
sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + (isNot ? " != " : " = ")
+ quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote;
+ quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote;
}
else {
onJoinComplexRelation(sql, quote, j, jt, onList, on);
Expand All @@ -4828,7 +4834,7 @@ protected String concatJoinOn(@NotNull String sql, @NotNull String quote, @NotNu
}

sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + " " + rt + " "
+ quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote;
+ quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote;
}
else if (rt.endsWith("$")) {
String t = rt.substring(0, rt.length() - 1);
Expand Down Expand Up @@ -4874,11 +4880,11 @@ else if (l > 0 && StringUtil.isName(String.valueOf(l))) {

if (l <= 0 && r <= 0) {
sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + (isNot ? NOT : "")
+ " LIKE " + quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote;
+ " LIKE " + quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote;
}
else {
sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + (isNot ? NOT : "")
+ (l <= 0 ? " LIKE concat(" : " LIKE concat('" + l + "', ") + quote + on.getTargetTable() + quote
+ (l <= 0 ? " LIKE concat(" : " LIKE concat('" + l + "', ") + quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote
+ "." + quote + on.getTargetKey() + quote + (r <= 0 ? ")" : ", '" + r + "')");
}
}
Expand All @@ -4887,38 +4893,38 @@ else if (rt.endsWith("~")) {
if (isPostgreSQL() || isInfluxDB()) {
sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote
+ (isNot ? NOT : "") + " ~" + (ignoreCase ? "* " : " ")
+ quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote;
+ quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote;
}
else if (isOracle() || isDameng() || isKingBase()) {
sql += (first ? ON : AND) + "regexp_like(" + quote + jt + quote + "." + quote + on.getKey() + quote
+ ", " + quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote
+ ", " + quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote
+ (ignoreCase ? ", 'i'" : ", 'c'") + ")";
}
else if (isPresto() || isTrino()) {
sql += (first ? ON : AND) + "regexp_like(" + (ignoreCase ? "lower(" : "") + quote
else if (isPresto() || isTrino()) {
sql += (first ? ON : AND) + "regexp_like(" + (ignoreCase ? "lower(" : "") + quote
+ jt + quote + "." + quote + on.getKey() + quote + (ignoreCase ? ")" : "")
+ ", " + (ignoreCase ? "lower(" : "") + quote + on.getTargetTable()
+ ", " + (ignoreCase ? "lower(" : "") + quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias())
+ quote + "." + quote + on.getTargetKey() + quote + (ignoreCase ? ")" : "") + ")";
}
}
else if (isClickHouse()) {
sql += (first ? ON : AND) + "match(" + (ignoreCase ? "lower(" : "") + quote + jt
+ quote + "." + quote + on.getKey() + quote + (ignoreCase ? ")" : "")
+ ", " + (ignoreCase ? "lower(" : "") + quote + on.getTargetTable()
+ ", " + (ignoreCase ? "lower(" : "") + quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias())
+ quote + "." + quote + on.getTargetKey() + quote + (ignoreCase ? ")" : "") + ")";
}
else if (isElasticsearch()) {
sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + (isNot ? NOT : "")
+ " RLIKE " + quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote;
}
sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + (isNot ? NOT : "")
+ " RLIKE " + quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote;
}
else if (isHive()) {
sql += (first ? ON : AND) + (ignoreCase ? "lower(" : "") + quote + jt + quote + "." + quote + on.getKey() + quote + (ignoreCase ? ")" : "")
+ " REGEXP " + (ignoreCase ? "lower(" : "") + quote + on.getTargetTable()
sql += (first ? ON : AND) + (ignoreCase ? "lower(" : "") + quote + jt + quote + "." + quote + on.getKey() + quote + (ignoreCase ? ")" : "")
+ " REGEXP " + (ignoreCase ? "lower(" : "") + quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias())
+ quote + "." + quote + on.getTargetKey() + quote + (ignoreCase ? ")" : "");
}
}
else {
sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + (isNot ? NOT : "")
sql += (first ? ON : AND) + quote + jt + quote + "." + quote + on.getKey() + quote + (isNot ? NOT : "")
+ " REGEXP " + (ignoreCase ? "" : "BINARY ")
+ quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote;
+ quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote;
}
}
else if ("{}".equals(rt) || "<>".equals(rt)) {
Expand Down Expand Up @@ -4950,12 +4956,12 @@ else if ("{}".equals(rt) || "<>".equals(rt)) {
String arrKeyPath;
String itemKeyPath;
if ("{}".equals(rt)) {
arrKeyPath = quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote;
arrKeyPath = quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote;
itemKeyPath = quote + jt + quote + "." + quote + on.getKey() + quote;
}
else {
arrKeyPath = quote + jt + quote + "." + quote + on.getKey() + quote;
itemKeyPath = quote + on.getTargetTable() + quote + "." + quote + on.getTargetKey() + quote;
itemKeyPath = quote + getSQLTableWithAlias(on.getTargetTable(),on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote;
}

if (isPostgreSQL() || isInfluxDB()) { //operator does not exist: jsonb @> character varying "[" + c + "]");
Expand Down