提交 0f2737c7 编写于 作者: T terrymanu

for #2457, add ParameterRewriter

上级 01e2e827
......@@ -25,6 +25,7 @@ import org.apache.shardingsphere.core.constant.properties.ShardingPropertiesCons
import org.apache.shardingsphere.core.metadata.ShardingMetaData;
import org.apache.shardingsphere.core.rewrite.SQLRewriteEngine;
import org.apache.shardingsphere.core.rewrite.rewriter.EncryptSQLRewriter;
import org.apache.shardingsphere.core.rewrite.rewriter.ShardingParameterRewriter;
import org.apache.shardingsphere.core.rewrite.rewriter.ShardingSQLRewriter;
import org.apache.shardingsphere.core.route.RouteUnit;
import org.apache.shardingsphere.core.route.SQLLogger;
......@@ -103,9 +104,10 @@ public abstract class BaseShardingEngine {
private Collection<RouteUnit> rewriteAndConvert(final List<Object> parameters, final SQLRouteResult sqlRouteResult) {
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, sqlRouteResult.getSqlStatement(), parameters, sqlRouteResult.getRoutingResult().isSingleRouting());
ShardingParameterRewriter shardingParameterRewriter = new ShardingParameterRewriter(databaseType, sqlRouteResult);
ShardingSQLRewriter shardingSQLRewriter = new ShardingSQLRewriter(shardingRule, databaseType, sqlRouteResult, sqlRouteResult.getOptimizeResult());
EncryptSQLRewriter encryptSQLRewriter = new EncryptSQLRewriter(shardingRule.getEncryptRule().getEncryptorEngine(), sqlRouteResult.getSqlStatement(), sqlRouteResult.getOptimizeResult());
rewriteEngine.init(shardingSQLRewriter, encryptSQLRewriter);
rewriteEngine.init(shardingParameterRewriter, shardingSQLRewriter, encryptSQLRewriter);
Collection<RouteUnit> result = new LinkedHashSet<>();
for (RoutingUnit each : sqlRouteResult.getRoutingResult().getRoutingUnits()) {
result.add(new RouteUnit(each.getDataSourceName(), rewriteEngine.generateSQL(each)));
......
......@@ -23,6 +23,7 @@ import org.apache.shardingsphere.core.parse.sql.token.SQLToken;
import org.apache.shardingsphere.core.rewrite.builder.ParameterBuilder;
import org.apache.shardingsphere.core.rewrite.builder.SQLBuilder;
import org.apache.shardingsphere.core.rewrite.rewriter.BaseSQLRewriter;
import org.apache.shardingsphere.core.rewrite.rewriter.ParameterRewriter;
import org.apache.shardingsphere.core.rewrite.rewriter.SQLRewriter;
import org.apache.shardingsphere.core.rewrite.token.BaseTokenGenerateEngine;
import org.apache.shardingsphere.core.rewrite.token.EncryptTokenGenerateEngine;
......@@ -108,9 +109,13 @@ public final class SQLRewriteEngine {
/**
* Initialize SQL rewrite engine.
*
* @param parameterRewriter parameter rewriter
* @param sqlRewriters SQL rewriters
*/
public void init(final SQLRewriter... sqlRewriters) {
public void init(final ParameterRewriter parameterRewriter, final SQLRewriter... sqlRewriters) {
if (null != parameterRewriter) {
parameterRewriter.rewrite(parameterBuilder);
}
if (sqlTokens.isEmpty()) {
baseSQLRewriter.appendWholeSQL(sqlBuilder);
return;
......
......@@ -40,13 +40,16 @@ public final class ParameterBuilder {
private final List<Object> originalParameters;
private final Map<Integer, Object> assistedIndexAndParametersForUpdate;
private final Map<Integer, Object> addedIndexAndParameters;
private final Map<Integer, Object> replacedIndexAndParameters;
private final List<InsertParameterUnit> insertParameterUnits;
public ParameterBuilder(final List<Object> parameters) {
originalParameters = new LinkedList<>(parameters);
assistedIndexAndParametersForUpdate = new HashMap<>();
addedIndexAndParameters = new HashMap<>();
replacedIndexAndParameters = new HashMap<>();
insertParameterUnits = new LinkedList<>();
}
......@@ -122,9 +125,12 @@ public final class ParameterBuilder {
private List<Object> getRevisedParameters() {
List<Object> result = new LinkedList<>(originalParameters);
for (Entry<Integer, Object> entry : assistedIndexAndParametersForUpdate.entrySet()) {
for (Entry<Integer, Object> entry : addedIndexAndParameters.entrySet()) {
result.add(entry.getKey(), entry.getValue());
}
for (Entry<Integer, Object> entry : replacedIndexAndParameters.entrySet()) {
result.set(entry.getKey(), entry.getValue());
}
return result;
}
}
......@@ -30,10 +30,6 @@ import org.apache.shardingsphere.core.parse.sql.segment.dml.predicate.PredicateS
import org.apache.shardingsphere.core.parse.sql.statement.SQLStatement;
import org.apache.shardingsphere.core.parse.sql.statement.dml.UpdateStatement;
import org.apache.shardingsphere.core.parse.sql.token.SQLToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertAssistedColumnsToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertSetAddAssistedColumnsToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertSetEncryptValueToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertValuesToken;
import org.apache.shardingsphere.core.rewrite.builder.ParameterBuilder;
import org.apache.shardingsphere.core.rewrite.builder.SQLBuilder;
import org.apache.shardingsphere.core.rewrite.placeholder.InsertAssistedColumnsPlaceholder;
......@@ -46,6 +42,10 @@ import org.apache.shardingsphere.core.rewrite.placeholder.UpdateEncryptAssistedI
import org.apache.shardingsphere.core.rewrite.placeholder.UpdateEncryptItemPlaceholder;
import org.apache.shardingsphere.core.rewrite.placeholder.WhereEncryptColumnPlaceholder;
import org.apache.shardingsphere.core.rewrite.token.pojo.EncryptColumnToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertAssistedColumnsToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertSetAddAssistedColumnsToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertSetEncryptValueToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertValuesToken;
import org.apache.shardingsphere.core.rule.ColumnNode;
import org.apache.shardingsphere.core.strategy.encrypt.ShardingEncryptorEngine;
import org.apache.shardingsphere.spi.encrypt.ShardingEncryptor;
......@@ -140,7 +140,8 @@ public final class EncryptSQLRewriter implements SQLRewriter {
sqlBuilder.appendPlaceholder(new InsertSetEncryptValuePlaceholder(insertOptimizeResult.getUnits().get(0).getColumnSQLExpression(insertSetEncryptValueToken.getColumnName())));
}
private void appendInsertSetAddItemsPlaceholder(final SQLBuilder sqlBuilder, final InsertSetAddAssistedColumnsToken insertSetAddAssistedColumnsToken, final InsertOptimizeResult insertOptimizeResult) {
private void appendInsertSetAddItemsPlaceholder(
final SQLBuilder sqlBuilder, final InsertSetAddAssistedColumnsToken insertSetAddAssistedColumnsToken, final InsertOptimizeResult insertOptimizeResult) {
List<ExpressionSegment> columnValues = new LinkedList<>();
for (String each : insertSetAddAssistedColumnsToken.getColumnNames()) {
columnValues.add(insertOptimizeResult.getUnits().get(0).getColumnSQLExpression(each));
......@@ -214,7 +215,7 @@ public final class EncryptSQLRewriter implements SQLRewriter {
return getUpdateEncryptItemPlaceholder(encryptColumnToken, encryptColumnValues);
}
List<Comparable<?>> encryptAssistedColumnValues = encryptorEngine.getEncryptAssistedColumnValues(columnNode, Collections.<Comparable<?>>singletonList(originalColumnValue));
parameterBuilder.getAssistedIndexAndParametersForUpdate().putAll(getIndexAndParameters(encryptColumnToken, encryptAssistedColumnValues));
parameterBuilder.getAddedIndexAndParameters().putAll(getIndexAndParameters(encryptColumnToken, encryptAssistedColumnValues));
return getUpdateEncryptAssistedItemPlaceholder(encryptColumnToken, encryptColumnValues, encryptAssistedColumnValues);
}
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.core.rewrite.rewriter;
import org.apache.shardingsphere.core.rewrite.builder.ParameterBuilder;
/**
* Parameter rewriter.
*
* @author zhangliang
*/
public interface ParameterRewriter {
/**
* Rewrite.
*
* @param parameterBuilder parameter builder
*/
void rewrite(ParameterBuilder parameterBuilder);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.shardingsphere.core.rewrite.rewriter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.core.constant.DatabaseType;
import org.apache.shardingsphere.core.parse.sql.statement.dml.SelectStatement;
import org.apache.shardingsphere.core.rewrite.builder.ParameterBuilder;
import org.apache.shardingsphere.core.route.SQLRouteResult;
import java.util.Map;
/**
* Parameter rewriter for sharding.
*
* @author zhangliang
*/
@RequiredArgsConstructor
public final class ShardingParameterRewriter implements ParameterRewriter {
private final DatabaseType databaseType;
private final SQLRouteResult sqlRouteResult;
@Override
public void rewrite(final ParameterBuilder parameterBuilder) {
if (sqlRouteResult.getSqlStatement() instanceof SelectStatement) {
SelectStatement selectStatement = (SelectStatement) sqlRouteResult.getSqlStatement();
if (null == selectStatement.getLimit()) {
return;
}
boolean isNeedFetchAll = (!selectStatement.getGroupByItems().isEmpty() || !selectStatement.getAggregationSelectItems().isEmpty()) && !selectStatement.isSameGroupByAndOrderByItems();
Map<Integer, Object> revisedIndexAndParameters = sqlRouteResult.getLimit().getRevisedIndexAndParameters(isNeedFetchAll, databaseType.name());
parameterBuilder.getReplacedIndexAndParameters().putAll(revisedIndexAndParameters);
}
}
}
......@@ -26,7 +26,6 @@ import org.apache.shardingsphere.core.parse.sql.segment.dml.order.item.OrderByIt
import org.apache.shardingsphere.core.parse.sql.segment.dml.order.item.TextOrderByItemSegment;
import org.apache.shardingsphere.core.parse.sql.statement.dml.SelectStatement;
import org.apache.shardingsphere.core.parse.sql.token.SQLToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertSetAddGeneratedKeyToken;
import org.apache.shardingsphere.core.rewrite.builder.ParameterBuilder;
import org.apache.shardingsphere.core.rewrite.builder.SQLBuilder;
import org.apache.shardingsphere.core.rewrite.placeholder.AggregationDistinctPlaceholder;
......@@ -42,6 +41,7 @@ import org.apache.shardingsphere.core.rewrite.placeholder.TablePlaceholder;
import org.apache.shardingsphere.core.rewrite.token.pojo.AggregationDistinctToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.IndexToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertGeneratedKeyToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.InsertSetAddGeneratedKeyToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.OffsetToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.OrderByToken;
import org.apache.shardingsphere.core.rewrite.token.pojo.RowCountToken;
......@@ -186,7 +186,8 @@ public final class ShardingSQLRewriter implements SQLRewriter {
sqlBuilder.appendPlaceholder(new InsertGeneratedKeyPlaceholder(insertGeneratedKeyToken.getColumn(), insertGeneratedKeyToken.isToAddCloseParenthesis()));
}
private void appendInsertSetAddGeneratedKeyPlaceholder(final SQLBuilder sqlBuilder, final InsertSetAddGeneratedKeyToken insertSetAddGeneratedKeyToken, final InsertOptimizeResult insertOptimizeResult) {
private void appendInsertSetAddGeneratedKeyPlaceholder(
final SQLBuilder sqlBuilder, final InsertSetAddGeneratedKeyToken insertSetAddGeneratedKeyToken, final InsertOptimizeResult insertOptimizeResult) {
String columnName = insertSetAddGeneratedKeyToken.getColumnName();
sqlBuilder.appendPlaceholder(new InsertSetAddGeneratedKeyPlaceholder(columnName, insertOptimizeResult.getUnits().get(0).getColumnSQLExpression(columnName)));
}
......
......@@ -185,7 +185,7 @@ public final class EncryptSQLRewriterTest {
SQLStatement sqlStatement = encryptSQLParseEngine.parse(sql, false);
SQLRewriteEngine sqlRewriteEngine = new SQLRewriteEngine(encryptRule, sqlStatement, parameters);
OptimizeResult optimizeResult = OptimizeEngineFactory.newInstance(encryptRule, sqlStatement, parameters).optimize();
sqlRewriteEngine.init(new EncryptSQLRewriter(encryptRule.getEncryptorEngine(), sqlStatement, optimizeResult));
sqlRewriteEngine.init(null, new EncryptSQLRewriter(encryptRule.getEncryptorEngine(), sqlStatement, optimizeResult));
return sqlRewriteEngine.generateSQL();
}
}
......@@ -539,7 +539,7 @@ public final class ShardingSQLRewriterTest {
routeResult.setRoutingResult(new RoutingResult());
selectStatement.setLogicSQL("SELECT table_x.id, x.name FROM table_x x, table_y y WHERE table_x.id=? AND x.name=?");
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, routeResult.getSqlStatement(), parameters, routeResult.getRoutingResult().isSingleRouting());
rewriteEngine.init(
rewriteEngine.init(new ShardingParameterRewriter(DatabaseType.MySQL, routeResult),
new ShardingSQLRewriter(shardingRule, DatabaseType.MySQL, routeResult, null),
new EncryptSQLRewriter(shardingRule.getEncryptRule().getEncryptorEngine(), routeResult.getSqlStatement(), routeResult.getOptimizeResult()));
RoutingUnit routingUnit = new RoutingUnit("db0");
......@@ -902,7 +902,7 @@ public final class ShardingSQLRewriterTest {
private SQLRewriteEngine createSQLRewriteEngine(final DatabaseType databaseType, final List<Object> parameters) {
SQLRewriteEngine result = new SQLRewriteEngine(shardingRule, routeResult.getSqlStatement(), parameters, routeResult.getRoutingResult().isSingleRouting());
result.init(
result.init(new ShardingParameterRewriter(DatabaseType.MySQL, routeResult),
new ShardingSQLRewriter(shardingRule, databaseType, routeResult, routeResult.getOptimizeResult()),
new EncryptSQLRewriter(shardingRule.getEncryptRule().getEncryptorEngine(), routeResult.getSqlStatement(), routeResult.getOptimizeResult()));
return result;
......
......@@ -23,7 +23,9 @@ import lombok.ToString;
import org.apache.shardingsphere.core.parse.exception.SQLParsingException;
import org.apache.shardingsphere.core.util.NumberUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Limit object.
......@@ -60,15 +62,12 @@ public final class Limit {
}
/**
* Fill parameters for rewrite limit.
* Fill parameters.
*
* @param parameters parameters
* @param isFetchAll is fetch all data or not
* @param databaseType database type
* @param parameters SQL parameters
*/
public void processParameters(final List<Object> parameters, final boolean isFetchAll, final String databaseType) {
public void fillParameters(final List<Object> parameters) {
fill(parameters);
rewrite(parameters, isFetchAll, databaseType);
}
private void fill(final List<Object> parameters) {
......@@ -87,7 +86,15 @@ public final class Limit {
}
}
private void rewrite(final List<Object> parameters, final boolean isFetchAll, final String databaseType) {
/**
* Revise parameters.
*
* @param isFetchAll is fetch all data or not
* @param databaseType database type
* @return revised indexes and parameters
*/
public Map<Integer, Object> getRevisedIndexAndParameters(final boolean isFetchAll, final String databaseType) {
Map<Integer, Object> result = new HashMap<>(2, 1);
int rewriteOffset = 0;
int rewriteRowCount;
if (isFetchAll) {
......@@ -98,11 +105,12 @@ public final class Limit {
rewriteRowCount = rowCount.getValue();
}
if (null != offset && offset.getIndex() > -1) {
parameters.set(offset.getIndex(), rewriteOffset);
result.put(offset.getIndex(), rewriteOffset);
}
if (null != rowCount && rowCount.getIndex() > -1) {
parameters.set(rowCount.getIndex(), rewriteRowCount);
result.put(rowCount.getIndex(), rewriteRowCount);
}
return result;
}
/**
......
......@@ -190,9 +190,8 @@ public final class ParsingSQLRouter implements ShardingRouter {
}
private Limit createLimit(final SelectStatement selectStatement, final List<Object> parameters) {
boolean isNeedFetchAll = (!selectStatement.getGroupByItems().isEmpty() || !selectStatement.getAggregationSelectItems().isEmpty()) && !selectStatement.isSameGroupByAndOrderByItems();
Limit result = createLimit(selectStatement.getLimit());
result.processParameters(parameters, isNeedFetchAll, databaseType.name());
result.fillParameters(parameters);
return result;
}
......
......@@ -149,7 +149,7 @@ public final class EncryptPreparedStatement extends AbstractShardingPreparedStat
SQLStatement sqlStatement = connection.getParseEngine().parse(sql, true);
SQLRewriteEngine encryptSQLRewriteEngine = new SQLRewriteEngine(connection.getEncryptRule(), sqlStatement, getParameters());
OptimizeResult optimizeResult = OptimizeEngineFactory.newInstance(connection.getEncryptRule(), sqlStatement, getParameters()).optimize();
encryptSQLRewriteEngine.init(new EncryptSQLRewriter(connection.getEncryptRule().getEncryptorEngine(), sqlStatement, optimizeResult));
encryptSQLRewriteEngine.init(null, new EncryptSQLRewriter(connection.getEncryptRule().getEncryptorEngine(), sqlStatement, optimizeResult));
return encryptSQLRewriteEngine.generateSQL();
}
......
......@@ -81,7 +81,7 @@ public final class EncryptStatement extends AbstractUnsupportedOperationStatemen
SQLStatement sqlStatement = connection.getParseEngine().parse(sql, false);
SQLRewriteEngine encryptSQLRewriteEngine = new SQLRewriteEngine(connection.getEncryptRule(), sqlStatement, Collections.emptyList());
OptimizeResult optimizeResult = OptimizeEngineFactory.newInstance(connection.getEncryptRule(), sqlStatement, Collections.emptyList()).optimize();
encryptSQLRewriteEngine.init(new EncryptSQLRewriter(connection.getEncryptRule().getEncryptorEngine(), sqlStatement, optimizeResult));
encryptSQLRewriteEngine.init(null, new EncryptSQLRewriter(connection.getEncryptRule().getEncryptorEngine(), sqlStatement, optimizeResult));
return encryptSQLRewriteEngine.generateSQL().getSql();
}
......
......@@ -77,7 +77,7 @@ public final class PreparedStatementExecutorWrapper implements JDBCExecutorWrapp
private SQLRouteResult doMasterSlaveRoute(final String sql) {
SQLStatement sqlStatement = ((MasterSlaveSchema) logicSchema).getParseEngine().parse(sql, true);
SQLRewriteEngine sqlRewriteEngine = new SQLRewriteEngine(sqlStatement);
sqlRewriteEngine.init();
sqlRewriteEngine.init(null);
String rewriteSQL = sqlRewriteEngine.generateSQL().getSql();
SQLRouteResult result = new SQLRouteResult(sqlStatement);
for (String each : new MasterSlaveRouter(((MasterSlaveSchema) logicSchema).getMasterSlaveRule(), ((MasterSlaveSchema) logicSchema).getParseEngine(),
......@@ -92,7 +92,7 @@ public final class PreparedStatementExecutorWrapper implements JDBCExecutorWrapp
SQLStatement sqlStatement = encryptSchema.getEncryptSQLParseEntry().parse(sql, true);
SQLRewriteEngine sqlRewriteEngine = new SQLRewriteEngine(encryptSchema.getEncryptRule(), sqlStatement, parameters);
OptimizeResult optimizeResult = OptimizeEngineFactory.newInstance(encryptSchema.getEncryptRule(), sqlStatement, parameters).optimize();
sqlRewriteEngine.init(new EncryptSQLRewriter(encryptSchema.getEncryptRule().getEncryptorEngine(), sqlStatement, optimizeResult));
sqlRewriteEngine.init(null, new EncryptSQLRewriter(encryptSchema.getEncryptRule().getEncryptorEngine(), sqlStatement, optimizeResult));
SQLRouteResult result = new SQLRouteResult(sqlStatement);
result.getRouteUnits().add(new RouteUnit(logicSchema.getDataSources().keySet().iterator().next(), new SQLUnit(sqlRewriteEngine.generateSQL().getSql(), parameters)));
return result;
......
......@@ -78,7 +78,7 @@ public final class StatementExecutorWrapper implements JDBCExecutorWrapper {
private SQLRouteResult doMasterSlaveRoute(final String sql) {
SQLStatement sqlStatement = ((MasterSlaveSchema) logicSchema).getParseEngine().parse(sql, false);
SQLRewriteEngine sqlRewriteEngine = new SQLRewriteEngine(sqlStatement);
sqlRewriteEngine.init();
sqlRewriteEngine.init(null);
String rewriteSQL = sqlRewriteEngine.generateSQL().getSql();
SQLRouteResult result = new SQLRouteResult(sqlStatement);
for (String each : new MasterSlaveRouter(((MasterSlaveSchema) logicSchema).getMasterSlaveRule(), ((MasterSlaveSchema) logicSchema).getParseEngine(),
......@@ -93,7 +93,7 @@ public final class StatementExecutorWrapper implements JDBCExecutorWrapper {
SQLStatement sqlStatement = encryptSchema.getEncryptSQLParseEntry().parse(sql, false);
SQLRewriteEngine sqlRewriteEngine = new SQLRewriteEngine(encryptSchema.getEncryptRule(), sqlStatement, Collections.emptyList());
OptimizeResult optimizeResult = OptimizeEngineFactory.newInstance(encryptSchema.getEncryptRule(), sqlStatement, new LinkedList<>()).optimize();
sqlRewriteEngine.init(new EncryptSQLRewriter(encryptSchema.getEncryptRule().getEncryptorEngine(), sqlStatement, optimizeResult));
sqlRewriteEngine.init(null, new EncryptSQLRewriter(encryptSchema.getEncryptRule().getEncryptorEngine(), sqlStatement, optimizeResult));
SQLRouteResult result = new SQLRouteResult(sqlStatement);
result.getRouteUnits().add(new RouteUnit(logicSchema.getDataSources().keySet().iterator().next(), new SQLUnit(sqlRewriteEngine.generateSQL().getSql(), Collections.emptyList())));
return result;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册