(improvement)[chat] Skip the corrector for complex SQL, and do not add the HAVING field to the SELECT clause (#1754)

This commit is contained in:
lexluo09
2024-10-09 14:38:12 +08:00
committed by GitHub
parent 3ea3c93dc6
commit fc040970b2
9 changed files with 150 additions and 61 deletions

View File

@@ -12,11 +12,28 @@ import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
public class SqlAsHelper {
private static void extractAliasesFromSelect(PlainSelect plainSelect, Set<String> aliases) {
// Extract aliases from SELECT items
for (SelectItem selectItem : plainSelect.getSelectItems()) {
Alias alias = selectItem.getAlias();
if (alias != null) {
aliases.add(alias.getName());
}
}
FunctionAliasVisitor visitor = new FunctionAliasVisitor(aliases);
for (SelectItem selectItem : plainSelect.getSelectItems()) {
selectItem.accept(visitor);
}
}
public static List<String> getAsFields(String sql) {
List<PlainSelect> plainSelectList = SqlSelectHelper.getPlainSelect(sql);
if (CollectionUtils.isEmpty(plainSelectList)) {
@@ -43,17 +60,14 @@ public class SqlAsHelper {
return new ArrayList<>(aliases);
}
private static void extractAliasesFromSelect(PlainSelect plainSelect, Set<String> aliases) {
// Extract aliases from SELECT items
for (SelectItem selectItem : plainSelect.getSelectItems()) {
Alias alias = selectItem.getAlias();
if (alias != null) {
aliases.add(alias.getName());
}
}
FunctionAliasVisitor visitor = new FunctionAliasVisitor(aliases);
for (SelectItem selectItem : plainSelect.getSelectItems()) {
selectItem.accept(visitor);
}
public static Map<String, String> getFieldMapFilterByAsFields(String sql,
Map<String, String> fieldNameMap) {
// Delete aliases if they exist
List<String> asFields = SqlAsHelper.getAsFields(sql);
Set<String> asFieldsSet = new HashSet<>(asFields);
fieldNameMap = fieldNameMap.entrySet().stream()
.filter(entry -> !asFieldsSet.contains(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return fieldNameMap;
}
}

View File

@@ -43,7 +43,9 @@ import java.util.Objects;
import java.util.Set;
import java.util.function.UnaryOperator;
/** Sql Parser replace Helper */
/**
* Sql Parser replace Helper
*/
@Slf4j
public class SqlReplaceHelper {
public static String replaceAggFields(String sql,
@@ -180,6 +182,8 @@ public class SqlReplaceHelper {
return selectStatement.toString();
}
private static void replaceFieldsInPlainOneSelect(Map<String, String> fieldNameMap,
boolean exactReplace, PlainSelect plainSelect) {
// 1. replace where fields

View File

@@ -2,11 +2,14 @@ package com.tencent.supersonic.common.jsqlparser;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.select.PlainSelect;
import org.apache.commons.collections.CollectionUtils;
import java.util.List;
/** Sql Parser valid Helper */
/**
* Sql Parser valid Helper
*/
@Slf4j
public class SqlValidHelper {
@@ -75,4 +78,9 @@ public class SqlValidHelper {
return false;
}
}
public static boolean isComplexSQL(String sql) {
List<PlainSelect> plainSelect = SqlSelectHelper.getPlainSelect(sql);
return !CollectionUtils.isEmpty(plainSelect) && plainSelect.size() >= 2;
}
}

View File

@@ -61,4 +61,54 @@ class SqlValidHelperTest {
Assert.assertEquals(SqlValidHelper.isValidSQL(sql1), false);
}
@Test
void testIsComplexSQL() {
String sql1 = "SELECT * FROM table1 WHERE column1 = 1 AND column2 = 2";
Assert.assertEquals(SqlValidHelper.isComplexSQL(sql1), false);
sql1 = "SELECT\n" + " COUNT(部门)\n" + "FROM\n" + " (\n" + " SELECT\n" + " 部门,\n"
+ " COUNT(DISTINCT 用户) AS UV\n" + " FROM\n" + " 超音数数据集\n"
+ " WHERE\n" + " 数据日期 >= '2024-09-08'\n"
+ " AND 数据日期 <= '2024-10-08'\n" + " GROUP BY\n" + " 部门\n"
+ " HAVING\n" + " COUNT(DISTINCT 用户) > 2\n" + " ) AS subquery";
Assert.assertEquals(SqlValidHelper.isComplexSQL(sql1), true);
sql1 = "SELECT\n" + " COUNT(部门)\n" + "FROM\n" + " (\n" + " SELECT\n" + " 部门,\n"
+ " COUNT(DISTINCT 用户) AS UV\n" + " FROM\n" + " 超音数数据集\n"
+ " WHERE\n" + " 数据日期 >= '2024-09-08'\n"
+ " AND 数据日期 <= '2024-10-08'\n" + " GROUP BY\n" + " 部门\n"
+ " HAVING\n" + " COUNT(DISTINCT 用户) > 2\n" + " ) AS subquery";
Assert.assertEquals(SqlValidHelper.isComplexSQL(sql1), true);
sql1 = " SELECT\n" + " `t6`.`sys_imp_date`,\n" + " `t5`.`department`,\n"
+ " `t6`.`s2_pv_uv_statis_pv` AS `pv`\n" + " FROM\n" + " (\n"
+ " SELECT\n" + " `user_name`,\n" + " `department`\n"
+ " FROM\n" + " `s2_user_department`\n" + " ) AS `t5`\n"
+ " LEFT JOIN (\n" + " SELECT\n"
+ " 1 AS `s2_pv_uv_statis_pv`,\n"
+ " `imp_date` AS `sys_imp_date`,\n" + " `user_name`\n"
+ " FROM\n" + " `s2_pv_uv_statis`\n"
+ " ) AS `t6` ON `t5`.`user_name` = `t6`.`user_name`";
Assert.assertEquals(SqlValidHelper.isComplexSQL(sql1), true);
sql1 = " SELECT\n" + " `t6`.`sys_imp_date`,\n" + " `t5`.`department`,\n"
+ " `t6`.`s2_pv_uv_statis_pv` AS `pv`\n" + " FROM\n" + " (\n"
+ " SELECT\n" + " `user_name`,\n" + " `department`\n"
+ " FROM\n" + " `s2_user_department`\n" + " ) AS `t5`\n"
+ " LEFT JOIN (\n" + " SELECT\n"
+ " 1 AS `s2_pv_uv_statis_pv`,\n"
+ " `imp_date` AS `sys_imp_date`,\n" + " `user_name`\n"
+ " FROM\n" + " `s2_pv_uv_statis`\n"
+ " ) AS `t6` ON `t5`.`user_name` = `t6`.`user_name`";
Assert.assertEquals(SqlValidHelper.isComplexSQL(sql1), true);
sql1 = "WITH\n" + " UserCounts AS (\n" + " SELECT\n" + " 部门,\n"
+ " COUNT(DISTINCT 用户) AS UV\n" + " FROM\n" + " 超音数数据集\n"
+ " WHERE\n" + " 数据日期 >= '2024-09-08'\n"
+ " AND 数据日期 <= '2024-10-08'\n" + " GROUP BY\n" + " 部门\n" + " )\n"
+ "SELECT\n" + " COUNT(*)\n" + "FROM\n" + " UserCounts\n" + "WHERE\n"
+ " count(UV) > 2";
Assert.assertEquals(SqlValidHelper.isComplexSQL(sql1), true);
}
}