mirror of
https://github.com/dataease/dataease.git
synced 2026-06-13 01:01:20 +08:00
fix: 【数据集 】SQL 参数拼接报错
This commit is contained in:
@@ -77,46 +77,34 @@ public class DeSqlparserUtils {
|
||||
StringBuilder sqlItemBuilder = new StringBuilder();
|
||||
int sqlItemLastIndex = 0;
|
||||
while (m.find()) {
|
||||
if (m.start() < sqlItemLastIndex) {
|
||||
continue;
|
||||
}
|
||||
String sqlVariable = m.group();
|
||||
sqlItemBuilder.append(sqlItem, sqlItemLastIndex, m.start());
|
||||
boolean replaceParamItem = false;
|
||||
String variableName = sqlVariable.substring(2, sqlVariable.length() - 1);
|
||||
SqlVariableDetails defaultsSqlVariableDetail = findSqlVariableDetail(defaultsSqlVariableDetails, variableName);
|
||||
SqlVariableDetails filterParameter = findSqlVariableDetail(parameters, variableName);
|
||||
if (filterParameter != null) {
|
||||
PreparedSqlFragment preparedSqlFragment = buildPreparedSqlFragment(filterParameter);
|
||||
boolean quoted = isQuotedVariable(sqlItem, m.start(), m.end());
|
||||
if (quoted) {
|
||||
sqlItemBuilder.setLength(sqlItemBuilder.length() - 1);
|
||||
QuotedLiteralContext quotedLiteralContext = findQuotedLiteralContext(sqlItem, m.start(), m.end());
|
||||
int appendEnd = quotedLiteralContext == null ? m.start() : quotedLiteralContext.start();
|
||||
if (appendEnd < sqlItemLastIndex) {
|
||||
continue;
|
||||
}
|
||||
sqlItemBuilder.append(sqlItem, sqlItemLastIndex, appendEnd);
|
||||
PreparedSqlFragment preparedSqlFragment;
|
||||
if (quotedLiteralContext != null) {
|
||||
preparedSqlFragment = buildPreparedSqlFragmentForQuotedLiteral(quotedLiteralContext, parameters, isEdit, isFromDataSet);
|
||||
if (preparedSqlFragment != null) {
|
||||
sqlItemBuilder.append(preparedSqlFragment.replacement());
|
||||
sqlItemLastIndex = quotedLiteralContext.end() + 1;
|
||||
sqlItemFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaceParamItem = true;
|
||||
}
|
||||
sqlItemBuilder.append(preparedSqlFragment.replacement());
|
||||
sqlItemLastIndex = quoted ? m.end() + 1 : m.end();
|
||||
sqlItemFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaceParamItem = true;
|
||||
} else {
|
||||
if (defaultsSqlVariableDetail != null && StringUtils.isNotEmpty(defaultsSqlVariableDetail.getDefaultValue())) {
|
||||
if (!isEdit && isFromDataSet && defaultsSqlVariableDetail.getDefaultValueScope().equals(SqlVariableDetails.DefaultValueScope.ALLSCOPE)) {
|
||||
PreparedSqlFragment preparedSqlFragment = buildPreparedSqlFragmentForDefaultValue(defaultsSqlVariableDetail);
|
||||
boolean quoted = isQuotedVariable(sqlItem, m.start(), m.end());
|
||||
if (quoted) {
|
||||
sqlItemBuilder.setLength(sqlItemBuilder.length() - 1);
|
||||
}
|
||||
sqlItemBuilder.append(preparedSqlFragment.replacement());
|
||||
sqlItemLastIndex = quoted ? m.end() + 1 : m.end();
|
||||
sqlItemFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaceParamItem = true;
|
||||
}
|
||||
if (isEdit) {
|
||||
PreparedSqlFragment preparedSqlFragment = buildPreparedSqlFragmentForDefaultValue(defaultsSqlVariableDetail);
|
||||
boolean quoted = isQuotedVariable(sqlItem, m.start(), m.end());
|
||||
if (quoted) {
|
||||
sqlItemBuilder.setLength(sqlItemBuilder.length() - 1);
|
||||
}
|
||||
sqlItemBuilder.append(preparedSqlFragment.replacement());
|
||||
sqlItemLastIndex = quoted ? m.end() + 1 : m.end();
|
||||
sqlItemFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaceParamItem = true;
|
||||
}
|
||||
preparedSqlFragment = resolvePreparedSqlFragment(variableName, parameters, isEdit, isFromDataSet);
|
||||
if (preparedSqlFragment != null) {
|
||||
sqlItemBuilder.append(preparedSqlFragment.replacement());
|
||||
sqlItemLastIndex = m.end();
|
||||
sqlItemFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaceParamItem = true;
|
||||
}
|
||||
}
|
||||
if (!replaceParamItem) {
|
||||
@@ -248,6 +236,25 @@ public class DeSqlparserUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
private PreparedSqlFragment resolvePreparedSqlFragment(String variableName, List<SqlVariableDetails> parameters, boolean isEdit, boolean isFromDataSet) {
|
||||
SqlVariableDetails filterParameter = findSqlVariableDetail(parameters, variableName);
|
||||
if (filterParameter != null) {
|
||||
return buildPreparedSqlFragment(filterParameter);
|
||||
}
|
||||
SqlVariableDetails defaultsSqlVariableDetail = findSqlVariableDetail(defaultsSqlVariableDetails, variableName);
|
||||
if (shouldUseDefaultValue(defaultsSqlVariableDetail, isEdit, isFromDataSet)) {
|
||||
return buildPreparedSqlFragmentForDefaultValue(defaultsSqlVariableDetail);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean shouldUseDefaultValue(SqlVariableDetails sqlVariableDetails, boolean isEdit, boolean isFromDataSet) {
|
||||
if (sqlVariableDetails == null || StringUtils.isEmpty(sqlVariableDetails.getDefaultValue())) {
|
||||
return false;
|
||||
}
|
||||
return isEdit || isFromDataSet && sqlVariableDetails.getDefaultValueScope() == SqlVariableDetails.DefaultValueScope.ALLSCOPE;
|
||||
}
|
||||
|
||||
private boolean isQuotedVariable(String sqlItem, int start, int end) {
|
||||
return start > 0
|
||||
&& end < sqlItem.length()
|
||||
@@ -255,6 +262,118 @@ public class DeSqlparserUtils {
|
||||
&& sqlItem.charAt(end) == '\'';
|
||||
}
|
||||
|
||||
private QuotedLiteralContext findQuotedLiteralContext(String sqlItem, int start, int end) {
|
||||
int literalStart = -1;
|
||||
for (int i = 0; i < sqlItem.length(); i++) {
|
||||
if (sqlItem.charAt(i) != '\'') {
|
||||
continue;
|
||||
}
|
||||
if (literalStart < 0) {
|
||||
literalStart = i;
|
||||
continue;
|
||||
}
|
||||
if (i + 1 < sqlItem.length() && sqlItem.charAt(i + 1) == '\'') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (start > literalStart && end <= i) {
|
||||
return new QuotedLiteralContext(literalStart, i, sqlItem.substring(literalStart + 1, i));
|
||||
}
|
||||
literalStart = -1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PreparedSqlFragment buildPreparedSqlFragmentForQuotedLiteral(QuotedLiteralContext quotedLiteralContext, List<SqlVariableDetails> parameters, boolean isEdit, boolean isFromDataSet) {
|
||||
List<LiteralSegment> literalSegments = parseLiteralSegments(quotedLiteralContext.content());
|
||||
if (literalSegments.size() == 1 && literalSegments.get(0).variable()) {
|
||||
return resolvePreparedSqlFragment(literalSegments.get(0).content(), parameters, isEdit, isFromDataSet);
|
||||
}
|
||||
StringBuilder preparedValueBuilder = new StringBuilder();
|
||||
boolean hasVariable = false;
|
||||
for (LiteralSegment literalSegment : literalSegments) {
|
||||
if (!literalSegment.variable()) {
|
||||
preparedValueBuilder.append(unescapeQuotedLiteralText(literalSegment.content()));
|
||||
continue;
|
||||
}
|
||||
hasVariable = true;
|
||||
String preparedValue = resolveQuotedLiteralVariableValue(literalSegment.content(), parameters, isEdit, isFromDataSet);
|
||||
if (preparedValue == null) {
|
||||
return null;
|
||||
}
|
||||
preparedValueBuilder.append(preparedValue);
|
||||
}
|
||||
if (!hasVariable) {
|
||||
return null;
|
||||
}
|
||||
TableFieldWithValue tableFieldWithValue = new TableFieldWithValue();
|
||||
tableFieldWithValue.setFiledName(firstVariableName(literalSegments));
|
||||
tableFieldWithValue.setType(Types.VARCHAR);
|
||||
tableFieldWithValue.setColumnTypeName("VARCHAR");
|
||||
tableFieldWithValue.setValue(preparedValueBuilder.toString());
|
||||
return new PreparedSqlFragment("?", Collections.singletonList(tableFieldWithValue));
|
||||
}
|
||||
|
||||
private String resolveQuotedLiteralVariableValue(String variableName, List<SqlVariableDetails> parameters, boolean isEdit, boolean isFromDataSet) {
|
||||
List<String> preparedValues = resolvePreparedValuesForQuotedLiteral(variableName, parameters, isEdit, isFromDataSet);
|
||||
if (CollectionUtils.isEmpty(preparedValues)) {
|
||||
return null;
|
||||
}
|
||||
if (preparedValues.size() != 1) {
|
||||
DEException.throwException("SQL模板字符串仅支持单值参数");
|
||||
}
|
||||
return preparedValues.get(0);
|
||||
}
|
||||
|
||||
private List<String> resolvePreparedValuesForQuotedLiteral(String variableName, List<SqlVariableDetails> parameters, boolean isEdit, boolean isFromDataSet) {
|
||||
SqlVariableDetails filterParameter = findSqlVariableDetail(parameters, variableName);
|
||||
if (filterParameter != null) {
|
||||
return resolvePreparedValues(filterParameter);
|
||||
}
|
||||
SqlVariableDetails defaultsSqlVariableDetail = findSqlVariableDetail(defaultsSqlVariableDetails, variableName);
|
||||
if (!shouldUseDefaultValue(defaultsSqlVariableDetail, isEdit, isFromDataSet)) {
|
||||
return null;
|
||||
}
|
||||
SqlVariableDetails defaultValueDetail = new SqlVariableDetails();
|
||||
defaultValueDetail.setVariableName(defaultsSqlVariableDetail.getVariableName());
|
||||
defaultValueDetail.setType(defaultsSqlVariableDetail.getType());
|
||||
defaultValueDetail.setDeType(defaultsSqlVariableDetail.getDeType());
|
||||
defaultValueDetail.setId(defaultsSqlVariableDetail.getId());
|
||||
defaultValueDetail.setOperator(defaultsSqlVariableDetail.getOperator());
|
||||
defaultValueDetail.setValue(Collections.singletonList(defaultsSqlVariableDetail.getDefaultValue()));
|
||||
return resolvePreparedValues(defaultValueDetail);
|
||||
}
|
||||
|
||||
private List<LiteralSegment> parseLiteralSegments(String literalContent) {
|
||||
List<LiteralSegment> literalSegments = new ArrayList<>();
|
||||
Matcher matcher = Pattern.compile(sqlParamsRegex).matcher(literalContent);
|
||||
int lastIndex = 0;
|
||||
while (matcher.find()) {
|
||||
if (matcher.start() > lastIndex) {
|
||||
literalSegments.add(new LiteralSegment(false, literalContent.substring(lastIndex, matcher.start())));
|
||||
}
|
||||
literalSegments.add(new LiteralSegment(true, matcher.group().substring(2, matcher.group().length() - 1)));
|
||||
lastIndex = matcher.end();
|
||||
}
|
||||
if (lastIndex < literalContent.length()) {
|
||||
literalSegments.add(new LiteralSegment(false, literalContent.substring(lastIndex)));
|
||||
}
|
||||
return literalSegments;
|
||||
}
|
||||
|
||||
private String unescapeQuotedLiteralText(String text) {
|
||||
return StringUtils.replace(text, "''", "'");
|
||||
}
|
||||
|
||||
private String firstVariableName(List<LiteralSegment> literalSegments) {
|
||||
for (LiteralSegment literalSegment : literalSegments) {
|
||||
if (literalSegment.variable()) {
|
||||
return literalSegment.content();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PreparedSqlFragment buildPreparedSqlFragment(SqlVariableDetails sqlVariableDetails) {
|
||||
List<TableFieldWithValue> values = new ArrayList<>();
|
||||
List<String> replacements = new ArrayList<>();
|
||||
@@ -342,6 +461,12 @@ public class DeSqlparserUtils {
|
||||
private record PreparedSqlFragment(String replacement, List<TableFieldWithValue> tableFieldWithValues) {
|
||||
}
|
||||
|
||||
private record QuotedLiteralContext(int start, int end, String content) {
|
||||
}
|
||||
|
||||
private record LiteralSegment(boolean variable, String content) {
|
||||
}
|
||||
|
||||
private String handleSubstitutedSql(String sysVariableId) {
|
||||
if (userEntity != null) {
|
||||
if (sysVariableId.equalsIgnoreCase("sysParams.userId")) {
|
||||
|
||||
@@ -52,6 +52,7 @@ public class SqlparserUtils {
|
||||
private UserFormVO userEntity;
|
||||
private final List<Map<String, String>> sysParams = new ArrayList<>();
|
||||
private static final String deVariablePattern = "\\$DE_PARAM\\{(.*?)\\}";
|
||||
private List<SqlVariableDetails> defaultsSqlVariableDetails = new ArrayList<>();
|
||||
|
||||
public String handleVariableDefaultValue(String sql, String sqlVariableDetails, boolean isEdit, boolean isFromDataSet, List<SqlVariableDetails> parameters, boolean isCross, Map<Long, DatasourceSchemaDTO> dsMap, PluginManageApi pluginManage, UserFormVO userEntity) {
|
||||
return handleVariableDefaultValueWithPreparedParams(sql, sqlVariableDetails, isEdit, isFromDataSet, parameters, isCross, dsMap, pluginManage, userEntity).getSql();
|
||||
@@ -75,58 +76,43 @@ public class SqlparserUtils {
|
||||
sql = sql.substring(0, sql.length() - 1);
|
||||
}
|
||||
List<TableFieldWithValue> tableFieldWithValues = new ArrayList<>();
|
||||
defaultsSqlVariableDetails = new ArrayList<>();
|
||||
if (StringUtils.isNotEmpty(sqlVariableDetails)) {
|
||||
TypeReference<List<SqlVariableDetails>> listTypeReference = new TypeReference<List<SqlVariableDetails>>() {
|
||||
};
|
||||
List<SqlVariableDetails> defaultsSqlVariableDetails = JsonUtil.parseList(sqlVariableDetails, listTypeReference);
|
||||
defaultsSqlVariableDetails = JsonUtil.parseList(sqlVariableDetails, listTypeReference);
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(sql);
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
int lastIndex = 0;
|
||||
while (matcher.find()) {
|
||||
sqlBuilder.append(sql, lastIndex, matcher.start());
|
||||
if (matcher.start() < lastIndex) {
|
||||
continue;
|
||||
}
|
||||
String variableName = matcher.group().substring(2, matcher.group().length() - 1);
|
||||
SqlVariableDetails defaultsSqlVariableDetail = findSqlVariableDetail(defaultsSqlVariableDetails, variableName);
|
||||
SqlVariableDetails filterParameter = findSqlVariableDetail(parameters, variableName);
|
||||
QuotedLiteralContext quotedLiteralContext = findQuotedLiteralContext(sql, matcher.start(), matcher.end());
|
||||
int appendEnd = quotedLiteralContext == null ? matcher.start() : quotedLiteralContext.start();
|
||||
if (appendEnd < lastIndex) {
|
||||
continue;
|
||||
}
|
||||
sqlBuilder.append(sql, lastIndex, appendEnd);
|
||||
boolean replaced = false;
|
||||
if (filterParameter != null) {
|
||||
PreparedSqlFragment preparedSqlFragment = buildPreparedSqlFragment(filterParameter);
|
||||
boolean quoted = isQuotedVariable(sql, matcher.start(), matcher.end());
|
||||
if (quoted) {
|
||||
sqlBuilder.setLength(sqlBuilder.length() - 1);
|
||||
PreparedSqlFragment preparedSqlFragment;
|
||||
if (quotedLiteralContext != null) {
|
||||
preparedSqlFragment = buildPreparedSqlFragmentForQuotedLiteral(quotedLiteralContext, parameters, isEdit, isFromDataSet);
|
||||
if (preparedSqlFragment != null) {
|
||||
sqlBuilder.append(preparedSqlFragment.replacement());
|
||||
lastIndex = quotedLiteralContext.end() + 1;
|
||||
tableFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaced = true;
|
||||
}
|
||||
sqlBuilder.append(preparedSqlFragment.replacement());
|
||||
if (quoted) {
|
||||
lastIndex = matcher.end() + 1;
|
||||
} else {
|
||||
lastIndex = matcher.end();
|
||||
}
|
||||
tableFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaced = true;
|
||||
} else {
|
||||
if (defaultsSqlVariableDetail != null && StringUtils.isNotEmpty(defaultsSqlVariableDetail.getDefaultValue())) {
|
||||
if (!isEdit && isFromDataSet && defaultsSqlVariableDetail.getDefaultValueScope().equals(SqlVariableDetails.DefaultValueScope.ALLSCOPE)) {
|
||||
PreparedSqlFragment preparedSqlFragment = buildPreparedSqlFragmentForDefaultValue(defaultsSqlVariableDetail);
|
||||
boolean quoted = isQuotedVariable(sql, matcher.start(), matcher.end());
|
||||
if (quoted) {
|
||||
sqlBuilder.setLength(sqlBuilder.length() - 1);
|
||||
}
|
||||
sqlBuilder.append(preparedSqlFragment.replacement());
|
||||
lastIndex = quoted ? matcher.end() + 1 : matcher.end();
|
||||
tableFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaced = true;
|
||||
}
|
||||
if (isEdit) {
|
||||
PreparedSqlFragment preparedSqlFragment = buildPreparedSqlFragmentForDefaultValue(defaultsSqlVariableDetail);
|
||||
boolean quoted = isQuotedVariable(sql, matcher.start(), matcher.end());
|
||||
if (quoted) {
|
||||
sqlBuilder.setLength(sqlBuilder.length() - 1);
|
||||
}
|
||||
sqlBuilder.append(preparedSqlFragment.replacement());
|
||||
lastIndex = quoted ? matcher.end() + 1 : matcher.end();
|
||||
tableFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaced = true;
|
||||
}
|
||||
preparedSqlFragment = resolvePreparedSqlFragment(variableName, parameters, isEdit, isFromDataSet);
|
||||
if (preparedSqlFragment != null) {
|
||||
sqlBuilder.append(preparedSqlFragment.replacement());
|
||||
lastIndex = matcher.end();
|
||||
tableFieldWithValues.addAll(preparedSqlFragment.tableFieldWithValues());
|
||||
replaced = true;
|
||||
}
|
||||
}
|
||||
if (!replaced) {
|
||||
@@ -735,6 +721,25 @@ public class SqlparserUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
private PreparedSqlFragment resolvePreparedSqlFragment(String variableName, List<SqlVariableDetails> parameters, boolean isEdit, boolean isFromDataSet) {
|
||||
SqlVariableDetails filterParameter = findSqlVariableDetail(parameters, variableName);
|
||||
if (filterParameter != null) {
|
||||
return buildPreparedSqlFragment(filterParameter);
|
||||
}
|
||||
SqlVariableDetails defaultsSqlVariableDetail = findSqlVariableDetail(defaultsSqlVariableDetails, variableName);
|
||||
if (shouldUseDefaultValue(defaultsSqlVariableDetail, isEdit, isFromDataSet)) {
|
||||
return buildPreparedSqlFragmentForDefaultValue(defaultsSqlVariableDetail);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean shouldUseDefaultValue(SqlVariableDetails sqlVariableDetails, boolean isEdit, boolean isFromDataSet) {
|
||||
if (sqlVariableDetails == null || StringUtils.isEmpty(sqlVariableDetails.getDefaultValue())) {
|
||||
return false;
|
||||
}
|
||||
return isEdit || isFromDataSet && sqlVariableDetails.getDefaultValueScope() == SqlVariableDetails.DefaultValueScope.ALLSCOPE;
|
||||
}
|
||||
|
||||
private boolean isQuotedVariable(String sql, int start, int end) {
|
||||
return start > 0
|
||||
&& end < sql.length()
|
||||
@@ -742,6 +747,118 @@ public class SqlparserUtils {
|
||||
&& sql.charAt(end) == '\'';
|
||||
}
|
||||
|
||||
private QuotedLiteralContext findQuotedLiteralContext(String sql, int start, int end) {
|
||||
int literalStart = -1;
|
||||
for (int i = 0; i < sql.length(); i++) {
|
||||
if (sql.charAt(i) != '\'') {
|
||||
continue;
|
||||
}
|
||||
if (literalStart < 0) {
|
||||
literalStart = i;
|
||||
continue;
|
||||
}
|
||||
if (i + 1 < sql.length() && sql.charAt(i + 1) == '\'') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (start > literalStart && end <= i) {
|
||||
return new QuotedLiteralContext(literalStart, i, sql.substring(literalStart + 1, i));
|
||||
}
|
||||
literalStart = -1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PreparedSqlFragment buildPreparedSqlFragmentForQuotedLiteral(QuotedLiteralContext quotedLiteralContext, List<SqlVariableDetails> parameters, boolean isEdit, boolean isFromDataSet) {
|
||||
List<LiteralSegment> literalSegments = parseLiteralSegments(quotedLiteralContext.content());
|
||||
if (literalSegments.size() == 1 && literalSegments.get(0).variable()) {
|
||||
return resolvePreparedSqlFragment(literalSegments.get(0).content(), parameters, isEdit, isFromDataSet);
|
||||
}
|
||||
StringBuilder preparedValueBuilder = new StringBuilder();
|
||||
boolean hasVariable = false;
|
||||
for (LiteralSegment literalSegment : literalSegments) {
|
||||
if (!literalSegment.variable()) {
|
||||
preparedValueBuilder.append(unescapeQuotedLiteralText(literalSegment.content()));
|
||||
continue;
|
||||
}
|
||||
hasVariable = true;
|
||||
String preparedValue = resolveQuotedLiteralVariableValue(literalSegment.content(), parameters, isEdit, isFromDataSet);
|
||||
if (preparedValue == null) {
|
||||
return null;
|
||||
}
|
||||
preparedValueBuilder.append(preparedValue);
|
||||
}
|
||||
if (!hasVariable) {
|
||||
return null;
|
||||
}
|
||||
TableFieldWithValue tableFieldWithValue = new TableFieldWithValue();
|
||||
tableFieldWithValue.setFiledName(firstVariableName(literalSegments));
|
||||
tableFieldWithValue.setType(Types.VARCHAR);
|
||||
tableFieldWithValue.setColumnTypeName("VARCHAR");
|
||||
tableFieldWithValue.setValue(preparedValueBuilder.toString());
|
||||
return new PreparedSqlFragment("?", Collections.singletonList(tableFieldWithValue));
|
||||
}
|
||||
|
||||
private String resolveQuotedLiteralVariableValue(String variableName, List<SqlVariableDetails> parameters, boolean isEdit, boolean isFromDataSet) {
|
||||
List<String> preparedValues = resolvePreparedValuesForQuotedLiteral(variableName, parameters, isEdit, isFromDataSet);
|
||||
if (CollectionUtils.isEmpty(preparedValues)) {
|
||||
return null;
|
||||
}
|
||||
if (preparedValues.size() != 1) {
|
||||
DEException.throwException("SQL模板字符串仅支持单值参数");
|
||||
}
|
||||
return preparedValues.get(0);
|
||||
}
|
||||
|
||||
private List<String> resolvePreparedValuesForQuotedLiteral(String variableName, List<SqlVariableDetails> parameters, boolean isEdit, boolean isFromDataSet) {
|
||||
SqlVariableDetails filterParameter = findSqlVariableDetail(parameters, variableName);
|
||||
if (filterParameter != null) {
|
||||
return resolvePreparedValues(filterParameter);
|
||||
}
|
||||
SqlVariableDetails defaultsSqlVariableDetail = findSqlVariableDetail(defaultsSqlVariableDetails, variableName);
|
||||
if (!shouldUseDefaultValue(defaultsSqlVariableDetail, isEdit, isFromDataSet)) {
|
||||
return null;
|
||||
}
|
||||
SqlVariableDetails defaultValueDetail = new SqlVariableDetails();
|
||||
defaultValueDetail.setVariableName(defaultsSqlVariableDetail.getVariableName());
|
||||
defaultValueDetail.setType(defaultsSqlVariableDetail.getType());
|
||||
defaultValueDetail.setDeType(defaultsSqlVariableDetail.getDeType());
|
||||
defaultValueDetail.setId(defaultsSqlVariableDetail.getId());
|
||||
defaultValueDetail.setOperator(defaultsSqlVariableDetail.getOperator());
|
||||
defaultValueDetail.setValue(Collections.singletonList(defaultsSqlVariableDetail.getDefaultValue()));
|
||||
return resolvePreparedValues(defaultValueDetail);
|
||||
}
|
||||
|
||||
private List<LiteralSegment> parseLiteralSegments(String literalContent) {
|
||||
List<LiteralSegment> literalSegments = new ArrayList<>();
|
||||
Matcher matcher = Pattern.compile(regex).matcher(literalContent);
|
||||
int lastIndex = 0;
|
||||
while (matcher.find()) {
|
||||
if (matcher.start() > lastIndex) {
|
||||
literalSegments.add(new LiteralSegment(false, literalContent.substring(lastIndex, matcher.start())));
|
||||
}
|
||||
literalSegments.add(new LiteralSegment(true, matcher.group().substring(2, matcher.group().length() - 1)));
|
||||
lastIndex = matcher.end();
|
||||
}
|
||||
if (lastIndex < literalContent.length()) {
|
||||
literalSegments.add(new LiteralSegment(false, literalContent.substring(lastIndex)));
|
||||
}
|
||||
return literalSegments;
|
||||
}
|
||||
|
||||
private String unescapeQuotedLiteralText(String text) {
|
||||
return StringUtils.replace(text, "''", "'");
|
||||
}
|
||||
|
||||
private String firstVariableName(List<LiteralSegment> literalSegments) {
|
||||
for (LiteralSegment literalSegment : literalSegments) {
|
||||
if (literalSegment.variable()) {
|
||||
return literalSegment.content();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PreparedSqlFragment buildPreparedSqlFragment(SqlVariableDetails sqlVariableDetails) {
|
||||
List<TableFieldWithValue> values = new ArrayList<>();
|
||||
List<String> replacements = new ArrayList<>();
|
||||
@@ -829,6 +946,12 @@ public class SqlparserUtils {
|
||||
private record PreparedSqlFragment(String replacement, List<TableFieldWithValue> tableFieldWithValues) {
|
||||
}
|
||||
|
||||
private record QuotedLiteralContext(int start, int end, String content) {
|
||||
}
|
||||
|
||||
private record LiteralSegment(boolean variable, String content) {
|
||||
}
|
||||
|
||||
private String handleSubstitutedSql(String sql) {
|
||||
if (sql.contains(SysParamsSubstitutedParams) && userEntity != null) {
|
||||
sql = sql.replace(SysParamsSubstitutedParams + "sysParams.userId", userEntity.getAccount());
|
||||
|
||||
Reference in New Issue
Block a user