未验证 提交 48acae5a 编写于 作者: L Liang Zhang 提交者: GitHub

Refactor shadow route module (#7277)

* Refactor shadow route module

* Refactor ShadowRouteDecorator
上级 cc4020d4
...@@ -18,9 +18,10 @@ ...@@ -18,9 +18,10 @@
package org.apache.shardingsphere.shadow.route.engine; package org.apache.shardingsphere.shadow.route.engine;
import org.apache.shardingsphere.shadow.constant.ShadowOrder; import org.apache.shardingsphere.shadow.constant.ShadowOrder;
import org.apache.shardingsphere.shadow.route.engine.judge.ShadowDataSourceJudgeEngine;
import org.apache.shardingsphere.shadow.rule.ShadowRule; import org.apache.shardingsphere.shadow.rule.ShadowRule;
import org.apache.shardingsphere.shadow.route.engine.impl.PreparedShadowDataSourceRouter; import org.apache.shardingsphere.shadow.route.engine.judge.impl.PreparedShadowDataSourceJudgeEngine;
import org.apache.shardingsphere.shadow.route.engine.impl.SimpleShadowDataSourceRouter; import org.apache.shardingsphere.shadow.route.engine.judge.impl.SimpleShadowDataSourceJudgeEngine;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext; import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement; import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DMLStatement; import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DMLStatement;
...@@ -48,18 +49,18 @@ public final class ShadowRouteDecorator implements RouteDecorator<ShadowRule> { ...@@ -48,18 +49,18 @@ public final class ShadowRouteDecorator implements RouteDecorator<ShadowRule> {
} }
private RouteContext getRouteContext(final RouteContext routeContext, final ShadowRule shadowRule) { private RouteContext getRouteContext(final RouteContext routeContext, final ShadowRule shadowRule) {
SQLStatementContext sqlStatementContext = routeContext.getSqlStatementContext(); SQLStatementContext<?> sqlStatementContext = routeContext.getSqlStatementContext();
SQLStatement sqlStatement = sqlStatementContext.getSqlStatement(); SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
RouteResult routeResult = new RouteResult(); RouteResult routeResult = new RouteResult();
List<Object> parameters = routeContext.getParameters(); List<Object> parameters = routeContext.getParameters();
if (!(sqlStatement instanceof DMLStatement)) { if (!(sqlStatement instanceof DMLStatement)) {
shadowRule.getShadowMappings().forEach((k, v) -> { shadowRule.getShadowMappings().forEach((key, value) -> {
routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(k, k), Collections.emptyList())); routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(key, key), Collections.emptyList()));
routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(v, v), Collections.emptyList())); routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(value, value), Collections.emptyList()));
}); });
return new RouteContext(sqlStatementContext, parameters, routeResult); return new RouteContext(sqlStatementContext, parameters, routeResult);
} }
if (isShadowSQL(routeContext, shadowRule)) { if (isShadow(routeContext, shadowRule)) {
shadowRule.getShadowMappings().values().forEach(each -> routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList()))); shadowRule.getShadowMappings().values().forEach(each -> routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList())));
} else { } else {
shadowRule.getShadowMappings().keySet().forEach(each -> routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList()))); shadowRule.getShadowMappings().keySet().forEach(each -> routeResult.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList())));
...@@ -79,7 +80,7 @@ public final class ShadowRouteDecorator implements RouteDecorator<ShadowRule> { ...@@ -79,7 +80,7 @@ public final class ShadowRouteDecorator implements RouteDecorator<ShadowRule> {
return routeContext; return routeContext;
} }
Collection<RouteUnit> toBeRemoved = new LinkedList<>(); Collection<RouteUnit> toBeRemoved = new LinkedList<>();
if (isShadowSQL(routeContext, shadowRule)) { if (isShadow(routeContext, shadowRule)) {
for (RouteUnit each : routeContext.getRouteResult().getRouteUnits()) { for (RouteUnit each : routeContext.getRouteResult().getRouteUnits()) {
toBeRemoved.add(each); toBeRemoved.add(each);
String shadowDataSourceName = shadowRule.getShadowMappings().get(each.getDataSourceMapper().getActualName()); String shadowDataSourceName = shadowRule.getShadowMappings().get(each.getDataSourceMapper().getActualName());
...@@ -91,12 +92,12 @@ public final class ShadowRouteDecorator implements RouteDecorator<ShadowRule> { ...@@ -91,12 +92,12 @@ public final class ShadowRouteDecorator implements RouteDecorator<ShadowRule> {
return routeContext; return routeContext;
} }
private boolean isShadowSQL(final RouteContext routeContext, final ShadowRule shadowRule) { private boolean isShadow(final RouteContext routeContext, final ShadowRule shadowRule) {
List<Object> parameters = routeContext.getParameters(); List<Object> parameters = routeContext.getParameters();
SQLStatementContext sqlStatementContext = routeContext.getSqlStatementContext(); SQLStatementContext<?> sqlStatementContext = routeContext.getSqlStatementContext();
ShadowDataSourceRouter shadowDataSourceRouter = parameters.isEmpty() ? new SimpleShadowDataSourceRouter(shadowRule, sqlStatementContext) ShadowDataSourceJudgeEngine shadowDataSourceRouter = parameters.isEmpty() ? new SimpleShadowDataSourceJudgeEngine(shadowRule, sqlStatementContext)
: new PreparedShadowDataSourceRouter(shadowRule, sqlStatementContext, parameters); : new PreparedShadowDataSourceJudgeEngine(shadowRule, sqlStatementContext, parameters);
return shadowDataSourceRouter.isShadowSQL(); return shadowDataSourceRouter.isShadow();
} }
@Override @Override
......
/*
* 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.shadow.route.engine.judge;
/**
* Shadow data source judge engine.
*/
public interface ShadowDataSourceJudgeEngine {
/**
* Judge whether shadow.
*
* @return is shadow or not
*/
boolean isShadow();
}
...@@ -15,12 +15,13 @@ ...@@ -15,12 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.shardingsphere.shadow.route.engine.impl; package org.apache.shardingsphere.shadow.route.engine.judge.impl;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.shadow.route.engine.judge.util.ShadowValueJudgeUtil;
import org.apache.shardingsphere.shadow.rule.ShadowRule; import org.apache.shardingsphere.shadow.rule.ShadowRule;
import org.apache.shardingsphere.shadow.route.engine.ShadowDataSourceRouter; import org.apache.shardingsphere.shadow.route.engine.judge.ShadowDataSourceJudgeEngine;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext; import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.binder.statement.dml.InsertStatementContext; import org.apache.shardingsphere.sql.parser.binder.statement.dml.InsertStatementContext;
import org.apache.shardingsphere.sql.parser.binder.type.WhereAvailable; import org.apache.shardingsphere.sql.parser.binder.type.WhereAvailable;
...@@ -36,26 +37,25 @@ import java.util.List; ...@@ -36,26 +37,25 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
/** /**
* Shadow judgement engine for prepared. * Prepared shadow data source judge engine.
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
public final class PreparedShadowDataSourceRouter implements ShadowDataSourceRouter { public final class PreparedShadowDataSourceJudgeEngine implements ShadowDataSourceJudgeEngine {
private final ShadowRule shadowRule; private final ShadowRule shadowRule;
private final SQLStatementContext sqlStatementContext; private final SQLStatementContext<?> sqlStatementContext;
private final List<Object> parameters; private final List<Object> parameters;
@Override @Override
public boolean isShadowSQL() { public boolean isShadow() {
if (sqlStatementContext instanceof InsertStatementContext) { if (sqlStatementContext instanceof InsertStatementContext) {
Collection<ColumnSegment> columnSegments = (((InsertStatementContext) sqlStatementContext).getSqlStatement()).getColumns(); Collection<ColumnSegment> columnSegments = (((InsertStatementContext) sqlStatementContext).getSqlStatement()).getColumns();
int count = 0; int count = 0;
for (ColumnSegment each : columnSegments) { for (ColumnSegment each : columnSegments) {
if (each.getIdentifier().getValue().equals(shadowRule.getColumn())) { if (each.getIdentifier().getValue().equals(shadowRule.getColumn())) {
Object value = parameters.get(count); return ShadowValueJudgeUtil.isShadowValue(parameters.get(count));
return isShadowField(value);
} }
count++; count++;
} }
...@@ -82,8 +82,7 @@ public final class PreparedShadowDataSourceRouter implements ShadowDataSourceRou ...@@ -82,8 +82,7 @@ public final class PreparedShadowDataSourceRouter implements ShadowDataSourceRou
Preconditions.checkArgument(each.getRightValue() instanceof PredicateCompareRightValue, "must be PredicateCompareRightValue"); Preconditions.checkArgument(each.getRightValue() instanceof PredicateCompareRightValue, "must be PredicateCompareRightValue");
PredicateCompareRightValue rightValue = (PredicateCompareRightValue) each.getRightValue(); PredicateCompareRightValue rightValue = (PredicateCompareRightValue) each.getRightValue();
int parameterMarkerIndex = ((ParameterMarkerExpressionSegment) rightValue.getExpression()).getParameterMarkerIndex(); int parameterMarkerIndex = ((ParameterMarkerExpressionSegment) rightValue.getExpression()).getParameterMarkerIndex();
Object value = parameters.get(parameterMarkerIndex); return ShadowValueJudgeUtil.isShadowValue(parameters.get(parameterMarkerIndex));
return isShadowField(value);
} }
} }
return false; return false;
......
...@@ -15,13 +15,14 @@ ...@@ -15,13 +15,14 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.shardingsphere.shadow.route.engine.impl; package org.apache.shardingsphere.shadow.route.engine.judge.impl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.shadow.rule.ShadowRule;
import org.apache.shardingsphere.shadow.condition.ShadowCondition; import org.apache.shardingsphere.shadow.condition.ShadowCondition;
import org.apache.shardingsphere.shadow.condition.ShadowConditionEngine; import org.apache.shardingsphere.shadow.condition.ShadowConditionEngine;
import org.apache.shardingsphere.shadow.route.engine.ShadowDataSourceRouter; import org.apache.shardingsphere.shadow.route.engine.judge.ShadowDataSourceJudgeEngine;
import org.apache.shardingsphere.shadow.route.engine.judge.util.ShadowValueJudgeUtil;
import org.apache.shardingsphere.shadow.rule.ShadowRule;
import org.apache.shardingsphere.sql.parser.binder.segment.insert.values.InsertValueContext; import org.apache.shardingsphere.sql.parser.binder.segment.insert.values.InsertValueContext;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext; import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.binder.statement.dml.InsertStatementContext; import org.apache.shardingsphere.sql.parser.binder.statement.dml.InsertStatementContext;
...@@ -33,17 +34,17 @@ import java.util.List; ...@@ -33,17 +34,17 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
/** /**
* Simple shadow judgement engine. * Simple shadow data source judge engine.
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
public final class SimpleShadowDataSourceRouter implements ShadowDataSourceRouter { public final class SimpleShadowDataSourceJudgeEngine implements ShadowDataSourceJudgeEngine {
private final ShadowRule shadowRule; private final ShadowRule shadowRule;
private final SQLStatementContext sqlStatementContext; private final SQLStatementContext<?> sqlStatementContext;
@Override @Override
public boolean isShadowSQL() { public boolean isShadow() {
if (sqlStatementContext instanceof InsertStatementContext) { if (sqlStatementContext instanceof InsertStatementContext) {
for (InsertValueContext each : ((InsertStatementContext) sqlStatementContext).getInsertValueContexts()) { for (InsertValueContext each : ((InsertStatementContext) sqlStatementContext).getInsertValueContexts()) {
if (judgeShadowSqlForInsert(each, (InsertStatementContext) sqlStatementContext)) { if (judgeShadowSqlForInsert(each, (InsertStatementContext) sqlStatementContext)) {
...@@ -58,7 +59,7 @@ public final class SimpleShadowDataSourceRouter implements ShadowDataSourceRoute ...@@ -58,7 +59,7 @@ public final class SimpleShadowDataSourceRouter implements ShadowDataSourceRoute
return false; return false;
} }
List<Object> values = shadowCondition.get().getValues(Collections.emptyList()); List<Object> values = shadowCondition.get().getValues(Collections.emptyList());
return !values.isEmpty() && isShadowField(values.get(0)); return !values.isEmpty() && ShadowValueJudgeUtil.isShadowValue(values.get(0));
} }
return false; return false;
} }
...@@ -69,8 +70,7 @@ public final class SimpleShadowDataSourceRouter implements ShadowDataSourceRoute ...@@ -69,8 +70,7 @@ public final class SimpleShadowDataSourceRouter implements ShadowDataSourceRoute
String columnName = descendingColumnNames.next(); String columnName = descendingColumnNames.next();
if (shadowRule.getColumn().equals(columnName)) { if (shadowRule.getColumn().equals(columnName)) {
int columnIndex = insertStatementContext.getColumnNames().indexOf(columnName); int columnIndex = insertStatementContext.getColumnNames().indexOf(columnName);
Object value = insertValueContext.getValue(columnIndex); return ShadowValueJudgeUtil.isShadowValue(insertValueContext.getValue(columnIndex));
return isShadowField(value);
} }
} }
return false; return false;
......
...@@ -15,28 +15,25 @@ ...@@ -15,28 +15,25 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.shardingsphere.shadow.route.engine; package org.apache.shardingsphere.shadow.route.engine.judge.util;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
/** /**
* Route decorator for shadow. * Shadow value judge util.
*/ */
public interface ShadowDataSourceRouter { @NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ShadowValueJudgeUtil {
/**
* Judge whether SQL is shadow.
*
* @return SQL is shadow or not
*/
boolean isShadowSQL();
/** /**
* Judge whether field is shadow. * Judge whether shadow value.
* @param value the field *
* @return field is shadow or not * @param value value to be judged
* @return is shadow value ot not
*/ */
default boolean isShadowField(final Object value) { public static boolean isShadowValue(final Object value) {
return (value instanceof Boolean && (Boolean) value) return (value instanceof Boolean && (Boolean) value)
|| (value instanceof Integer && 1 == (Integer) value) || (value instanceof Integer && 1 == (Integer) value) || (value instanceof String && Boolean.parseBoolean((String) value));
|| (value instanceof String && Boolean.parseBoolean((String) value));
} }
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.shardingsphere.shadow.route.engine.impl; package org.apache.shardingsphere.shadow.route.engine.judge.impl;
import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration; import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
import org.apache.shardingsphere.shadow.rule.ShadowRule; import org.apache.shardingsphere.shadow.rule.ShadowRule;
...@@ -49,7 +49,7 @@ public final class PreparedShadowDataSourceRouterTest { ...@@ -49,7 +49,7 @@ public final class PreparedShadowDataSourceRouterTest {
Arrays.asList(new ColumnSegment(0, 0, new IdentifierValue("id")), new ColumnSegment(0, 0, new IdentifierValue("name")), new ColumnSegment(0, 0, new IdentifierValue("shadow")))); Arrays.asList(new ColumnSegment(0, 0, new IdentifierValue("id")), new ColumnSegment(0, 0, new IdentifierValue("name")), new ColumnSegment(0, 0, new IdentifierValue("shadow"))));
insertStatement.setInsertColumns(insertColumnsSegment); insertStatement.setInsertColumns(insertColumnsSegment);
InsertStatementContext insertStatementContext = new InsertStatementContext(schemaMetaData, Arrays.asList(1, "Tom", 2, "Jerry", 3, true), insertStatement); InsertStatementContext insertStatementContext = new InsertStatementContext(schemaMetaData, Arrays.asList(1, "Tom", 2, "Jerry", 3, true), insertStatement);
PreparedShadowDataSourceRouter preparedShadowDataSourceRouter = new PreparedShadowDataSourceRouter(shadowRule, insertStatementContext, Arrays.asList(1, "Tom", true)); PreparedShadowDataSourceJudgeEngine preparedShadowDataSourceRouter = new PreparedShadowDataSourceJudgeEngine(shadowRule, insertStatementContext, Arrays.asList(1, "Tom", true));
assertTrue("should be shadow", preparedShadowDataSourceRouter.isShadowSQL()); assertTrue("should be shadow", preparedShadowDataSourceRouter.isShadow());
} }
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.shardingsphere.shadow.route.engine.impl; package org.apache.shardingsphere.shadow.route.engine.judge.impl;
import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration; import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
import org.apache.shardingsphere.shadow.rule.ShadowRule; import org.apache.shardingsphere.shadow.rule.ShadowRule;
...@@ -71,14 +71,14 @@ public final class SimpleShadowDataSourceRouterTest { ...@@ -71,14 +71,14 @@ public final class SimpleShadowDataSourceRouterTest {
insertStatement.getValues().addAll(Collections.singletonList(new InsertValuesSegment( insertStatement.getValues().addAll(Collections.singletonList(new InsertValuesSegment(
0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "name"), new LiteralExpressionSegment(0, 0, true))))); 0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "name"), new LiteralExpressionSegment(0, 0, true)))));
InsertStatementContext insertStatementContext = new InsertStatementContext(schemaMetaData, Collections.emptyList(), insertStatement); InsertStatementContext insertStatementContext = new InsertStatementContext(schemaMetaData, Collections.emptyList(), insertStatement);
SimpleShadowDataSourceRouter simpleShadowDataSourceRouter = new SimpleShadowDataSourceRouter(shadowRule, insertStatementContext); SimpleShadowDataSourceJudgeEngine simpleShadowDataSourceRouter = new SimpleShadowDataSourceJudgeEngine(shadowRule, insertStatementContext);
assertTrue("should be shadow", simpleShadowDataSourceRouter.isShadowSQL()); assertTrue("should be shadow", simpleShadowDataSourceRouter.isShadow());
insertStatement.getValues().clear(); insertStatement.getValues().clear();
insertStatement.getValues().addAll(Collections.singletonList( insertStatement.getValues().addAll(Collections.singletonList(
new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "name"), new LiteralExpressionSegment(0, 0, false))))); new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "name"), new LiteralExpressionSegment(0, 0, false)))));
insertStatementContext = new InsertStatementContext(schemaMetaData, Collections.emptyList(), insertStatement); insertStatementContext = new InsertStatementContext(schemaMetaData, Collections.emptyList(), insertStatement);
simpleShadowDataSourceRouter = new SimpleShadowDataSourceRouter(shadowRule, insertStatementContext); simpleShadowDataSourceRouter = new SimpleShadowDataSourceJudgeEngine(shadowRule, insertStatementContext);
assertFalse("should not be shadow", simpleShadowDataSourceRouter.isShadowSQL()); assertFalse("should not be shadow", simpleShadowDataSourceRouter.isShadow());
} }
@Test @Test
...@@ -95,13 +95,13 @@ public final class SimpleShadowDataSourceRouterTest { ...@@ -95,13 +95,13 @@ public final class SimpleShadowDataSourceRouterTest {
projectionsSegment.getProjections().addAll(Collections.singletonList(new ExpressionProjectionSegment(0, 0, "true"))); projectionsSegment.getProjections().addAll(Collections.singletonList(new ExpressionProjectionSegment(0, 0, "true")));
selectStatement.setProjections(projectionsSegment); selectStatement.setProjections(projectionsSegment);
SelectStatementContext selectStatementContext = new SelectStatementContext(schemaMetaData, Collections.emptyList(), selectStatement); SelectStatementContext selectStatementContext = new SelectStatementContext(schemaMetaData, Collections.emptyList(), selectStatement);
SimpleShadowDataSourceRouter simpleShadowDataSourceRouter = new SimpleShadowDataSourceRouter(shadowRule, selectStatementContext); SimpleShadowDataSourceJudgeEngine simpleShadowDataSourceRouter = new SimpleShadowDataSourceJudgeEngine(shadowRule, selectStatementContext);
assertTrue("should be shadow", simpleShadowDataSourceRouter.isShadowSQL()); assertTrue("should be shadow", simpleShadowDataSourceRouter.isShadow());
andPredicate.getPredicates().clear(); andPredicate.getPredicates().clear();
andPredicate.getPredicates().addAll(Collections.singletonList( andPredicate.getPredicates().addAll(Collections.singletonList(
new PredicateSegment(0, 0, new ColumnSegment(0, 0, new IdentifierValue("shadow")), new PredicateCompareRightValue(0, 0, "=", new LiteralExpressionSegment(0, 0, false))))); new PredicateSegment(0, 0, new ColumnSegment(0, 0, new IdentifierValue("shadow")), new PredicateCompareRightValue(0, 0, "=", new LiteralExpressionSegment(0, 0, false)))));
projectionsSegment.getProjections().clear(); projectionsSegment.getProjections().clear();
projectionsSegment.getProjections().addAll(Collections.singletonList(new ExpressionProjectionSegment(0, 0, "false"))); projectionsSegment.getProjections().addAll(Collections.singletonList(new ExpressionProjectionSegment(0, 0, "false")));
assertFalse("should not be shadow", simpleShadowDataSourceRouter.isShadowSQL()); assertFalse("should not be shadow", simpleShadowDataSourceRouter.isShadow());
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册