diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingRuleConfigurationChecker.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingRuleConfigurationChecker.java index ed9fb2a2a9bf7..984a472bb0932 100644 --- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingRuleConfigurationChecker.java +++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingRuleConfigurationChecker.java @@ -79,7 +79,7 @@ private void checkDataSources(final String databaseName, final Map dataSourceMap, final Collection addedWriteDataSourceNames, final ReadwriteSplittingDataSourceRuleConfiguration config, final Collection rules) { - for (String each : InlineExpressionParserFactory.newInstance().splitAndEvaluate(config.getWriteDataSourceName())) { + for (String each : InlineExpressionParserFactory.newInstance(config.getWriteDataSourceName()).splitAndEvaluate()) { ShardingSpherePreconditions.checkState(dataSourceMap.containsKey(each) || containsInOtherRules(each, rules), () -> new DataSourceNameExistedException(String.format("Write data source name `%s` not in database `%s`.", each, databaseName))); ShardingSpherePreconditions.checkState(addedWriteDataSourceNames.add(each), @@ -97,7 +97,7 @@ private boolean containsInOtherRules(final String datasourceName, final Collecti } private void checkReadeDataSourceNames(final String databaseName, final Map dataSourceMap, final Collection addedReadDataSourceNames, final String readDataSourceName) { - for (String each : InlineExpressionParserFactory.newInstance().splitAndEvaluate(readDataSourceName)) { + for (String each : InlineExpressionParserFactory.newInstance(readDataSourceName).splitAndEvaluate()) { ShardingSpherePreconditions.checkState(dataSourceMap.containsKey(each), () -> new DataSourceNameExistedException(String.format("Read data source name `%s` not in database `%s`.", each, databaseName))); ShardingSpherePreconditions.checkState(addedReadDataSourceNames.add(each), diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java index db9bad0d7374d..68ec5cb426756 100644 --- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java +++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java @@ -103,10 +103,10 @@ private Map createDataSourceRules(fina private Map createStaticDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config, final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) { - List inlineReadwriteDataSourceNames = InlineExpressionParserFactory.newInstance().splitAndEvaluate(config.getName()); - List inlineWriteDatasourceNames = InlineExpressionParserFactory.newInstance().splitAndEvaluate(config.getWriteDataSourceName()); + List inlineReadwriteDataSourceNames = InlineExpressionParserFactory.newInstance(config.getName()).splitAndEvaluate(); + List inlineWriteDatasourceNames = InlineExpressionParserFactory.newInstance(config.getWriteDataSourceName()).splitAndEvaluate(); List> inlineReadDatasourceNames = config.getReadDataSourceNames().stream() - .map(each -> InlineExpressionParserFactory.newInstance().splitAndEvaluate(each)).collect(Collectors.toList()); + .map(each -> InlineExpressionParserFactory.newInstance(each).splitAndEvaluate()).collect(Collectors.toList()); ShardingSpherePreconditions.checkState(inlineWriteDatasourceNames.size() == inlineReadwriteDataSourceNames.size(), () -> new InvalidInlineExpressionDataSourceNameException("Inline expression write data source names size error.")); inlineReadDatasourceNames.forEach(each -> ShardingSpherePreconditions.checkState(each.size() == inlineReadwriteDataSourceNames.size(), diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java index 1d0ba06f06713..1f52b6980fa1a 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/hint/HintInlineShardingAlgorithm.java @@ -51,7 +51,7 @@ public void init(final Properties props) { private String getAlgorithmExpression(final Properties props) { String algorithmExpression = props.getProperty(ALGORITHM_EXPRESSION_KEY, DEFAULT_ALGORITHM_EXPRESSION); ShardingSpherePreconditions.checkNotNull(algorithmExpression, () -> new ShardingAlgorithmInitializationException(getType(), "Inline sharding algorithm expression can not be null.")); - return InlineExpressionParserFactory.newInstance().handlePlaceHolder(algorithmExpression.trim()); + return InlineExpressionParserFactory.newInstance(algorithmExpression.trim()).handlePlaceHolder(); } @Override @@ -67,7 +67,7 @@ private String doSharding(final Comparable shardingValue) { } private Closure createClosure() { - Closure result = InlineExpressionParserFactory.newInstance().evaluateClosure(algorithmExpression).rehydrate(new Expando(), null, null); + Closure result = InlineExpressionParserFactory.newInstance(algorithmExpression).evaluateClosure().rehydrate(new Expando(), null, null); result.setResolveStrategy(Closure.DELEGATE_ONLY); return result; } diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/ComplexInlineShardingAlgorithm.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/ComplexInlineShardingAlgorithm.java index e9d81087cc6ed..22042132704de 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/ComplexInlineShardingAlgorithm.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/ComplexInlineShardingAlgorithm.java @@ -67,7 +67,7 @@ private String getAlgorithmExpression(final Properties props) { String algorithmExpression = props.getProperty(ALGORITHM_EXPRESSION_KEY); ShardingSpherePreconditions.checkState(!Strings.isNullOrEmpty(algorithmExpression), () -> new ShardingAlgorithmInitializationException(getType(), "Inline sharding algorithm expression can not be null.")); - return InlineExpressionParserFactory.newInstance().handlePlaceHolder(algorithmExpression.trim()); + return InlineExpressionParserFactory.newInstance(algorithmExpression.trim()).handlePlaceHolder(); } private Collection getShardingColumns(final Properties props) { @@ -132,7 +132,7 @@ private Collection>> flatten(final Collection createClosure() { - Closure result = InlineExpressionParserFactory.newInstance().evaluateClosure(algorithmExpression).rehydrate(new Expando(), null, null); + Closure result = InlineExpressionParserFactory.newInstance(algorithmExpression).evaluateClosure().rehydrate(new Expando(), null, null); result.setResolveStrategy(Closure.DELEGATE_ONLY); return result; } diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/InlineShardingAlgorithm.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/InlineShardingAlgorithm.java index 593b1a02663d1..84c1ba83c87d5 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/InlineShardingAlgorithm.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/algorithm/sharding/inline/InlineShardingAlgorithm.java @@ -58,7 +58,7 @@ private String getAlgorithmExpression(final Properties props) { String expression = props.getProperty(ALGORITHM_EXPRESSION_KEY); ShardingSpherePreconditions.checkState(!Strings.isNullOrEmpty(expression), () -> new ShardingAlgorithmInitializationException(getType(), "Inline sharding algorithm expression cannot be null or empty")); - return InlineExpressionParserFactory.newInstance().handlePlaceHolder(expression.trim()); + return InlineExpressionParserFactory.newInstance(expression.trim()).handlePlaceHolder(); } private boolean isAllowRangeQuery(final Properties props) { @@ -83,7 +83,7 @@ public Collection doSharding(final Collection availableTargetNam } private Closure createClosure() { - Closure result = InlineExpressionParserFactory.newInstance().evaluateClosure(algorithmExpression).rehydrate(new Expando(), null, null); + Closure result = InlineExpressionParserFactory.newInstance(algorithmExpression).evaluateClosure().rehydrate(new Expando(), null, null); result.setResolveStrategy(Closure.DELEGATE_ONLY); return result; } diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java index 17d9d126e79bb..cd35c79d0824a 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java @@ -197,12 +197,12 @@ private Collection getDataSourceNames(final Collection getDataSourceNames(final ShardingAutoTableRuleConfiguration shardingAutoTableRuleConfig) { - List actualDataSources = InlineExpressionParserFactory.newInstance().splitAndEvaluate(shardingAutoTableRuleConfig.getActualDataSources()); + List actualDataSources = InlineExpressionParserFactory.newInstance(shardingAutoTableRuleConfig.getActualDataSources()).splitAndEvaluate(); return new HashSet<>(actualDataSources); } private Collection getDataSourceNames(final ShardingTableRuleConfiguration shardingTableRuleConfig) { - List actualDataNodes = InlineExpressionParserFactory.newInstance().splitAndEvaluate(shardingTableRuleConfig.getActualDataNodes()); + List actualDataNodes = InlineExpressionParserFactory.newInstance(shardingTableRuleConfig.getActualDataNodes()).splitAndEvaluate(); return actualDataNodes.stream().map(each -> new DataNode(each).getDataSourceName()).collect(Collectors.toList()); } diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/TableRule.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/TableRule.java index ea7c5af15c883..429ad42d83e45 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/TableRule.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/TableRule.java @@ -106,7 +106,7 @@ public TableRule(final Collection dataSourceNames, final String logicTab public TableRule(final ShardingTableRuleConfiguration tableRuleConfig, final Collection dataSourceNames, final String defaultGenerateKeyColumn) { logicTable = tableRuleConfig.getLogicTable(); - List dataNodes = InlineExpressionParserFactory.newInstance().splitAndEvaluate(tableRuleConfig.getActualDataNodes()); + List dataNodes = InlineExpressionParserFactory.newInstance(tableRuleConfig.getActualDataNodes()).splitAndEvaluate(); dataNodeIndexMap = new HashMap<>(dataNodes.size(), 1F); actualDataNodes = isEmptyDataNodes(dataNodes) ? generateDataNodes(tableRuleConfig.getLogicTable(), dataSourceNames) : generateDataNodes(dataNodes, dataSourceNames); actualTables = getActualTables(); @@ -158,7 +158,7 @@ private List getDataNodes(final ShardingAutoTableRuleConfiguration table return new LinkedList<>(); } List dataSources = Strings.isNullOrEmpty(tableRuleConfig.getActualDataSources()) ? new LinkedList<>(dataSourceNames) - : InlineExpressionParserFactory.newInstance().splitAndEvaluate(tableRuleConfig.getActualDataSources()); + : InlineExpressionParserFactory.newInstance(tableRuleConfig.getActualDataSources()).splitAndEvaluate(); return DataNodeUtils.getFormatDataNodes(shardingAlgorithm.getAutoTablesAmount(), logicTable, dataSources); } diff --git a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java index cfefac1e9c4cc..70abf9cdee3e8 100644 --- a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java +++ b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java @@ -179,13 +179,13 @@ private static Collection getDataSourceNames(final Collection result = new LinkedHashSet<>(); tableRuleConfigs.forEach(each -> result.addAll(getDataSourceNames(each))); - autoTableRuleConfigs.forEach(each -> result.addAll(InlineExpressionParserFactory.newInstance().splitAndEvaluate(each.getActualDataSources()))); + autoTableRuleConfigs.forEach(each -> result.addAll(InlineExpressionParserFactory.newInstance(each.getActualDataSources()).splitAndEvaluate())); return result; } private static Collection getDataSourceNames(final ShardingTableRuleConfiguration shardingTableRuleConfig) { - return InlineExpressionParserFactory.newInstance() - .splitAndEvaluate(shardingTableRuleConfig.getActualDataNodes()).stream().map(each -> new DataNode(each).getDataSourceName()).collect(Collectors.toList()); + return InlineExpressionParserFactory.newInstance(shardingTableRuleConfig.getActualDataNodes()) + .splitAndEvaluate().stream().map(each -> new DataNode(each).getDataSourceName()).collect(Collectors.toList()); } private static Collection getDataSourceNames(final Collection actualDataNodes) { @@ -316,7 +316,7 @@ private static Collection getRequiredDataSources(final ShardingRuleConfi Collection result = new LinkedHashSet<>(); result.addAll(config.getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getActualDataSources) .map(each -> Splitter.on(",").trimResults().splitToList(each)).flatMap(Collection::stream).collect(Collectors.toSet())); - result.addAll(config.getTables().stream().map(each -> InlineExpressionParserFactory.newInstance().splitAndEvaluate(each.getActualDataNodes())) + result.addAll(config.getTables().stream().map(each -> InlineExpressionParserFactory.newInstance(each.getActualDataNodes()).splitAndEvaluate()) .flatMap(Collection::stream).distinct().map(each -> new DataNode(each).getDataSourceName()).collect(Collectors.toSet())); return result; } @@ -327,7 +327,7 @@ private static Collection getRequir } private static Collection parseDateSource(final String dateSource) { - return InlineExpressionParserFactory.newInstance().splitAndEvaluate(dateSource); + return InlineExpressionParserFactory.newInstance(dateSource).splitAndEvaluate(); } private static Collection getLogicDataSources(final ShardingSphereDatabase database) { diff --git a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/fixture/sharding/CoreHintShardingAlgorithmFixture.java b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/fixture/sharding/CoreHintShardingAlgorithmFixture.java index 40c8865786def..671a4b1d9468f 100644 --- a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/fixture/sharding/CoreHintShardingAlgorithmFixture.java +++ b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/fixture/sharding/CoreHintShardingAlgorithmFixture.java @@ -46,7 +46,7 @@ public void init(final Properties props) { private String getAlgorithmExpression(final Properties props) { String algorithmExpression = props.getProperty(ALGORITHM_EXPRESSION_KEY, DEFAULT_ALGORITHM_EXPRESSION); Preconditions.checkNotNull(algorithmExpression, "Inline sharding algorithm expression can not be null."); - return InlineExpressionParserFactory.newInstance().handlePlaceHolder(algorithmExpression.trim()); + return InlineExpressionParserFactory.newInstance(algorithmExpression.trim()).handlePlaceHolder(); } @Override @@ -61,7 +61,7 @@ private String doSharding(final Comparable shardingValue) { } private Closure createClosure() { - Closure result = InlineExpressionParserFactory.newInstance().evaluateClosure(algorithmExpression).rehydrate(new Expando(), null, null); + Closure result = InlineExpressionParserFactory.newInstance(algorithmExpression).evaluateClosure().rehydrate(new Expando(), null, null); result.setResolveStrategy(Closure.DELEGATE_ONLY); return result; } diff --git a/infra/expr/core/pom.xml b/infra/expr/core/pom.xml index 84f274b57cf14..a5fafdeba9e86 100644 --- a/infra/expr/core/pom.xml +++ b/infra/expr/core/pom.xml @@ -34,7 +34,7 @@ org.apache.shardingsphere - shardingsphere-infra-expr-hotsopt + shardingsphere-infra-expr-groovy ${project.version} @@ -49,10 +49,5 @@ ${project.version} test - - - org.apache.groovy - groovy - diff --git a/infra/expr/core/src/main/java/org/apache/shardingsphere/infra/expr/core/InlineExpressionParserFactory.java b/infra/expr/core/src/main/java/org/apache/shardingsphere/infra/expr/core/InlineExpressionParserFactory.java index 11a03cd4948e4..97dd60b3c7653 100644 --- a/infra/expr/core/src/main/java/org/apache/shardingsphere/infra/expr/core/InlineExpressionParserFactory.java +++ b/infra/expr/core/src/main/java/org/apache/shardingsphere/infra/expr/core/InlineExpressionParserFactory.java @@ -22,21 +22,45 @@ import org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; +import java.util.Properties; + /** * Inline expression parser factory. */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class InlineExpressionParserFactory { - // workaround for https://junit.org/junit5/docs/5.10.0/api/org.junit.jupiter.api/org/junit/jupiter/api/condition/EnabledInNativeImage.html - private static final boolean IS_SUBSTRATE_VM = "runtime".equals(System.getProperty("org.graalvm.nativeimage.imagecode")); + private static final String TYPE_NAME_BEGIN_SYMBOL = "<"; + + private static final String TYPE_NAME_END_SYMBOL = ">"; /** - * Create new instance of inline expression parser. - * + * Create new instance of inline expression parser by inlineExpression. + * And for compatibility reasons, inlineExpression allows to be null. + * + * @param inlineExpression inline expression * @return created instance */ - public static InlineExpressionParser newInstance() { - return TypedSPILoader.getService(InlineExpressionParser.class, IS_SUBSTRATE_VM ? "PURELIST" : "HOTSPOT"); + public static InlineExpressionParser newInstance(final String inlineExpression) { + Properties props = new Properties(); + if (null == inlineExpression) { + return TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", props); + } + if (!inlineExpression.startsWith(TYPE_NAME_BEGIN_SYMBOL)) { + props.setProperty(InlineExpressionParser.INLINE_EXPRESSION_KEY, inlineExpression); + return TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", props); + } + Integer typeBeginIndex = inlineExpression.indexOf(TYPE_NAME_BEGIN_SYMBOL); + Integer typeEndIndex = inlineExpression.indexOf(TYPE_NAME_END_SYMBOL); + props.setProperty(InlineExpressionParser.INLINE_EXPRESSION_KEY, removeTypeNameInExpr(inlineExpression, typeBeginIndex, typeEndIndex)); + return TypedSPILoader.getService(InlineExpressionParser.class, getTypeName(inlineExpression, typeBeginIndex, typeEndIndex), props); + } + + private static String getTypeName(final String inlineExpression, final Integer beginIndex, final Integer endIndex) { + return beginIndex.equals(-1) || endIndex.equals(-1) ? "GROOVY" : inlineExpression.substring(beginIndex + 1, endIndex); + } + + private static String removeTypeNameInExpr(final String inlineExpression, final Integer beginIndex, final Integer endIndex) { + return inlineExpression.substring(0, beginIndex) + inlineExpression.substring(endIndex + 1); } } diff --git a/infra/expr/core/src/test/java/org/apache/shardingsphere/infra/expr/core/InlineExpressionParserFactoryTest.java b/infra/expr/core/src/test/java/org/apache/shardingsphere/infra/expr/core/InlineExpressionParserFactoryTest.java index 931e47f3150b3..4ade13127fe0e 100644 --- a/infra/expr/core/src/test/java/org/apache/shardingsphere/infra/expr/core/InlineExpressionParserFactoryTest.java +++ b/infra/expr/core/src/test/java/org/apache/shardingsphere/infra/expr/core/InlineExpressionParserFactoryTest.java @@ -17,34 +17,49 @@ package org.apache.shardingsphere.infra.expr.core; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; +import org.apache.shardingsphere.infra.spi.exception.ServiceProviderNotFoundException; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledInNativeImage; + +import java.util.Arrays; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; class InlineExpressionParserFactoryTest { - private String originalImageCode; - - @BeforeEach - public void setUp() { - originalImageCode = System.getProperty("org.graalvm.nativeimage.imagecode"); + @Test + @DisabledInNativeImage + void assertNewInstance() { + assertThat(InlineExpressionParserFactory.newInstance("t_order_0, t_order_1").getType(), is("GROOVY")); + assertThat(InlineExpressionParserFactory.newInstance("t_order_0, t_order_1").handlePlaceHolder(), is("t_order_0, t_order_1")); + assertThat(InlineExpressionParserFactory.newInstance("t_order_0, t_order_1").getType(), is("GROOVY")); + assertThat(InlineExpressionParserFactory.newInstance("t_order_0, t_order_1").handlePlaceHolder(), is("t_order_0, t_order_1")); + assertThat(InlineExpressionParserFactory.newInstance("t_order_0, t_order_1").getType(), is("PURELIST")); + assertThat(InlineExpressionParserFactory.newInstance("t_order_0, t_order_1").handlePlaceHolder(), is("t_order_0, t_order_1")); } - @AfterEach - public void tearDown() { - if (null != originalImageCode) { - System.setProperty("org.graalvm.nativeimage.imagecode", originalImageCode); - } else { - System.clearProperty("org.graalvm.nativeimage.imagecode"); - } + @Test + void assertUndefinedInstance() { + assertThrows(ServiceProviderNotFoundException.class, + () -> InlineExpressionParserFactory.newInstance("t_order_0, t_order_1").getType()); } @Test - void assertNewInstance() { - System.setProperty("org.graalvm.nativeimage.imagecode", ""); - assertThat(InlineExpressionParserFactory.newInstance().getType(), is("HOTSPOT")); + void assertFixtureInstance() { + assertThat(InlineExpressionParserFactory.newInstance("spring").splitAndEvaluate(), + is(Arrays.asList("t_order_2023_03", "t_order_2023_04", "t_order_2023_05"))); + assertThat(InlineExpressionParserFactory.newInstance("summer").splitAndEvaluate(), + is(Arrays.asList("t_order_2023_06", "t_order_2023_07", "t_order_2023_08"))); + assertThat(InlineExpressionParserFactory.newInstance("autumn").splitAndEvaluate(), + is(Arrays.asList("t_order_2023_09", "t_order_2023_10", "t_order_2023_11"))); + assertThat(InlineExpressionParserFactory.newInstance("winter").splitAndEvaluate(), + is(Arrays.asList("t_order_2023_12", "t_order_2024_01", "t_order_2024_02"))); + assertThat(InlineExpressionParserFactory.newInstance("").splitAndEvaluate(), + is(Arrays.asList("t_order_2023_03", "t_order_2023_04", "t_order_2023_05", + "t_order_2023_06", "t_order_2023_07", "t_order_2023_08", + "t_order_2023_09", "t_order_2023_10", "t_order_2023_11", + "t_order_2023_12", "t_order_2024_01", "t_order_2024_02"))); } } diff --git a/infra/expr/core/src/test/java/org/apache/shardingsphere/infra/expr/core/fixture/CustomInlineExpressionParserFixture.java b/infra/expr/core/src/test/java/org/apache/shardingsphere/infra/expr/core/fixture/CustomInlineExpressionParserFixture.java new file mode 100644 index 0000000000000..3f0f8d5a59dba --- /dev/null +++ b/infra/expr/core/src/test/java/org/apache/shardingsphere/infra/expr/core/fixture/CustomInlineExpressionParserFixture.java @@ -0,0 +1,63 @@ +/* + * 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.infra.expr.core.fixture; + +import org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser; + +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +public final class CustomInlineExpressionParserFixture implements InlineExpressionParser { + + private String inlineExpression; + + @Override + public void init(final Properties props) { + this.inlineExpression = props.getProperty(INLINE_EXPRESSION_KEY); + } + + @Override + public String handlePlaceHolder() { + return inlineExpression; + } + + @Override + public List splitAndEvaluate() { + switch (inlineExpression) { + case "spring": + return Arrays.asList("t_order_2023_03", "t_order_2023_04", "t_order_2023_05"); + case "summer": + return Arrays.asList("t_order_2023_06", "t_order_2023_07", "t_order_2023_08"); + case "autumn": + return Arrays.asList("t_order_2023_09", "t_order_2023_10", "t_order_2023_11"); + case "winter": + return Arrays.asList("t_order_2023_12", "t_order_2024_01", "t_order_2024_02"); + default: + return Arrays.asList("t_order_2023_03", "t_order_2023_04", "t_order_2023_05", + "t_order_2023_06", "t_order_2023_07", "t_order_2023_08", + "t_order_2023_09", "t_order_2023_10", "t_order_2023_11", + "t_order_2023_12", "t_order_2024_01", "t_order_2024_02"); + } + } + + @Override + public Object getType() { + return "CUSTOM.FIXTURE"; + } +} diff --git a/infra/expr/core/src/test/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser b/infra/expr/core/src/test/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser new file mode 100644 index 0000000000000..2af948cb146aa --- /dev/null +++ b/infra/expr/core/src/test/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.infra.expr.core.fixture.CustomInlineExpressionParserFixture diff --git a/infra/expr/espresso/pom.xml b/infra/expr/espresso/pom.xml index 653fe6e1653d7..df7c6fc1cfbda 100644 --- a/infra/expr/espresso/pom.xml +++ b/infra/expr/espresso/pom.xml @@ -26,6 +26,10 @@ shardingsphere-infra-expr-espresso ${project.artifactId} + + 21.2.0 + + org.apache.shardingsphere @@ -46,6 +50,14 @@ org.graalvm.truffle truffle-api + ${truffle-api.version} + + + + org.apache.shardingsphere + shardingsphere-test-util + ${project.version} + test diff --git a/infra/expr/espresso/src/main/java/org/apache/shardingsphere/infra/expr/espresso/EspressoInlineExpressionParser.java b/infra/expr/espresso/src/main/java/org/apache/shardingsphere/infra/expr/espresso/EspressoInlineExpressionParser.java index bfe5201bb08be..8e9b33fc3ad7f 100644 --- a/infra/expr/espresso/src/main/java/org/apache/shardingsphere/infra/expr/espresso/EspressoInlineExpressionParser.java +++ b/infra/expr/espresso/src/main/java/org/apache/shardingsphere/infra/expr/espresso/EspressoInlineExpressionParser.java @@ -19,7 +19,6 @@ import com.google.common.base.Strings; import com.google.common.collect.Sets; -import groovy.lang.Closure; import groovy.lang.GroovyShell; import org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser; import org.graalvm.polyglot.Context; @@ -32,6 +31,7 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; +import java.util.Properties; import java.util.Set; import java.util.stream.Collectors; @@ -44,31 +44,53 @@ public final class EspressoInlineExpressionParser implements InlineExpressionPar private static final char SPLITTER = ','; + private String inlineExpression; + static { URL resource = Thread.currentThread().getContextClassLoader().getResource("espresso-need-libs"); String dir = null == resource ? null : resource.getPath(); JAVA_CLASSPATH = dir + File.separator + "groovy.jar"; } + /** + * Initialize SPI. + * + * @param props A Properties instance that carries inlineExpression. + * And for compatibility reasons, inlineExpression allows to be null. + */ @Override - public String handlePlaceHolder(final String inlineExpression) { - return inlineExpression.contains("$->{") ? inlineExpression.replaceAll("\\$->\\{", "\\$\\{") : inlineExpression; + public void init(final Properties props) { + this.inlineExpression = props.getProperty(INLINE_EXPRESSION_KEY); } @Override - public List splitAndEvaluate(final String inlineExpression) { - try (Context context = createContext()) { - return Strings.isNullOrEmpty(inlineExpression) ? Collections.emptyList() : flatten(evaluate(split(inlineExpression), context)); - } + public String handlePlaceHolder() { + return handlePlaceHolder(inlineExpression); + } + + /** + * Replace all inline expression placeholders. + * + * @param inlineExpression inline expression with {@code $->} + * @return result inline expression with {@code $} + */ + private String handlePlaceHolder(final String inlineExpression) { + return inlineExpression.contains("$->{") ? inlineExpression.replaceAll("\\$->\\{", "\\$\\{") : inlineExpression; } @Override - public Closure evaluateClosure(final String inlineExpression) { - throw new UnsupportedOperationException("GraalVM Truffle's Espresso implementation cannot return an instance of `groovy.lang.Closure` to the Host JVM."); + public List splitAndEvaluate() { + try (Context context = createContext()) { + return Strings.isNullOrEmpty(inlineExpression) ? Collections.emptyList() : flatten(evaluate(split(handlePlaceHolder(inlineExpression)), context)); + } } + /** + * TODO espressoHome not defined not yet closed. + * + * @return the Truffle Context Instance. + */ private Context createContext() { - // TODO https://github.com/oracle/graal/issues/4555 not yet closed return Context.newBuilder() .allowAllAccess(true) .option("java.Properties.org.graalvm.home", System.getenv("JAVA_HOME")) diff --git a/infra/expr/espresso/src/test/java/org/apache/shardingsphere/infra/expr/espresso/EspressoInlineExpressionParserTest.java b/infra/expr/espresso/src/test/java/org/apache/shardingsphere/infra/expr/espresso/EspressoInlineExpressionParserTest.java index 3f7999f5e4cad..ca6deb1c66e1d 100644 --- a/infra/expr/espresso/src/test/java/org/apache/shardingsphere/infra/expr/espresso/EspressoInlineExpressionParserTest.java +++ b/infra/expr/espresso/src/test/java/org/apache/shardingsphere/infra/expr/espresso/EspressoInlineExpressionParserTest.java @@ -17,6 +17,9 @@ package org.apache.shardingsphere.infra.expr.espresso; +import org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser; +import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; +import org.apache.shardingsphere.test.util.PropertiesBuilder; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; @@ -24,6 +27,7 @@ import java.util.Collections; import java.util.List; +import java.util.Properties; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.is; @@ -35,62 +39,71 @@ class EspressoInlineExpressionParserTest { @Test void assertEvaluateForExpressionIsNull() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate(null); + InlineExpressionParser parser = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", new Properties()); + List expected = parser.splitAndEvaluate(); assertThat(expected, is(Collections.emptyList())); } @Test void assertEvaluateForSimpleString() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate(" t_order_0, t_order_1 "); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, " t_order_0, t_order_1 "))).splitAndEvaluate(); assertThat(expected.size(), is(2)); assertThat(expected, hasItems("t_order_0", "t_order_1")); } @Test void assertEvaluateForNull() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate("t_order_${null}"); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_order_${null}"))).splitAndEvaluate(); assertThat(expected.size(), is(1)); assertThat(expected, hasItems("t_order_")); } @Test void assertEvaluateForLiteral() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate("t_order_${'xx'}"); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_order_${'xx'}"))).splitAndEvaluate(); assertThat(expected.size(), is(1)); assertThat(expected, hasItems("t_order_xx")); } @Test void assertEvaluateForArray() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate("t_order_${[0, 1, 2]},t_order_item_${[0, 2]}"); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_order_${[0, 1, 2]},t_order_item_${[0, 2]}"))).splitAndEvaluate(); assertThat(expected.size(), is(5)); assertThat(expected, hasItems("t_order_0", "t_order_1", "t_order_2", "t_order_item_0", "t_order_item_2")); } @Test void assertEvaluateForRange() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate("t_order_${0..2},t_order_item_${0..1}"); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_order_${0..2},t_order_item_${0..1}"))).splitAndEvaluate(); assertThat(expected.size(), is(5)); assertThat(expected, hasItems("t_order_0", "t_order_1", "t_order_2", "t_order_item_0", "t_order_item_1")); } @Test void assertEvaluateForComplex() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate("t_${['new','old']}_order_${1..2}, t_config"); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_${['new','old']}_order_${1..2}, t_config"))).splitAndEvaluate(); assertThat(expected.size(), is(5)); assertThat(expected, hasItems("t_new_order_1", "t_new_order_2", "t_old_order_1", "t_old_order_2", "t_config")); } @Test void assertEvaluateForCalculate() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate("t_${[\"new${1+2}\",'old']}_order_${1..2}"); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_${[\"new${1+2}\",'old']}_order_${1..2}"))).splitAndEvaluate(); assertThat(expected.size(), is(4)); assertThat(expected, hasItems("t_new3_order_1", "t_new3_order_2", "t_old_order_1", "t_old_order_2")); } @Test void assertEvaluateForExpressionPlaceHolder() { - List expected = new EspressoInlineExpressionParser().splitAndEvaluate("t_$->{[\"new$->{1+2}\",'old']}_order_$->{1..2}"); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_$->{[\"new$->{1+2}\",'old']}_order_$->{1..2}"))).splitAndEvaluate(); assertThat(expected.size(), is(4)); assertThat(expected, hasItems("t_new3_order_1", "t_new3_order_2", "t_old_order_1", "t_old_order_2")); } @@ -107,15 +120,18 @@ void assertEvaluateForLong() { expression.append(","); } } - List expected = new EspressoInlineExpressionParser().splitAndEvaluate(expression.toString()); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, expression.toString()))).splitAndEvaluate(); assertThat(expected.size(), is(1024)); assertThat(expected, hasItems("ds_0.t_user_0", "ds_15.t_user_1023")); } @Test void assertHandlePlaceHolder() { - assertThat(new EspressoInlineExpressionParser().handlePlaceHolder("t_$->{[\"new$->{1+2}\"]}"), is("t_${[\"new${1+2}\"]}")); - assertThat(new EspressoInlineExpressionParser().handlePlaceHolder("t_${[\"new$->{1+2}\"]}"), is("t_${[\"new${1+2}\"]}")); + assertThat(TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_$->{[\"new$->{1+2}\"]}"))).handlePlaceHolder(), is("t_${[\"new${1+2}\"]}")); + assertThat(TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_${[\"new$->{1+2}\"]}"))).handlePlaceHolder(), is("t_${[\"new${1+2}\"]}")); } /* @@ -125,6 +141,7 @@ void assertHandlePlaceHolder() { @Test @Disabled("See java doc") void assertEvaluateClosure() { - assertThat(new EspressoInlineExpressionParser().evaluateClosure("${1+2}").call().toString(), is("3")); + assertThat(TypedSPILoader.getService(InlineExpressionParser.class, "ESPRESSO", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "${1+2}"))).evaluateClosure().call().toString(), is("3")); } } diff --git a/infra/expr/hotsopt/pom.xml b/infra/expr/groovy/pom.xml similarity index 86% rename from infra/expr/hotsopt/pom.xml rename to infra/expr/groovy/pom.xml index 2fa03655f3b2a..cbc18ed0bed35 100644 --- a/infra/expr/hotsopt/pom.xml +++ b/infra/expr/groovy/pom.xml @@ -23,7 +23,7 @@ shardingsphere-infra-expr 5.4.1-SNAPSHOT - shardingsphere-infra-expr-hotsopt + shardingsphere-infra-expr-groovy ${project.artifactId} @@ -34,8 +34,10 @@ - org.apache.groovy - groovy + org.apache.shardingsphere + shardingsphere-test-util + ${project.version} + test diff --git a/infra/expr/hotsopt/src/main/java/org/apache/shardingsphere/infra/expr/hotsopt/HotspotInlineExpressionParser.java b/infra/expr/groovy/src/main/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParser.java similarity index 78% rename from infra/expr/hotsopt/src/main/java/org/apache/shardingsphere/infra/expr/hotsopt/HotspotInlineExpressionParser.java rename to infra/expr/groovy/src/main/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParser.java index 1ec58bb940ca8..27411402be02a 100644 --- a/infra/expr/hotsopt/src/main/java/org/apache/shardingsphere/infra/expr/hotsopt/HotspotInlineExpressionParser.java +++ b/infra/expr/groovy/src/main/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParser.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.shardingsphere.infra.expr.hotsopt; +package org.apache.shardingsphere.infra.expr.groovy; import com.google.common.base.Strings; import com.google.common.collect.Sets; @@ -31,34 +31,70 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; /** - * Hotspot inline expression parser. + * Groovy inline expression parser. */ -public final class HotspotInlineExpressionParser implements InlineExpressionParser { +public final class GroovyInlineExpressionParser implements InlineExpressionParser { private static final char SPLITTER = ','; + private static final String INLINE_EXPRESSION_KEY = "inlineExpression"; + private static final Map SCRIPTS = new ConcurrentHashMap<>(); private static final GroovyShell SHELL = new GroovyShell(); + private String inlineExpression; + + /** + * Initialize SPI. + * + * @param props A Properties instance that carries inlineExpression. + * And for compatibility reasons, inlineExpression allows to be null. + */ @Override - public String handlePlaceHolder(final String inlineExpression) { + public void init(final Properties props) { + this.inlineExpression = props.getProperty(INLINE_EXPRESSION_KEY); + } + + @Override + public String handlePlaceHolder() { + return handlePlaceHolder(inlineExpression); + } + + /** + * Replace all inline expression placeholders. + * + * @param inlineExpression inline expression with {@code $->} + * @return result inline expression with {@code $} + */ + private String handlePlaceHolder(final String inlineExpression) { return inlineExpression.contains("$->{") ? inlineExpression.replaceAll("\\$->\\{", "\\$\\{") : inlineExpression; } + /** + * Split and Evaluate inline expression. This function will replace all inline expression placeholders. + * + * @return result inline expression with {@code $} + */ @Override - public List splitAndEvaluate(final String inlineExpression) { - return Strings.isNullOrEmpty(inlineExpression) ? Collections.emptyList() : flatten(evaluate(split(inlineExpression))); + public List splitAndEvaluate() { + return Strings.isNullOrEmpty(inlineExpression) ? Collections.emptyList() : flatten(evaluate(split(handlePlaceHolder(inlineExpression)))); } + /** + * Turn inline expression into Groovy Closure. This function will replace all inline expression placeholders. + * + * @return The result of the Groovy Closure pattern. + */ @Override - public Closure evaluateClosure(final String inlineExpression) { - return (Closure) evaluate("{it -> \"" + inlineExpression + "\"}"); + public Closure evaluateClosure() { + return (Closure) evaluate("{it -> \"" + handlePlaceHolder(inlineExpression) + "\"}"); } private List evaluate(final List inlineExpressions) { @@ -178,7 +214,7 @@ private String assemblySegment(final List cartesianValue, final GString @Override public String getType() { - return "HOTSPOT"; + return "GROOVY"; } @Override diff --git a/infra/expr/hotsopt/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser b/infra/expr/groovy/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser similarity index 91% rename from infra/expr/hotsopt/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser rename to infra/expr/groovy/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser index 48cf905c9a530..1eab5f0f7be8e 100644 --- a/infra/expr/hotsopt/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser +++ b/infra/expr/groovy/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser @@ -15,4 +15,4 @@ # limitations under the License. # -org.apache.shardingsphere.infra.expr.hotsopt.HotspotInlineExpressionParser +org.apache.shardingsphere.infra.expr.groovy.GroovyInlineExpressionParser diff --git a/infra/expr/groovy/src/test/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParserTest.java b/infra/expr/groovy/src/test/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParserTest.java new file mode 100644 index 0000000000000..b2a2940720f7a --- /dev/null +++ b/infra/expr/groovy/src/test/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParserTest.java @@ -0,0 +1,139 @@ +/* + * 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.infra.expr.groovy; + +import org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser; +import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; +import org.apache.shardingsphere.test.util.PropertiesBuilder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledInNativeImage; + +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@DisabledInNativeImage +class GroovyInlineExpressionParserTest { + + @Test + void assertEvaluateForExpressionIsNull() { + InlineExpressionParser parser = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", new Properties()); + List expected = parser.splitAndEvaluate(); + assertThat(expected, is(Collections.emptyList())); + } + + @Test + void assertEvaluateForSimpleString() { + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, " t_order_0, t_order_1 "))).splitAndEvaluate(); + assertThat(expected.size(), is(2)); + assertThat(expected, hasItems("t_order_0", "t_order_1")); + } + + @Test + void assertEvaluateForNull() { + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_order_${null}"))).splitAndEvaluate(); + assertThat(expected.size(), is(1)); + assertThat(expected, hasItems("t_order_")); + } + + @Test + void assertEvaluateForLiteral() { + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_order_${'xx'}"))).splitAndEvaluate(); + assertThat(expected.size(), is(1)); + assertThat(expected, hasItems("t_order_xx")); + } + + @Test + void assertEvaluateForArray() { + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_order_${[0, 1, 2]},t_order_item_${[0, 2]}"))).splitAndEvaluate(); + assertThat(expected.size(), is(5)); + assertThat(expected, hasItems("t_order_0", "t_order_1", "t_order_2", "t_order_item_0", "t_order_item_2")); + } + + @Test + void assertEvaluateForRange() { + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_order_${0..2},t_order_item_${0..1}"))).splitAndEvaluate(); + assertThat(expected.size(), is(5)); + assertThat(expected, hasItems("t_order_0", "t_order_1", "t_order_2", "t_order_item_0", "t_order_item_1")); + } + + @Test + void assertEvaluateForComplex() { + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_${['new','old']}_order_${1..2}, t_config"))).splitAndEvaluate(); + assertThat(expected.size(), is(5)); + assertThat(expected, hasItems("t_new_order_1", "t_new_order_2", "t_old_order_1", "t_old_order_2", "t_config")); + } + + @Test + void assertEvaluateForCalculate() { + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_${[\"new${1+2}\",'old']}_order_${1..2}"))).splitAndEvaluate(); + assertThat(expected.size(), is(4)); + assertThat(expected, hasItems("t_new3_order_1", "t_new3_order_2", "t_old_order_1", "t_old_order_2")); + } + + @Test + void assertEvaluateForExpressionPlaceHolder() { + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_$->{[\"new$->{1+2}\",'old']}_order_$->{1..2}"))).splitAndEvaluate(); + assertThat(expected.size(), is(4)); + assertThat(expected, hasItems("t_new3_order_1", "t_new3_order_2", "t_old_order_1", "t_old_order_2")); + } + + @Test + void assertEvaluateForLong() { + StringBuilder expression = new StringBuilder(); + for (int i = 0; i < 1024; i++) { + expression.append("ds_"); + expression.append(i / 64); + expression.append(".t_user_"); + expression.append(i); + if (i != 1023) { + expression.append(","); + } + } + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, expression.toString()))).splitAndEvaluate(); + assertThat(expected.size(), is(1024)); + assertThat(expected, hasItems("ds_0.t_user_0", "ds_15.t_user_1023")); + } + + @Test + void assertHandlePlaceHolder() { + assertThat(TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_$->{[\"new$->{1+2}\"]}"))).handlePlaceHolder(), is("t_${[\"new${1+2}\"]}")); + assertThat(TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_${[\"new$->{1+2}\"]}"))).handlePlaceHolder(), is("t_${[\"new${1+2}\"]}")); + } + + @Test + void assertEvaluateClosure() { + assertThat(TypedSPILoader.getService(InlineExpressionParser.class, "GROOVY", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "${1+2}"))).evaluateClosure().call().toString(), is("3")); + } +} diff --git a/infra/expr/hotsopt/src/test/java/org/apache/shardingsphere/infra/expr/hotsopt/HotspotInlineExpressionParserTest.java b/infra/expr/hotsopt/src/test/java/org/apache/shardingsphere/infra/expr/hotsopt/HotspotInlineExpressionParserTest.java deleted file mode 100644 index 9a836eff0f9ac..0000000000000 --- a/infra/expr/hotsopt/src/test/java/org/apache/shardingsphere/infra/expr/hotsopt/HotspotInlineExpressionParserTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.infra.expr.hotsopt; - -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.List; - -import static org.hamcrest.CoreMatchers.hasItems; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -class HotspotInlineExpressionParserTest { - - @Test - void assertEvaluateForExpressionIsNull() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate(null); - assertThat(expected, is(Collections.emptyList())); - } - - @Test - void assertEvaluateForSimpleString() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate(" t_order_0, t_order_1 "); - assertThat(expected.size(), is(2)); - assertThat(expected, hasItems("t_order_0", "t_order_1")); - } - - @Test - void assertEvaluateForNull() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate("t_order_${null}"); - assertThat(expected.size(), is(1)); - assertThat(expected, hasItems("t_order_")); - } - - @Test - void assertEvaluateForLiteral() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate("t_order_${'xx'}"); - assertThat(expected.size(), is(1)); - assertThat(expected, hasItems("t_order_xx")); - } - - @Test - void assertEvaluateForArray() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate("t_order_${[0, 1, 2]},t_order_item_${[0, 2]}"); - assertThat(expected.size(), is(5)); - assertThat(expected, hasItems("t_order_0", "t_order_1", "t_order_2", "t_order_item_0", "t_order_item_2")); - } - - @Test - void assertEvaluateForRange() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate("t_order_${0..2},t_order_item_${0..1}"); - assertThat(expected.size(), is(5)); - assertThat(expected, hasItems("t_order_0", "t_order_1", "t_order_2", "t_order_item_0", "t_order_item_1")); - } - - @Test - void assertEvaluateForComplex() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate("t_${['new','old']}_order_${1..2}, t_config"); - assertThat(expected.size(), is(5)); - assertThat(expected, hasItems("t_new_order_1", "t_new_order_2", "t_old_order_1", "t_old_order_2", "t_config")); - } - - @Test - void assertEvaluateForCalculate() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate("t_${[\"new${1+2}\",'old']}_order_${1..2}"); - assertThat(expected.size(), is(4)); - assertThat(expected, hasItems("t_new3_order_1", "t_new3_order_2", "t_old_order_1", "t_old_order_2")); - } - - @Test - void assertEvaluateForExpressionPlaceHolder() { - List expected = new HotspotInlineExpressionParser().splitAndEvaluate("t_$->{[\"new$->{1+2}\",'old']}_order_$->{1..2}"); - assertThat(expected.size(), is(4)); - assertThat(expected, hasItems("t_new3_order_1", "t_new3_order_2", "t_old_order_1", "t_old_order_2")); - } - - @Test - void assertEvaluateForLong() { - StringBuilder expression = new StringBuilder(); - for (int i = 0; i < 1024; i++) { - expression.append("ds_"); - expression.append(i / 64); - expression.append(".t_user_"); - expression.append(i); - if (i != 1023) { - expression.append(","); - } - } - List expected = new HotspotInlineExpressionParser().splitAndEvaluate(expression.toString()); - assertThat(expected.size(), is(1024)); - assertThat(expected, hasItems("ds_0.t_user_0", "ds_15.t_user_1023")); - } - - @Test - void assertHandlePlaceHolder() { - assertThat(new HotspotInlineExpressionParser().handlePlaceHolder("t_$->{[\"new$->{1+2}\"]}"), is("t_${[\"new${1+2}\"]}")); - assertThat(new HotspotInlineExpressionParser().handlePlaceHolder("t_${[\"new$->{1+2}\"]}"), is("t_${[\"new${1+2}\"]}")); - } - - @Test - void assertEvaluateClosure() { - assertThat(new HotspotInlineExpressionParser().evaluateClosure("${1+2}").call().toString(), is("3")); - } -} diff --git a/infra/expr/pom.xml b/infra/expr/pom.xml index 14aa380d873ee..9f9e4e7cb6486 100644 --- a/infra/expr/pom.xml +++ b/infra/expr/pom.xml @@ -30,8 +30,8 @@ spi core - hotsopt - espresso + groovy purelist + espresso diff --git a/infra/expr/purelist/pom.xml b/infra/expr/purelist/pom.xml index b45ff489b3770..0e3d95b390bff 100644 --- a/infra/expr/purelist/pom.xml +++ b/infra/expr/purelist/pom.xml @@ -34,8 +34,10 @@ - org.apache.groovy - groovy + org.apache.shardingsphere + shardingsphere-test-util + ${project.version} + test diff --git a/infra/expr/purelist/src/main/java/org/apache/shardingsphere/infra/expr/purelist/PureListInlineExpressionParser.java b/infra/expr/purelist/src/main/java/org/apache/shardingsphere/infra/expr/purelist/PureListInlineExpressionParser.java index 347b6d4f3e219..ab1d3a34af286 100644 --- a/infra/expr/purelist/src/main/java/org/apache/shardingsphere/infra/expr/purelist/PureListInlineExpressionParser.java +++ b/infra/expr/purelist/src/main/java/org/apache/shardingsphere/infra/expr/purelist/PureListInlineExpressionParser.java @@ -18,12 +18,12 @@ package org.apache.shardingsphere.infra.expr.purelist; import com.google.common.base.Strings; -import groovy.lang.Closure; import org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Properties; /** * Pure List inline expression parser. @@ -32,19 +32,27 @@ public final class PureListInlineExpressionParser implements InlineExpressionPar private static final char SPLITTER = ','; + private String inlineExpression; + + /** + * Initialize SPI. + * + * @param props A Properties instance that carries inlineExpression. + * And for compatibility reasons, inlineExpression allows to be null. + */ @Override - public String handlePlaceHolder(final String inlineExpression) { - return inlineExpression.contains("$->{") ? inlineExpression.replaceAll("\\$->\\{", "\\$\\{") : inlineExpression; + public void init(final Properties props) { + this.inlineExpression = props.getProperty(INLINE_EXPRESSION_KEY); } @Override - public List splitAndEvaluate(final String inlineExpression) { - return Strings.isNullOrEmpty(inlineExpression) ? Collections.emptyList() : split(inlineExpression); + public String handlePlaceHolder() { + return inlineExpression; } @Override - public Closure evaluateClosure(final String inlineExpression) { - throw new UnsupportedOperationException("Groovy classes cannot be used directly within GraalVM Native Image."); + public List splitAndEvaluate() { + return Strings.isNullOrEmpty(inlineExpression) ? Collections.emptyList() : split(inlineExpression); } private List split(final String inlineExpression) { diff --git a/infra/expr/purelist/src/test/java/org/apache/shardingsphere/infra/expr/purelist/PureListInlineExpressionParserTest.java b/infra/expr/purelist/src/test/java/org/apache/shardingsphere/infra/expr/purelist/PureListInlineExpressionParserTest.java index bb8ebbf8855ce..2ddeacdd7b45f 100644 --- a/infra/expr/purelist/src/test/java/org/apache/shardingsphere/infra/expr/purelist/PureListInlineExpressionParserTest.java +++ b/infra/expr/purelist/src/test/java/org/apache/shardingsphere/infra/expr/purelist/PureListInlineExpressionParserTest.java @@ -17,26 +17,33 @@ package org.apache.shardingsphere.infra.expr.purelist; +import org.apache.shardingsphere.infra.expr.spi.InlineExpressionParser; +import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; +import org.apache.shardingsphere.test.util.PropertiesBuilder; import org.junit.jupiter.api.Test; import java.util.Collections; import java.util.List; +import java.util.Properties; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; class PureListInlineExpressionParserTest { @Test void assertEvaluateForExpressionIsNull() { - List expected = new PureListInlineExpressionParser().splitAndEvaluate(null); + InlineExpressionParser parser = TypedSPILoader.getService(InlineExpressionParser.class, "PURELIST", new Properties()); + List expected = parser.splitAndEvaluate(); assertThat(expected, is(Collections.emptyList())); } @Test void assertEvaluateForSimpleString() { - List expected = new PureListInlineExpressionParser().splitAndEvaluate(" t_order_0, t_order_1 "); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "PURELIST", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, " t_order_0, t_order_1 "))).splitAndEvaluate(); assertThat(expected.size(), is(2)); assertThat(expected, hasItems("t_order_0", "t_order_1")); } @@ -53,8 +60,23 @@ void assertEvaluateForLong() { expression.append(","); } } - List expected = new PureListInlineExpressionParser().splitAndEvaluate(expression.toString()); + List expected = TypedSPILoader.getService(InlineExpressionParser.class, "PURELIST", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, expression.toString()))).splitAndEvaluate(); assertThat(expected.size(), is(1024)); assertThat(expected, hasItems("ds_0.t_user_0", "ds_15.t_user_1023")); } + + @Test + void assertHandlePlaceHolder() { + assertThat(TypedSPILoader.getService(InlineExpressionParser.class, "PURELIST", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_$->{[\"new$->{1+2}\"]}"))).handlePlaceHolder(), is("t_$->{[\"new$->{1+2}\"]}")); + assertThat(TypedSPILoader.getService(InlineExpressionParser.class, "PURELIST", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "t_${[\"new$->{1+2}\"]}"))).handlePlaceHolder(), is("t_${[\"new$->{1+2}\"]}")); + } + + @Test + void assertEvaluateClosure() { + assertThrows(UnsupportedOperationException.class, () -> TypedSPILoader.getService(InlineExpressionParser.class, "PURELIST", PropertiesBuilder.build( + new PropertiesBuilder.Property(InlineExpressionParser.INLINE_EXPRESSION_KEY, "${1+2}"))).evaluateClosure().call().toString()); + } } diff --git a/infra/expr/spi/src/main/java/org/apache/shardingsphere/infra/expr/spi/InlineExpressionParser.java b/infra/expr/spi/src/main/java/org/apache/shardingsphere/infra/expr/spi/InlineExpressionParser.java index 7baa872862963..7578f5f8f2d4e 100644 --- a/infra/expr/spi/src/main/java/org/apache/shardingsphere/infra/expr/spi/InlineExpressionParser.java +++ b/infra/expr/spi/src/main/java/org/apache/shardingsphere/infra/expr/spi/InlineExpressionParser.java @@ -30,26 +30,34 @@ public interface InlineExpressionParser extends TypedSPI { /** - * Replace all inline expression placeholders. + * The expression used to build the InlineExpressionParser instance will be saved to the Properties instance via this key. + */ + String INLINE_EXPRESSION_KEY = "inlineExpression"; + + /** + * This method is used to return the inlineExpression String itself. In some cases, you may want to do + * additional processing on inlineExpression to return a specific value, in which case you need to override this + * method. * - * @param inlineExpression inline expression with {@code $->} - * @return result inline expression with {@code $} + * @return result processed inline expression defined by the SPI implementation. */ - String handlePlaceHolder(String inlineExpression); + String handlePlaceHolder(); /** * Split and evaluate inline expression. * - * @param inlineExpression inline expression * @return result list */ - List splitAndEvaluate(String inlineExpression); + List splitAndEvaluate(); /** * Evaluate closure. * - * @param inlineExpression inline expression * @return closure + * @throws UnsupportedOperationException In most cases, users should not implement this method, and the return value + * of this method can only be a Groovy Closure. */ - Closure evaluateClosure(String inlineExpression); + default Closure evaluateClosure() { + throw new UnsupportedOperationException("This SPI implementation does not support the use of this method."); + } } diff --git a/pom.xml b/pom.xml index aa743a7b073de..c1a8677d65615 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,6 @@ 2.3.0 1.3.2 1.2.0 - 21.2.0 1.35.0 2.9.3 @@ -627,12 +626,6 @@ ${awaitility.version} test - - - org.graalvm.truffle - truffle-api - ${truffle-api.version} - @@ -1209,7 +1202,6 @@ generateStandardMetadata - 23.0.1 true true true diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/common/checker/ShardingRuleConfigurationImportChecker.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/common/checker/ShardingRuleConfigurationImportChecker.java index 2260ffbdf9075..6d95d37e16f05 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/common/checker/ShardingRuleConfigurationImportChecker.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/common/checker/ShardingRuleConfigurationImportChecker.java @@ -90,12 +90,12 @@ private Collection getRequiredResources(final ShardingRuleConfiguration } private Collection getDataSourceNames(final ShardingAutoTableRuleConfiguration shardingAutoTableRuleConfig) { - Collection actualDataSources = InlineExpressionParserFactory.newInstance().splitAndEvaluate(shardingAutoTableRuleConfig.getActualDataSources()); + Collection actualDataSources = InlineExpressionParserFactory.newInstance(shardingAutoTableRuleConfig.getActualDataSources()).splitAndEvaluate(); return new HashSet<>(actualDataSources); } private Collection getDataSourceNames(final ShardingTableRuleConfiguration shardingTableRuleConfig) { - Collection actualDataNodes = InlineExpressionParserFactory.newInstance().splitAndEvaluate(shardingTableRuleConfig.getActualDataNodes()); + Collection actualDataNodes = InlineExpressionParserFactory.newInstance(shardingTableRuleConfig.getActualDataNodes()).splitAndEvaluate(); return actualDataNodes.stream().map(each -> new DataNode(each).getDataSourceName()).collect(Collectors.toList()); } diff --git a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/cases/dataset/DataSet.java b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/cases/dataset/DataSet.java index c973887c28986..0d393b83c70b2 100644 --- a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/cases/dataset/DataSet.java +++ b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/cases/dataset/DataSet.java @@ -65,7 +65,7 @@ public DataSetMetaData findMetaData(final String tableName) { * @return data set meta data belong to current data node */ public DataSetMetaData findMetaData(final DataNode dataNode) { - Optional result = metaDataList.stream().filter(each -> contains(InlineExpressionParserFactory.newInstance().splitAndEvaluate(each.getDataNodes()), dataNode)).findFirst(); + Optional result = metaDataList.stream().filter(each -> contains(InlineExpressionParserFactory.newInstance(each.getDataNodes()).splitAndEvaluate(), dataNode)).findFirst(); return result.orElseThrow(() -> new IllegalArgumentException(String.format("Cannot find data node: %s", dataNode))); } diff --git a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/composer/BatchE2EContainerComposer.java b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/composer/BatchE2EContainerComposer.java index d6b1341f63377..d11bc084292e3 100644 --- a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/composer/BatchE2EContainerComposer.java +++ b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/composer/BatchE2EContainerComposer.java @@ -85,7 +85,7 @@ public void assertDataSets(final int[] actualUpdateCounts) throws SQLException { DataSet expected = getDataSet(actualUpdateCounts); assertThat("Only support single table for DML.", expected.getMetaDataList().size(), is(1)); DataSetMetaData expectedDataSetMetaData = expected.getMetaDataList().get(0); - for (String each : InlineExpressionParserFactory.newInstance().splitAndEvaluate(expectedDataSetMetaData.getDataNodes())) { + for (String each : InlineExpressionParserFactory.newInstance(expectedDataSetMetaData.getDataNodes()).splitAndEvaluate()) { DataNode dataNode = new DataNode(each); DataSource dataSource = getActualDataSourceMap().get(dataNode.getDataSourceName()); try ( diff --git a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/DDLE2EIT.java b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/DDLE2EIT.java index cc2bd74b6708d..1beba8c29f92c 100644 --- a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/DDLE2EIT.java +++ b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/DDLE2EIT.java @@ -170,7 +170,7 @@ private void executeDestroySQLs(final SingleE2EContainerComposer containerCompos private void assertTableMetaData(final AssertionTestParameter testParam, final SingleE2EContainerComposer containerComposer) throws SQLException { String tableName = containerComposer.getAssertion().getInitialSQL().getAffectedTable(); DataSetMetaData expected = containerComposer.getDataSet().findMetaData(tableName); - Collection dataNodes = InlineExpressionParserFactory.newInstance().splitAndEvaluate(expected.getDataNodes()).stream().map(DataNode::new).collect(Collectors.toList()); + Collection dataNodes = InlineExpressionParserFactory.newInstance(expected.getDataNodes()).splitAndEvaluate().stream().map(DataNode::new).collect(Collectors.toList()); if (expected.getColumns().isEmpty()) { assertNotContainsTable(containerComposer, dataNodes); return; diff --git a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BaseDMLE2EIT.java b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BaseDMLE2EIT.java index e1a71a5cf6db2..022e253ea237c 100644 --- a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BaseDMLE2EIT.java +++ b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BaseDMLE2EIT.java @@ -91,9 +91,9 @@ protected final void assertDataSet(final AssertionTestParameter testParam, final assertDataSet(testParam, containerComposer, each); } } - + private void assertDataSet(final AssertionTestParameter testParam, final SingleE2EContainerComposer containerComposer, final DataSetMetaData expectedDataSetMetaData) throws SQLException { - for (String each : InlineExpressionParserFactory.newInstance().splitAndEvaluate(expectedDataSetMetaData.getDataNodes())) { + for (String each : InlineExpressionParserFactory.newInstance(expectedDataSetMetaData.getDataNodes()).splitAndEvaluate()) { DataNode dataNode = new DataNode(each); DataSource dataSource = containerComposer.getActualDataSourceMap().get(dataNode.getDataSourceName()); try ( diff --git a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/env/DataSetEnvironmentManager.java b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/env/DataSetEnvironmentManager.java index a611f55a036cf..8fb260e443d98 100644 --- a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/env/DataSetEnvironmentManager.java +++ b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/env/DataSetEnvironmentManager.java @@ -167,7 +167,7 @@ private Map> getDataNodeMap() { private Map> getDataNodeMap(final DataSetMetaData dataSetMetaData) { Map> result = new LinkedHashMap<>(); - for (String each : InlineExpressionParserFactory.newInstance().splitAndEvaluate(dataSetMetaData.getDataNodes())) { + for (String each : InlineExpressionParserFactory.newInstance(dataSetMetaData.getDataNodes()).splitAndEvaluate()) { DataNode dataNode = new DataNode(each); if (!result.containsKey(dataNode.getDataSourceName())) { result.put(dataNode.getDataSourceName(), new LinkedList<>());