diff --git a/sharding-core/sharding-core-entry/src/main/java/org/apache/shardingsphere/core/BaseShardingEngine.java b/sharding-core/sharding-core-entry/src/main/java/org/apache/shardingsphere/core/BaseShardingEngine.java index 08bea380eda69..b182a2575bc03 100644 --- a/sharding-core/sharding-core-entry/src/main/java/org/apache/shardingsphere/core/BaseShardingEngine.java +++ b/sharding-core/sharding-core-entry/src/main/java/org/apache/shardingsphere/core/BaseShardingEngine.java @@ -83,7 +83,7 @@ private Collection convert(final String sql, final List param } private Collection rewriteAndConvert(final String sql, final List parameters, final SQLRouteResult sqlRouteResult) { - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, sql, databaseType, sqlRouteResult.getSqlStatement(), parameters, sqlRouteResult.getOptimizeResult()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, sql, databaseType, sqlRouteResult, parameters, sqlRouteResult.getOptimizeResult()); SQLBuilder sqlBuilder = rewriteEngine.rewrite(sqlRouteResult.getRoutingResult().isSingleRouting()); Collection result = new LinkedHashSet<>(); for (TableUnit each : sqlRouteResult.getRoutingResult().getTableUnits().getTableUnits()) { diff --git a/sharding-core/sharding-core-merge/src/main/java/org/apache/shardingsphere/core/merge/MergeEngineFactory.java b/sharding-core/sharding-core-merge/src/main/java/org/apache/shardingsphere/core/merge/MergeEngineFactory.java index 25bd074db29aa..57f5ad6056271 100644 --- a/sharding-core/sharding-core-merge/src/main/java/org/apache/shardingsphere/core/merge/MergeEngineFactory.java +++ b/sharding-core/sharding-core-merge/src/main/java/org/apache/shardingsphere/core/merge/MergeEngineFactory.java @@ -24,9 +24,9 @@ import org.apache.shardingsphere.core.merge.dal.DALMergeEngine; import org.apache.shardingsphere.core.merge.dql.DQLMergeEngine; import org.apache.shardingsphere.core.metadata.table.ShardingTableMetaData; -import org.apache.shardingsphere.core.parse.parser.sql.SQLStatement; import org.apache.shardingsphere.core.parse.parser.sql.dal.DALStatement; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.apache.shardingsphere.core.rule.ShardingRule; import java.sql.SQLException; @@ -46,20 +46,20 @@ public final class MergeEngineFactory { * * @param databaseType database type * @param shardingRule sharding rule - * @param sqlStatement SQL statement + * @param routeResult SQL route result * @param shardingTableMetaData sharding table meta Data * @param queryResults query results * @return merge engine instance * @throws SQLException SQL exception */ - public static MergeEngine newInstance(final DatabaseType databaseType, final ShardingRule shardingRule, - final SQLStatement sqlStatement, final ShardingTableMetaData shardingTableMetaData, final List queryResults) throws SQLException { - if (sqlStatement instanceof SelectStatement) { - return new DQLMergeEngine(databaseType, (SelectStatement) sqlStatement, queryResults); + public static MergeEngine newInstance(final DatabaseType databaseType, final ShardingRule shardingRule, + final SQLRouteResult routeResult, final ShardingTableMetaData shardingTableMetaData, final List queryResults) throws SQLException { + if (routeResult.getSqlStatement() instanceof SelectStatement) { + return new DQLMergeEngine(databaseType, routeResult, queryResults); } - if (sqlStatement instanceof DALStatement) { - return new DALMergeEngine(shardingRule, queryResults, (DALStatement) sqlStatement, shardingTableMetaData); + if (routeResult.getSqlStatement() instanceof DALStatement) { + return new DALMergeEngine(shardingRule, queryResults, (DALStatement) routeResult.getSqlStatement(), shardingTableMetaData); } - throw new UnsupportedOperationException(String.format("Cannot support type '%s'", sqlStatement.getType())); + throw new UnsupportedOperationException(String.format("Cannot support type '%s'", routeResult.getSqlStatement().getType())); } } diff --git a/sharding-core/sharding-core-merge/src/main/java/org/apache/shardingsphere/core/merge/dql/DQLMergeEngine.java b/sharding-core/sharding-core-merge/src/main/java/org/apache/shardingsphere/core/merge/dql/DQLMergeEngine.java index 555985197aaee..22c6f63c2fbce 100644 --- a/sharding-core/sharding-core-merge/src/main/java/org/apache/shardingsphere/core/merge/dql/DQLMergeEngine.java +++ b/sharding-core/sharding-core-merge/src/main/java/org/apache/shardingsphere/core/merge/dql/DQLMergeEngine.java @@ -36,6 +36,7 @@ import org.apache.shardingsphere.core.parse.parser.context.limit.Limit; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; import org.apache.shardingsphere.core.parse.util.SQLUtil; +import org.apache.shardingsphere.core.route.SQLRouteResult; import java.sql.SQLException; import java.util.ArrayList; @@ -53,6 +54,8 @@ public final class DQLMergeEngine implements MergeEngine { private final DatabaseType databaseType; + private final SQLRouteResult routeResult; + private final SelectStatement selectStatement; private final List queryResults; @@ -60,9 +63,10 @@ public final class DQLMergeEngine implements MergeEngine { @Getter private final Map columnLabelIndexMap; - public DQLMergeEngine(final DatabaseType databaseType, final SelectStatement selectStatement, final List queryResults) throws SQLException { + public DQLMergeEngine(final DatabaseType databaseType, final SQLRouteResult routeResult, final List queryResults) throws SQLException { this.databaseType = databaseType; - this.selectStatement = selectStatement; + this.routeResult = routeResult; + this.selectStatement = (SelectStatement) routeResult.getSqlStatement(); this.queryResults = getRealQueryResults(queryResults); columnLabelIndexMap = getColumnLabelIndexMap(this.queryResults.get(0)); } @@ -131,18 +135,18 @@ private MergedResult getGroupByMergedResult() throws SQLException { } private MergedResult decorate(final MergedResult mergedResult) throws SQLException { - Limit limit = selectStatement.getLimit(); + Limit limit = routeResult.getLimit(); if (null == limit || 1 == queryResults.size()) { return mergedResult; } if (DatabaseType.MySQL == databaseType || DatabaseType.PostgreSQL == databaseType || DatabaseType.H2 == databaseType) { - return new LimitDecoratorMergedResult(mergedResult, selectStatement.getLimit()); + return new LimitDecoratorMergedResult(mergedResult, routeResult.getLimit()); } if (DatabaseType.Oracle == databaseType) { - return new RowNumberDecoratorMergedResult(mergedResult, selectStatement.getLimit()); + return new RowNumberDecoratorMergedResult(mergedResult, routeResult.getLimit()); } if (DatabaseType.SQLServer == databaseType) { - return new TopAndRowNumberDecoratorMergedResult(mergedResult, selectStatement.getLimit()); + return new TopAndRowNumberDecoratorMergedResult(mergedResult, routeResult.getLimit()); } return mergedResult; } diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/AllMergerTests.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/AllMergerTests.java index 1d1983ed87630..43357ec6ff0e5 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/AllMergerTests.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/AllMergerTests.java @@ -68,6 +68,6 @@ ShowOtherMergedResultTest.class, ShowTablesMergedResultTest.class, MergeEngineFactoryTest.class - }) +}) public final class AllMergerTests { } diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/MergeEngineFactoryTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/MergeEngineFactoryTest.java index 0c1b7be20d662..b188d12606eae 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/MergeEngineFactoryTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/MergeEngineFactoryTest.java @@ -23,10 +23,11 @@ import org.apache.shardingsphere.core.merge.dal.DALMergeEngine; import org.apache.shardingsphere.core.merge.dql.DQLMergeEngine; import org.apache.shardingsphere.core.merge.fixture.TestQueryResult; -import org.apache.shardingsphere.core.parse.parser.sql.SQLStatement; +import org.apache.shardingsphere.core.parse.parser.context.limit.Limit; import org.apache.shardingsphere.core.parse.parser.sql.dal.DALStatement; import org.apache.shardingsphere.core.parse.parser.sql.dml.insert.InsertStatement; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -59,19 +60,20 @@ public void setUp() throws SQLException { @Test public void assertNewInstanceWithSelectStatement() throws SQLException { - SQLStatement selectStatement = new SelectStatement(); - assertThat(MergeEngineFactory.newInstance(DatabaseType.MySQL, null, selectStatement, null, queryResults), instanceOf(DQLMergeEngine.class)); + SQLRouteResult routeResult = new SQLRouteResult(new SelectStatement()); + routeResult.setLimit(new Limit()); + assertThat(MergeEngineFactory.newInstance(DatabaseType.MySQL, null, routeResult, null, queryResults), instanceOf(DQLMergeEngine.class)); } @Test public void assertNewInstanceWithDALStatement() throws SQLException { - SQLStatement dalStatement = new DALStatement(); - assertThat(MergeEngineFactory.newInstance(DatabaseType.MySQL, null, dalStatement, null, queryResults), instanceOf(DALMergeEngine.class)); + SQLRouteResult routeResult = new SQLRouteResult(new DALStatement()); + assertThat(MergeEngineFactory.newInstance(DatabaseType.MySQL, null, routeResult, null, queryResults), instanceOf(DALMergeEngine.class)); } @Test(expected = UnsupportedOperationException.class) public void assertNewInstanceWithOtherStatement() throws SQLException { - SQLStatement insertStatement = new InsertStatement(); - MergeEngineFactory.newInstance(DatabaseType.MySQL, null, insertStatement, null, queryResults); + SQLRouteResult routeResult = new SQLRouteResult(new InsertStatement()); + MergeEngineFactory.newInstance(DatabaseType.MySQL, null, routeResult, null, queryResults); } } diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/DQLMergeEngineTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/DQLMergeEngineTest.java index 1191930e4cffd..67cbef7c2d316 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/DQLMergeEngineTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/DQLMergeEngineTest.java @@ -36,6 +36,7 @@ import org.apache.shardingsphere.core.parse.parser.context.orderby.OrderItem; import org.apache.shardingsphere.core.parse.parser.context.selectitem.AggregationSelectItem; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -61,6 +62,8 @@ public final class DQLMergeEngineTest { private SelectStatement selectStatement; + private SQLRouteResult routeResult; + @Before public void setUp() throws SQLException { ResultSet resultSet = mock(ResultSet.class); @@ -76,25 +79,26 @@ public void setUp() throws SQLException { queryResults.add(new TestQueryResult(each)); } selectStatement = new SelectStatement(); + routeResult = new SQLRouteResult(selectStatement); } @Test public void assertBuildIteratorStreamMergedResult() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); assertThat(mergeEngine.merge(), instanceOf(IteratorStreamMergedResult.class)); } @Test public void assertBuildIteratorStreamMergedResultWithLimit() throws SQLException { selectStatement.setLimit(new Limit()); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, singleQueryResult); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, singleQueryResult); assertThat(mergeEngine.merge(), instanceOf(IteratorStreamMergedResult.class)); } @Test public void assertBuildIteratorStreamMergedResultWithMySQLLimit() throws SQLException { - selectStatement.setLimit(new Limit()); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + routeResult.setLimit(new Limit()); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(LimitDecoratorMergedResult.class)); assertThat(((LimitDecoratorMergedResult) actual).getMergedResult(), instanceOf(IteratorStreamMergedResult.class)); @@ -102,8 +106,8 @@ public void assertBuildIteratorStreamMergedResultWithMySQLLimit() throws SQLExce @Test public void assertBuildIteratorStreamMergedResultWithOracleLimit() throws SQLException { - selectStatement.setLimit(new Limit()); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + routeResult.setLimit(new Limit()); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class)); assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(IteratorStreamMergedResult.class)); @@ -111,8 +115,8 @@ public void assertBuildIteratorStreamMergedResultWithOracleLimit() throws SQLExc @Test public void assertBuildIteratorStreamMergedResultWithSQLServerLimit() throws SQLException { - selectStatement.setLimit(new Limit()); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + routeResult.setLimit(new Limit()); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(TopAndRowNumberDecoratorMergedResult.class)); assertThat(((TopAndRowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(IteratorStreamMergedResult.class)); @@ -121,15 +125,15 @@ public void assertBuildIteratorStreamMergedResultWithSQLServerLimit() throws SQL @Test public void assertBuildOrderByStreamMergedResult() throws SQLException { selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); assertThat(mergeEngine.merge(), instanceOf(OrderByStreamMergedResult.class)); } @Test public void assertBuildOrderByStreamMergedResultWithMySQLLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(LimitDecoratorMergedResult.class)); assertThat(((LimitDecoratorMergedResult) actual).getMergedResult(), instanceOf(OrderByStreamMergedResult.class)); @@ -137,9 +141,9 @@ public void assertBuildOrderByStreamMergedResultWithMySQLLimit() throws SQLExcep @Test public void assertBuildOrderByStreamMergedResultWithOracleLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class)); assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(OrderByStreamMergedResult.class)); @@ -147,9 +151,9 @@ public void assertBuildOrderByStreamMergedResultWithOracleLimit() throws SQLExce @Test public void assertBuildOrderByStreamMergedResultWithSQLServerLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(TopAndRowNumberDecoratorMergedResult.class)); assertThat(((TopAndRowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(OrderByStreamMergedResult.class)); @@ -159,16 +163,16 @@ public void assertBuildOrderByStreamMergedResultWithSQLServerLimit() throws SQLE public void assertBuildGroupByStreamMergedResult() throws SQLException { selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); assertThat(mergeEngine.merge(), instanceOf(GroupByStreamMergedResult.class)); } @Test public void assertBuildGroupByStreamMergedResultWithMySQLLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(LimitDecoratorMergedResult.class)); assertThat(((LimitDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByStreamMergedResult.class)); @@ -176,10 +180,10 @@ public void assertBuildGroupByStreamMergedResultWithMySQLLimit() throws SQLExcep @Test public void assertBuildGroupByStreamMergedResultWithOracleLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class)); assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByStreamMergedResult.class)); @@ -187,10 +191,10 @@ public void assertBuildGroupByStreamMergedResultWithOracleLimit() throws SQLExce @Test public void assertBuildGroupByStreamMergedResultWithSQLServerLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(TopAndRowNumberDecoratorMergedResult.class)); assertThat(((TopAndRowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByStreamMergedResult.class)); @@ -199,15 +203,15 @@ public void assertBuildGroupByStreamMergedResultWithSQLServerLimit() throws SQLE @Test public void assertBuildGroupByMemoryMergedResult() throws SQLException { selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); assertThat(mergeEngine.merge(), instanceOf(GroupByMemoryMergedResult.class)); } @Test public void assertBuildGroupByMemoryMergedResultWithMySQLLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(LimitDecoratorMergedResult.class)); assertThat(((LimitDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByMemoryMergedResult.class)); @@ -215,10 +219,10 @@ public void assertBuildGroupByMemoryMergedResultWithMySQLLimit() throws SQLExcep @Test public void assertBuildGroupByMemoryMergedResultWithOracleLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); selectStatement.getOrderByItems().add(new OrderItem(2, OrderDirection.DESC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class)); assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByMemoryMergedResult.class)); @@ -226,10 +230,10 @@ public void assertBuildGroupByMemoryMergedResultWithOracleLimit() throws SQLExce @Test public void assertBuildGroupByMemoryMergedResultWithSQLServerLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.DESC, OrderDirection.ASC)); selectStatement.getGroupByItems().add(new OrderItem(1, OrderDirection.ASC, OrderDirection.ASC)); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(TopAndRowNumberDecoratorMergedResult.class)); assertThat(((TopAndRowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByMemoryMergedResult.class)); @@ -238,15 +242,15 @@ public void assertBuildGroupByMemoryMergedResultWithSQLServerLimit() throws SQLE @Test public void assertBuildGroupByMemoryMergedResultWithAggregationOnly() throws SQLException { selectStatement.getItems().add(new AggregationSelectItem(AggregationType.COUNT, "(*)", Optional.absent())); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); assertThat(mergeEngine.merge(), instanceOf(GroupByMemoryMergedResult.class)); } @Test public void assertBuildGroupByMemoryMergedResultWithAggregationOnlyWithMySQLLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getItems().add(new AggregationSelectItem(AggregationType.COUNT, "(*)", Optional.absent())); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(LimitDecoratorMergedResult.class)); assertThat(((LimitDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByMemoryMergedResult.class)); @@ -254,9 +258,9 @@ public void assertBuildGroupByMemoryMergedResultWithAggregationOnlyWithMySQLLimi @Test public void assertBuildGroupByMemoryMergedResultWithAggregationOnlyWithOracleLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getItems().add(new AggregationSelectItem(AggregationType.COUNT, "(*)", Optional.absent())); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class)); assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByMemoryMergedResult.class)); @@ -264,9 +268,9 @@ public void assertBuildGroupByMemoryMergedResultWithAggregationOnlyWithOracleLim @Test public void assertBuildGroupByMemoryMergedResultWithAggregationOnlyWithSQLServerLimit() throws SQLException { - selectStatement.setLimit(new Limit()); + routeResult.setLimit(new Limit()); selectStatement.getItems().add(new AggregationSelectItem(AggregationType.COUNT, "(*)", Optional.absent())); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertThat(actual, instanceOf(TopAndRowNumberDecoratorMergedResult.class)); assertThat(((TopAndRowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByMemoryMergedResult.class)); diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/groupby/GroupByMemoryMergedResultTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/groupby/GroupByMemoryMergedResultTest.java index 259a1657ee1c3..d5be0c6ebbcb2 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/groupby/GroupByMemoryMergedResultTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/groupby/GroupByMemoryMergedResultTest.java @@ -29,6 +29,7 @@ import org.apache.shardingsphere.core.parse.parser.context.orderby.OrderItem; import org.apache.shardingsphere.core.parse.parser.context.selectitem.AggregationSelectItem; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -56,6 +57,8 @@ public final class GroupByMemoryMergedResultTest { private SelectStatement selectStatement; + private SQLRouteResult routeResult; + @Before public void setUp() throws SQLException { resultSets = Lists.newArrayList(mockResultSet(), mockResultSet(), mockResultSet()); @@ -78,6 +81,8 @@ public void setUp() throws SQLException { selectStatement.getItems().add(aggregationSelectItem2); selectStatement.getGroupByItems().add(new OrderItem(3, OrderDirection.ASC, OrderDirection.ASC)); selectStatement.getOrderByItems().add(new OrderItem(3, OrderDirection.DESC, OrderDirection.ASC)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); } private ResultSet mockResultSet() throws SQLException { @@ -95,14 +100,14 @@ private ResultSet mockResultSet() throws SQLException { @Test public void assertNextForResultSetsAllEmpty() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertFalse(actual.next()); } @Test public void assertNextForSomeResultSetsEmpty() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); when(resultSets.get(0).next()).thenReturn(true, false); when(resultSets.get(0).getObject(1)).thenReturn(20); when(resultSets.get(0).getObject(2)).thenReturn(0); diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/groupby/GroupByStreamMergedResultTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/groupby/GroupByStreamMergedResultTest.java index 82ad8247c0490..b61e0b80b0a47 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/groupby/GroupByStreamMergedResultTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/groupby/GroupByStreamMergedResultTest.java @@ -29,6 +29,7 @@ import org.apache.shardingsphere.core.parse.parser.context.orderby.OrderItem; import org.apache.shardingsphere.core.parse.parser.context.selectitem.AggregationSelectItem; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -58,6 +59,8 @@ public final class GroupByStreamMergedResultTest { private SelectStatement selectStatement; + private SQLRouteResult routeResult; + @Before public void setUp() throws SQLException { resultSets = Lists.newArrayList(mockResultSet(), mockResultSet(), mockResultSet()); @@ -80,6 +83,8 @@ public void setUp() throws SQLException { selectStatement.getItems().add(aggregationSelectItem2); selectStatement.getGroupByItems().add(new OrderItem(3, OrderDirection.ASC, OrderDirection.ASC)); selectStatement.getOrderByItems().add(new OrderItem(3, OrderDirection.ASC, OrderDirection.ASC)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); } private ResultSet mockResultSet() throws SQLException { @@ -98,14 +103,14 @@ private ResultSet mockResultSet() throws SQLException { @Test public void assertNextForResultSetsAllEmpty() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertFalse(actual.next()); } @Test public void assertNextForSomeResultSetsEmpty() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); when(resultSets.get(0).next()).thenReturn(true, false); when(resultSets.get(0).getObject(1)).thenReturn(20); when(resultSets.get(0).getObject(2)).thenReturn(0); @@ -147,7 +152,7 @@ public void assertNextForSomeResultSetsEmpty() throws SQLException { @Test public void assertNextForMix() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); when(resultSets.get(0).next()).thenReturn(true, false); when(resultSets.get(0).getObject(1)).thenReturn(20); when(resultSets.get(0).getObject(2)).thenReturn(0); diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/iterator/IteratorStreamMergedResultTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/iterator/IteratorStreamMergedResultTest.java index 7ddeeaa2c7dc6..ef0136b96b011 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/iterator/IteratorStreamMergedResultTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/iterator/IteratorStreamMergedResultTest.java @@ -24,6 +24,7 @@ import org.apache.shardingsphere.core.merge.dql.DQLMergeEngine; import org.apache.shardingsphere.core.merge.fixture.TestQueryResult; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -45,6 +46,8 @@ public final class IteratorStreamMergedResultTest { private SelectStatement selectStatement; + private SQLRouteResult routeResult; + @Before public void setUp() throws SQLException { ResultSet resultSet = mock(ResultSet.class); @@ -53,11 +56,13 @@ public void setUp() throws SQLException { queryResults = Lists.newArrayList( new TestQueryResult(resultSet), new TestQueryResult(mock(ResultSet.class)), new TestQueryResult(mock(ResultSet.class))); selectStatement = new SelectStatement(); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); } @Test public void assertNextForResultSetsAllEmpty() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertFalse(actual.next()); } @@ -67,7 +72,7 @@ public void assertNextForResultSetsAllNotEmpty() throws SQLException { for (QueryResult each : queryResults) { when(each.next()).thenReturn(true, false); } - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertTrue(actual.next()); @@ -78,7 +83,7 @@ public void assertNextForResultSetsAllNotEmpty() throws SQLException { @Test public void assertNextForFirstResultSetsNotEmptyOnly() throws SQLException { when(queryResults.get(0).next()).thenReturn(true, false); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertFalse(actual.next()); @@ -87,7 +92,7 @@ public void assertNextForFirstResultSetsNotEmptyOnly() throws SQLException { @Test public void assertNextForMiddleResultSetsNotEmpty() throws SQLException { when(queryResults.get(1).next()).thenReturn(true, false); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertFalse(actual.next()); @@ -96,7 +101,7 @@ public void assertNextForMiddleResultSetsNotEmpty() throws SQLException { @Test public void assertNextForLastResultSetsNotEmptyOnly() throws SQLException { when(queryResults.get(2).next()).thenReturn(true, false); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertFalse(actual.next()); @@ -110,7 +115,7 @@ public void assertNextForMix() throws SQLException { when(queryResults.get(1).next()).thenReturn(true, false); when(queryResults.get(3).next()).thenReturn(true, false); when(queryResults.get(5).next()).thenReturn(true, false); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertTrue(actual.next()); diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/orderby/OrderByStreamMergedResultTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/orderby/OrderByStreamMergedResultTest.java index c2fb58168ce99..57d531bc78892 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/orderby/OrderByStreamMergedResultTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/orderby/OrderByStreamMergedResultTest.java @@ -26,6 +26,7 @@ import org.apache.shardingsphere.core.merge.fixture.TestQueryResult; import org.apache.shardingsphere.core.parse.parser.context.orderby.OrderItem; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -49,6 +50,8 @@ public final class OrderByStreamMergedResultTest { private SelectStatement selectStatement; + private SQLRouteResult routeResult; + @Before public void setUp() throws SQLException { ResultSet resultSet = mock(ResultSet.class); @@ -58,18 +61,20 @@ public void setUp() throws SQLException { new TestQueryResult(resultSet), new TestQueryResult(mock(ResultSet.class)), new TestQueryResult(mock(ResultSet.class))); selectStatement = new SelectStatement(); selectStatement.getOrderByItems().add(new OrderItem(1, OrderDirection.ASC, OrderDirection.ASC)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); } @Test public void assertNextForResultSetsAllEmpty() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertFalse(actual.next()); } @Test public void assertNextForSomeResultSetsEmpty() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); when(queryResults.get(0).next()).thenReturn(true, false); when(queryResults.get(0).getValue(1, Object.class)).thenReturn("2"); when(queryResults.get(2).next()).thenReturn(true, true, false); @@ -86,7 +91,7 @@ public void assertNextForSomeResultSetsEmpty() throws SQLException { @Test public void assertNextForMix() throws SQLException { - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); when(queryResults.get(0).next()).thenReturn(true, false); when(queryResults.get(0).getValue(1, Object.class)).thenReturn("2"); when(queryResults.get(1).next()).thenReturn(true, true, true, false); diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/LimitDecoratorMergedResultTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/LimitDecoratorMergedResultTest.java index 29cbdd2c846a8..5a75508c71a31 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/LimitDecoratorMergedResultTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/LimitDecoratorMergedResultTest.java @@ -26,6 +26,7 @@ import org.apache.shardingsphere.core.parse.parser.context.limit.Limit; import org.apache.shardingsphere.core.parse.parser.context.limit.LimitValue; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -48,6 +49,8 @@ public final class LimitDecoratorMergedResultTest { private SelectStatement selectStatement; + private SQLRouteResult routeResult; + @Before public void setUp() throws SQLException { ResultSet resultSet = mock(ResultSet.class); @@ -62,14 +65,16 @@ public void setUp() throws SQLException { queryResults.add(new TestQueryResult(each)); } selectStatement = new SelectStatement(); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); } @Test public void assertNextForSkipAll() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(Integer.MAX_VALUE, -1, true)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertFalse(actual.next()); } @@ -78,8 +83,8 @@ public void assertNextForSkipAll() throws SQLException { public void assertNextWithoutRowCount() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(2, -1, true)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); for (int i = 0; i < 6; i++) { assertTrue(actual.next()); @@ -92,8 +97,8 @@ public void assertNextWithRowCount() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(2, -1, true)); limit.setRowCount(new LimitValue(2, -1, false)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertTrue(actual.next()); diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java index 8e0a6af64d42e..dc1ec492a8017 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java @@ -26,6 +26,7 @@ import org.apache.shardingsphere.core.parse.parser.context.limit.Limit; import org.apache.shardingsphere.core.parse.parser.context.limit.LimitValue; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -48,6 +49,8 @@ public final class RowNumberDecoratorMergedResultTest { private SelectStatement selectStatement; + private SQLRouteResult routeResult; + @Before public void setUp() throws SQLException { ResultSet resultSet = mock(ResultSet.class); @@ -62,23 +65,23 @@ public void setUp() throws SQLException { queryResults.add(new TestQueryResult(each)); } selectStatement = new SelectStatement(); + routeResult = new SQLRouteResult(selectStatement); } @Test public void assertNextForSkipAll() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(Integer.MAX_VALUE, -1, true)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertFalse(actual.next()); } @Test public void assertNextWithoutOffsetWithoutRowCount() throws SQLException { - Limit limit = new Limit(); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + routeResult.setLimit(new Limit()); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); for (int i = 0; i < 8; i++) { assertTrue(actual.next()); @@ -91,8 +94,8 @@ public void assertNextForRowCountBoundOpenedFalse() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(2, -1, true)); limit.setRowCount(new LimitValue(4, -1, false)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertTrue(actual.next()); @@ -104,8 +107,8 @@ public void assertNextForRowCountBoundOpenedTrue() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(2, -1, true)); limit.setRowCount(new LimitValue(4, -1, true)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertTrue(actual.next()); diff --git a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/TopAndRowNumberDecoratorMergedResultTest.java b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/TopAndRowNumberDecoratorMergedResultTest.java index d3ced7f16dda6..f7153557919f1 100644 --- a/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/TopAndRowNumberDecoratorMergedResultTest.java +++ b/sharding-core/sharding-core-merge/src/test/java/org/apache/shardingsphere/core/merge/dql/pagination/TopAndRowNumberDecoratorMergedResultTest.java @@ -26,6 +26,7 @@ import org.apache.shardingsphere.core.parse.parser.context.limit.Limit; import org.apache.shardingsphere.core.parse.parser.context.limit.LimitValue; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.junit.Before; import org.junit.Test; @@ -48,6 +49,8 @@ public final class TopAndRowNumberDecoratorMergedResultTest { private SelectStatement selectStatement; + private SQLRouteResult routeResult; + @Before public void setUp() throws SQLException { ResultSet resultSet = mock(ResultSet.class); @@ -62,14 +65,15 @@ public void setUp() throws SQLException { queryResults.add(new TestQueryResult(each)); } selectStatement = new SelectStatement(); + routeResult = new SQLRouteResult(selectStatement); } @Test public void assertNextForSkipAll() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(Integer.MAX_VALUE, -1, true)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertFalse(actual.next()); } @@ -78,8 +82,8 @@ public void assertNextForSkipAll() throws SQLException { public void assertNextWithoutOffsetWithRowCount() throws SQLException { Limit limit = new Limit(); limit.setRowCount(new LimitValue(5, -1, false)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); for (int i = 0; i < 5; i++) { assertTrue(actual.next()); @@ -91,8 +95,8 @@ public void assertNextWithoutOffsetWithRowCount() throws SQLException { public void assertNextWithOffsetWithoutRowCount() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(2, -1, true)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); for (int i = 0; i < 7; i++) { assertTrue(actual.next()); @@ -105,8 +109,8 @@ public void assertNextWithOffsetBoundOpenedFalse() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(2, -1, false)); limit.setRowCount(new LimitValue(4, -1, false)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertTrue(actual.next()); @@ -118,8 +122,8 @@ public void assertNextWithOffsetBoundOpenedTrue() throws SQLException { Limit limit = new Limit(); limit.setOffset(new LimitValue(2, -1, true)); limit.setRowCount(new LimitValue(4, -1, false)); - selectStatement.setLimit(limit); - mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, selectStatement, queryResults); + routeResult.setLimit(limit); + mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults); MergedResult actual = mergeEngine.merge(); assertTrue(actual.next()); assertTrue(actual.next()); diff --git a/sharding-core/sharding-core-rewrite/src/main/java/org/apache/shardingsphere/core/rewrite/SQLRewriteEngine.java b/sharding-core/sharding-core-rewrite/src/main/java/org/apache/shardingsphere/core/rewrite/SQLRewriteEngine.java index bf99c08ed6590..df2b2783e374e 100644 --- a/sharding-core/sharding-core-rewrite/src/main/java/org/apache/shardingsphere/core/rewrite/SQLRewriteEngine.java +++ b/sharding-core/sharding-core-rewrite/src/main/java/org/apache/shardingsphere/core/rewrite/SQLRewriteEngine.java @@ -66,6 +66,7 @@ import org.apache.shardingsphere.core.rewrite.placeholder.SchemaPlaceholder; import org.apache.shardingsphere.core.rewrite.placeholder.ShardingPlaceholder; import org.apache.shardingsphere.core.rewrite.placeholder.TablePlaceholder; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.apache.shardingsphere.core.route.SQLUnit; import org.apache.shardingsphere.core.route.type.RoutingTable; import org.apache.shardingsphere.core.route.type.TableUnit; @@ -102,6 +103,8 @@ public final class SQLRewriteEngine { private final DatabaseType databaseType; + private final SQLRouteResult sqlRouteResult; + private final SQLStatement sqlStatement; private final List sqlTokens; @@ -120,16 +123,17 @@ public final class SQLRewriteEngine { * @param shardingRule databases and tables sharding rule * @param originalSQL original SQL * @param databaseType database type - * @param sqlStatement SQL statement + * @param sqlRouteResult SQL route result * @param parameters parameters */ - public SQLRewriteEngine(final ShardingRule shardingRule, - final String originalSQL, final DatabaseType databaseType, final SQLStatement sqlStatement, final List parameters, final OptimizeResult optimizeResult) { + public SQLRewriteEngine(final ShardingRule shardingRule, + final String originalSQL, final DatabaseType databaseType, final SQLRouteResult sqlRouteResult, final List parameters, final OptimizeResult optimizeResult) { this.shardingRule = shardingRule; this.originalSQL = originalSQL; this.databaseType = databaseType; - this.sqlStatement = sqlStatement; - sqlTokens = sqlStatement.getSQLTokens(); + this.sqlRouteResult = sqlRouteResult; + sqlStatement = sqlRouteResult.getSqlStatement(); + sqlTokens = sqlRouteResult.getSqlStatement().getSQLTokens(); this.parameters = parameters; appendedIndexAndParameters = new LinkedHashMap<>(); this.optimizeResult = optimizeResult; @@ -275,7 +279,7 @@ private void encryptInsertColumnValue(final InsertColumnValue insertColumnValue, private void appendLimitRowCount(final SQLBuilder sqlBuilder, final RowCountToken rowCountToken, final int count, final boolean isRewrite) { SelectStatement selectStatement = (SelectStatement) sqlStatement; - Limit limit = selectStatement.getLimit(); + Limit limit = sqlRouteResult.getLimit(); if (!isRewrite) { sqlBuilder.appendLiterals(String.valueOf(rowCountToken.getRowCount())); } else if ((!selectStatement.getGroupByItems().isEmpty() || !selectStatement.getAggregationSelectItems().isEmpty()) && !selectStatement.isSameGroupByAndOrderByItems()) { diff --git a/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/SQLRewriteEngineTest.java b/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/SQLRewriteEngineTest.java index ae00742b47adb..da938c4cfaf51 100644 --- a/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/SQLRewriteEngineTest.java +++ b/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/SQLRewriteEngineTest.java @@ -49,6 +49,7 @@ import org.apache.shardingsphere.core.parse.parser.token.RowCountToken; import org.apache.shardingsphere.core.parse.parser.token.SchemaToken; import org.apache.shardingsphere.core.parse.parser.token.TableToken; +import org.apache.shardingsphere.core.route.SQLRouteResult; import org.apache.shardingsphere.core.route.type.RoutingTable; import org.apache.shardingsphere.core.route.type.TableUnit; import org.apache.shardingsphere.core.rule.DataNode; @@ -82,6 +83,8 @@ public final class SQLRewriteEngineTest { private ShardingRule shardingRule; + private SQLRouteResult routeResult; + private SelectStatement selectStatement; private InsertStatement insertStatement; @@ -122,8 +125,10 @@ private Map getDataSourceURLs(final YamlRootShardingConfiguratio @Test public void assertRewriteWithoutChange() { + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT table_y.id FROM table_y WHERE table_y.id=?", DatabaseType.MySQL, selectStatement, Collections.singletonList(1), null); + "SELECT table_y.id FROM table_y WHERE table_y.id=?", DatabaseType.MySQL, routeResult, Collections.singletonList(1), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT table_y.id FROM table_y WHERE table_y.id=?")); } @@ -135,8 +140,10 @@ public void assertRewriteForTableName() { selectStatement.addSQLToken(new TableToken(7, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new TableToken(31, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new TableToken(47, "table_x", QuoteCharacter.NONE, 0)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT table_x.id, x.name FROM table_x x WHERE table_x.id=? AND x.name=?", DatabaseType.MySQL, selectStatement, parameters, null); + "SELECT table_x.id, x.name FROM table_x x WHERE table_x.id=? AND x.name=?", DatabaseType.MySQL, routeResult, parameters, null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT table_1.id, x.name FROM table_1 x WHERE table_1.id=? AND x.name=?")); } @@ -146,8 +153,10 @@ public void assertRewriteForOrderByAndGroupByDerivedColumns() { ItemsToken itemsToken = new ItemsToken(12); itemsToken.getItems().addAll(Arrays.asList("x.id as GROUP_BY_DERIVED_0", "x.name as ORDER_BY_DERIVED_0")); selectStatement.addSQLToken(itemsToken); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT x.age FROM table_x x GROUP BY x.id ORDER BY x.name", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + "SELECT x.age FROM table_x x GROUP BY x.id ORDER BY x.name", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is( "SELECT x.age, x.id as GROUP_BY_DERIVED_0, x.name as ORDER_BY_DERIVED_0 FROM table_1 x GROUP BY x.id ORDER BY x.name")); } @@ -158,7 +167,9 @@ public void assertRewriteForAggregationDerivedColumns() { ItemsToken itemsToken = new ItemsToken(17); itemsToken.getItems().addAll(Arrays.asList("COUNT(x.age) as AVG_DERIVED_COUNT_0", "SUM(x.age) as AVG_DERIVED_SUM_0")); selectStatement.addSQLToken(itemsToken); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT AVG(x.age) FROM table_x x", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT AVG(x.age) FROM table_x x", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is( "SELECT AVG(x.age), COUNT(x.age) as AVG_DERIVED_COUNT_0, SUM(x.age) as AVG_DERIVED_SUM_0 FROM table_1 x")); } @@ -183,8 +194,9 @@ public void assertRewriteForAutoGeneratedKeyColumn() { insertColumnValues.getColumnValues().get(0).getDataNodes().add(new DataNode("db0.table_1")); TableUnit tableUnit = new TableUnit("db0"); tableUnit.getRoutingTables().add(new RoutingTable("table_x", "table_1")); + routeResult = new SQLRouteResult(insertStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "INSERT INTO table_x (name, age) VALUES (?, ?)", - DatabaseType.MySQL, insertStatement, parameters, new OptimizeResult(insertColumnValues)); + DatabaseType.MySQL, routeResult, parameters, new OptimizeResult(insertColumnValues)); assertThat(rewriteEngine.rewrite(false).toSQL(tableUnit, tableTokens, null, shardingDataSourceMetaData).getSql(), is("INSERT INTO table_1 (name, age, id) VALUES (?, ?, ?)")); } @@ -208,8 +220,9 @@ public void assertRewriteForAutoGeneratedKeyColumnWithoutColumnsWithParameter() insertColumnValues.getColumnValues().get(0).getDataNodes().add(new DataNode("db0.table_1")); TableUnit tableUnit = new TableUnit("db0"); tableUnit.getRoutingTables().add(new RoutingTable("table_x", "table_1")); + routeResult = new SQLRouteResult(insertStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "INSERT INTO `table_x` VALUES (?)", DatabaseType.MySQL, insertStatement, parameters, new OptimizeResult(insertColumnValues)); + "INSERT INTO `table_x` VALUES (?)", DatabaseType.MySQL, routeResult, parameters, new OptimizeResult(insertColumnValues)); assertThat(rewriteEngine.rewrite(false).toSQL(tableUnit, tableTokens, null, shardingDataSourceMetaData).getSql(), is("INSERT INTO `table_1` (name, id) VALUES (?, ?)")); } @@ -229,8 +242,9 @@ public void assertRewriteForAutoGeneratedKeyColumnWithoutColumnsWithoutParameter insertColumnValues.getColumnValues().get(0).getDataNodes().add(new DataNode("db0.table_1")); TableUnit tableUnit = new TableUnit("db0"); tableUnit.getRoutingTables().add(new RoutingTable("table_x", "table_1")); + routeResult = new SQLRouteResult(insertStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "INSERT INTO `table_x` VALUES (10)", - DatabaseType.MySQL, insertStatement, Collections.emptyList(), new OptimizeResult(insertColumnValues)); + DatabaseType.MySQL, routeResult, Collections.emptyList(), new OptimizeResult(insertColumnValues)); assertThat(rewriteEngine.rewrite(false).toSQL(tableUnit, tableTokens, null, shardingDataSourceMetaData).getSql(), is("INSERT INTO `table_1` (name, id) VALUES (10, 1)")); } @@ -253,8 +267,9 @@ public void assertRewriteColumnWithoutColumnsWithoutParameter() { insertColumnValues.getColumnValues().get(0).getDataNodes().add(new DataNode("db0.table_1")); TableUnit tableUnit = new TableUnit("db0"); tableUnit.getRoutingTables().add(new RoutingTable("table_x", "table_1")); + routeResult = new SQLRouteResult(insertStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "INSERT INTO `table_x` VALUES (10, 1)", DatabaseType.MySQL, insertStatement, parameters, new OptimizeResult(insertColumnValues)); + "INSERT INTO `table_x` VALUES (10, 1)", DatabaseType.MySQL, routeResult, parameters, new OptimizeResult(insertColumnValues)); assertThat(rewriteEngine.rewrite(false).toSQL(tableUnit, tableTokens, null, shardingDataSourceMetaData).getSql(), is("INSERT INTO `table_1` (name, id) VALUES (10, 1)")); } @@ -277,8 +292,9 @@ public void assertRewriteColumnWithoutColumnsWithParameter() { insertColumnValues.getColumnValues().get(0).getDataNodes().add(new DataNode("db0.table_1")); TableUnit tableUnit = new TableUnit("db0"); tableUnit.getRoutingTables().add(new RoutingTable("table_x", "table_1")); + routeResult = new SQLRouteResult(insertStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "INSERT INTO `table_x` VALUES (?, ?)", DatabaseType.MySQL, insertStatement, parameters, new OptimizeResult(insertColumnValues)); + "INSERT INTO `table_x` VALUES (?, ?)", DatabaseType.MySQL, routeResult, parameters, new OptimizeResult(insertColumnValues)); assertThat(rewriteEngine.rewrite(false).toSQL(tableUnit, tableTokens, null, shardingDataSourceMetaData).getSql(), is("INSERT INTO `table_1` (name, id) VALUES (?, ?)")); } @@ -290,7 +306,9 @@ public void assertRewriteForLimit() { selectStatement.addSQLToken(new TableToken(17, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new OffsetToken(33, 2)); selectStatement.addSQLToken(new RowCountToken(36, 2)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT x.id FROM table_x x LIMIT 2, 2", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT x.id FROM table_x x LIMIT 2, 2", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT x.id FROM table_1 x LIMIT 0, 4")); } @@ -302,8 +320,10 @@ public void assertRewriteForRowNum() { selectStatement.addSQLToken(new TableToken(68, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new OffsetToken(119, 2)); selectStatement.addSQLToken(new RowCountToken(98, 4)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", - DatabaseType.Oracle, selectStatement, Collections.emptyList(), null); + DatabaseType.Oracle, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_1 x) row_ WHERE rownum<=4) t WHERE t.rownum_>0")); } @@ -316,9 +336,11 @@ public void assertRewriteForTopAndRowNumber() { selectStatement.addSQLToken(new TableToken(85, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new OffsetToken(123, 2)); selectStatement.addSQLToken(new RowCountToken(26, 4)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", - DatabaseType.SQLServer, selectStatement, Collections.emptyList(), null); + DatabaseType.SQLServer, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_1 x) AS row_ WHERE row_.rownum_>0")); } @@ -333,7 +355,9 @@ public void assertRewriteForLimitForMemoryGroupBy() { selectStatement.addSQLToken(new TableToken(17, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new OffsetToken(33, 2)); selectStatement.addSQLToken(new RowCountToken(36, 2)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT x.id FROM table_x x LIMIT 2, 2", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT x.id FROM table_x x LIMIT 2, 2", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT x.id FROM table_1 x LIMIT 0, 2147483647")); } @@ -347,8 +371,10 @@ public void assertRewriteForRowNumForMemoryGroupBy() { selectStatement.addSQLToken(new RowCountToken(98, 4)); selectStatement.getOrderByItems().add(new OrderItem("x", "id", OrderDirection.ASC, OrderDirection.ASC)); selectStatement.getGroupByItems().add(new OrderItem("x", "id", OrderDirection.DESC, OrderDirection.ASC)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", - DatabaseType.Oracle, selectStatement, Collections.emptyList(), null); + DatabaseType.Oracle, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_1 x) row_ WHERE rownum<=2147483647) t WHERE t.rownum_>0")); } @@ -363,9 +389,11 @@ public void assertRewriteForTopAndRowNumberForMemoryGroupBy() { selectStatement.addSQLToken(new RowCountToken(26, 4)); selectStatement.getOrderByItems().add(new OrderItem("x", "id", OrderDirection.ASC, OrderDirection.ASC)); selectStatement.getGroupByItems().add(new OrderItem("x", "id", OrderDirection.DESC, OrderDirection.ASC)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", - DatabaseType.SQLServer, selectStatement, Collections.emptyList(), null); + DatabaseType.SQLServer, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT * FROM (SELECT TOP(2147483647) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_1 x) AS row_ WHERE row_.rownum_>0")); } @@ -378,7 +406,9 @@ public void assertRewriteForLimitForNotRewriteLimit() { selectStatement.addSQLToken(new TableToken(17, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new OffsetToken(33, 2)); selectStatement.addSQLToken(new RowCountToken(36, 2)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT x.id FROM table_x x LIMIT 2, 2", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT x.id FROM table_x x LIMIT 2, 2", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT x.id FROM table_1 x LIMIT 2, 2")); } @@ -390,8 +420,10 @@ public void assertRewriteForRowNumForNotRewriteLimit() { selectStatement.addSQLToken(new TableToken(68, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new OffsetToken(119, 2)); selectStatement.addSQLToken(new RowCountToken(98, 4)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", - DatabaseType.Oracle, selectStatement, Collections.emptyList(), null); + DatabaseType.Oracle, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_1 x) row_ WHERE rownum<=4) t WHERE t.rownum_>2")); } @@ -404,9 +436,11 @@ public void assertRewriteForTopAndRowNumberForNotRewriteLimit() { selectStatement.addSQLToken(new TableToken(85, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new OffsetToken(123, 2)); selectStatement.addSQLToken(new RowCountToken(26, 4)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", - DatabaseType.SQLServer, selectStatement, Collections.emptyList(), null); + DatabaseType.SQLServer, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is("SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_1 x) AS row_ WHERE row_.rownum_>2")); } @@ -418,8 +452,10 @@ public void assertRewriteForDerivedOrderBy() { selectStatement.getOrderByItems().add(new OrderItem("x", "name", OrderDirection.DESC, OrderDirection.ASC)); selectStatement.addSQLToken(new TableToken(25, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new OrderByToken(61)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT x.id, x.name FROM table_x x GROUP BY x.id, x.name DESC", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + "SELECT x.id, x.name FROM table_x x GROUP BY x.id, x.name DESC", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, null, shardingDataSourceMetaData).getSql(), is( "SELECT x.id, x.name FROM table_1 x GROUP BY x.id, x.name DESC ORDER BY id ASC,name DESC ")); } @@ -434,8 +470,10 @@ public void assertGenerateSQL() { selectStatement.addSQLToken(new TableToken(58, "table_x", QuoteCharacter.NONE, 0)); selectStatement.getTables().add(new Table("table_x", Optional.of("x"))); selectStatement.getTables().add(new Table("table_y", Optional.of("y"))); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine sqlRewriteEngine = - new SQLRewriteEngine(shardingRule, "SELECT table_x.id, x.name FROM table_x x, table_y y WHERE table_x.id=? AND x.name=?", DatabaseType.MySQL, selectStatement, parameters, null); + new SQLRewriteEngine(shardingRule, "SELECT table_x.id, x.name FROM table_x x, table_y y WHERE table_x.id=? AND x.name=?", DatabaseType.MySQL, routeResult, parameters, null); SQLBuilder sqlBuilder = sqlRewriteEngine.rewrite(false); TableUnit tableUnit = new TableUnit("db0"); tableUnit.getRoutingTables().add(new RoutingTable("table_x", "table_x")); @@ -448,7 +486,9 @@ public void assertSchemaTokenRewriteForTableName() { tableTokens.put("table_x", "table_y"); selectStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.NONE, 0)); selectStatement.addSQLToken(new SchemaToken(29, 35, "table_x")); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW CREATE TABLE table_x ON table_x", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW CREATE TABLE table_x ON table_x", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW CREATE TABLE table_y ON db0")); } @@ -456,7 +496,9 @@ public void assertSchemaTokenRewriteForTableName() { public void assertIndexTokenForIndexNameTableName() { selectStatement.addSQLToken(new IndexToken(13, 22, "table_x")); selectStatement.addSQLToken(new TableToken(27, "table_x", QuoteCharacter.NONE, 0)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "CREATE INDEX index_name ON table_x ('column')", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "CREATE INDEX index_name ON table_x ('column')", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("CREATE INDEX index_name_table_1 ON table_1 ('column')")); } @@ -464,14 +506,17 @@ public void assertIndexTokenForIndexNameTableName() { public void assertIndexTokenForIndexNameTableNameWithoutLogicTableName() { selectStatement.addSQLToken(new IndexToken(13, 23, "")); selectStatement.addSQLToken(new TableToken(28, "table_x", QuoteCharacter.NONE, 0)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "CREATE INDEX logic_index ON table_x ('column')", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "CREATE INDEX logic_index ON table_x ('column')", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("CREATE INDEX logic_index_table_1 ON table_1 ('column')")); } @Test public void assertTableTokenWithoutBackQuoteForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.NONE, 0)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM table_x", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(showTablesStatement); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM table_x", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM table_1")); } @@ -479,7 +524,8 @@ public void assertTableTokenWithoutBackQuoteForShow() { public void assertTableTokenWithoutBackQuoteFromSchemaForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.NONE, 0)); showTablesStatement.addSQLToken(new SchemaToken(31, 43, "table_x")); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM table_x FROM 'sharding_db'", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(showTablesStatement); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM table_x FROM 'sharding_db'", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); Map logicAndActualTableMap = new LinkedHashMap<>(); logicAndActualTableMap.put("table_x", "table_x"); assertThat(rewriteEngine.rewrite(true).toSQL(null, logicAndActualTableMap, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM table_x FROM db0")); @@ -488,74 +534,85 @@ public void assertTableTokenWithoutBackQuoteFromSchemaForShow() { @Test public void assertTableTokenWithBackQuoteForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.BACK_QUOTE, 0)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM `table_x`", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(showTablesStatement); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM `table_x`", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM `table_1`")); } @Test public void assertTableTokenWithBackQuoteFromSchemaForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.BACK_QUOTE, 0)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM `table_x` FROM 'sharding_db'", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(showTablesStatement); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM `table_x` FROM 'sharding_db'", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM `table_1` FROM 'sharding_db'")); } @Test public void assertTableTokenWithSchemaForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.NONE, "sharding_db".length() + 1)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM sharding_db.table_x", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(showTablesStatement); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM sharding_db.table_x", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM table_1")); } @Test public void assertTableTokenWithSchemaFromSchemaForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.NONE, "sharding_db".length() + 1)); + routeResult = new SQLRouteResult(showTablesStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SHOW COLUMNS FROM sharding_db.table_x FROM sharding_db", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + "SHOW COLUMNS FROM sharding_db.table_x FROM sharding_db", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM table_1 FROM sharding_db")); } @Test public void assertTableTokenWithBackQuoteWithSchemaForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.BACK_QUOTE, "sharding_db".length() + 1)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM sharding_db.`table_x`", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(showTablesStatement); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM sharding_db.`table_x`", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM `table_1`")); } @Test public void assertTableTokenWithBackQuoteWithSchemaFromSchemaForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.BACK_QUOTE, "sharding_db".length() + 1)); + routeResult = new SQLRouteResult(showTablesStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SHOW COLUMNS FROM sharding_db.`table_x` FROM sharding_db", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + "SHOW COLUMNS FROM sharding_db.`table_x` FROM sharding_db", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM `table_1` FROM sharding_db")); } @Test public void assertTableTokenWithSchemaWithBackQuoteForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.BACK_QUOTE, "`sharding_db`".length() + 1)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM `sharding_db`.`table_x`", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(showTablesStatement); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SHOW COLUMNS FROM `sharding_db`.`table_x`", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM `table_1`")); } @Test public void assertTableTokenWithSchemaWithBackQuoteFromSchemaForShow() { showTablesStatement.addSQLToken(new TableToken(18, "table_x", QuoteCharacter.BACK_QUOTE, "`sharding_db`".length() + 1)); + routeResult = new SQLRouteResult(showTablesStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SHOW COLUMNS FROM `sharding_db`.`table_x` FROM sharding_db", DatabaseType.MySQL, showTablesStatement, Collections.emptyList(), null); + "SHOW COLUMNS FROM `sharding_db`.`table_x` FROM sharding_db", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SHOW COLUMNS FROM `table_1` FROM sharding_db")); } @Test public void assertTableTokenWithSchemaForSelect() { selectStatement.addSQLToken(new TableToken(14, "table_x", QuoteCharacter.NONE, "sharding_db".length() + 1)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT * FROM sharding_db.table_x", DatabaseType.MySQL, selectStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "SELECT * FROM sharding_db.table_x", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SELECT * FROM table_1")); } @Test public void assertTableTokenWithSchemaForInsert() { insertStatement.addSQLToken(new TableToken(12, "table_x", QuoteCharacter.NONE, "sharding_db".length() + 1)); + routeResult = new SQLRouteResult(insertStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "INSERT INTO sharding_db.table_x (order_id, user_id, status) values (1, 1, 'OK')", DatabaseType.MySQL, insertStatement, Collections.emptyList(), null); + "INSERT INTO sharding_db.table_x (order_id, user_id, status) values (1, 1, 'OK')", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL( null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("INSERT INTO table_1 (order_id, user_id, status) values (1, 1, 'OK')")); } @@ -563,15 +620,17 @@ public void assertTableTokenWithSchemaForInsert() { @Test public void assertTableTokenWithSchemaForUpdate() { dmlStatement.addSQLToken(new TableToken(7, "table_x", QuoteCharacter.NONE, "`sharding_db`".length() + 1)); + routeResult = new SQLRouteResult(dmlStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "UPDATE `sharding_db`.table_x SET user_id=1 WHERE order_id=1", DatabaseType.MySQL, dmlStatement, Collections.emptyList(), null); + "UPDATE `sharding_db`.table_x SET user_id=1 WHERE order_id=1", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("UPDATE table_1 SET user_id=1 WHERE order_id=1")); } @Test public void assertTableTokenWithSchemaForDelete() { dmlStatement.addSQLToken(new TableToken(12, "table_x", QuoteCharacter.BACK_QUOTE, "`sharding_db`".length() + 1)); - SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "DELETE FROM `sharding_db`.`table_x` WHERE user_id=1", DatabaseType.MySQL, dmlStatement, Collections.emptyList(), null); + routeResult = new SQLRouteResult(dmlStatement); + SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, "DELETE FROM `sharding_db`.`table_x` WHERE user_id=1", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(true).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("DELETE FROM `table_1` WHERE user_id=1")); } @@ -585,8 +644,10 @@ public void assertSelectEqualWithShardingEncryptor() { selectStatement.addSQLToken(new EncryptColumnToken(29, 32, column, true)); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().add(new AndCondition()); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().get(0).getConditions().add(new Condition(column, new SQLPlaceholderExpression(0))); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT id FROM table_z WHERE id=? AND name=?", DatabaseType.MySQL, selectStatement, parameters, null); + "SELECT id FROM table_z WHERE id=? AND name=?", DatabaseType.MySQL, routeResult, parameters, null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SELECT id FROM table_z WHERE id = ? AND name=?")); assertThat(parameters.get(0), is((Object) "encryptValue")); } @@ -598,8 +659,10 @@ public void assertSelectBetweenWithShardingEncryptor() { selectStatement.addSQLToken(new EncryptColumnToken(29, 46, column, true)); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().add(new AndCondition()); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().get(0).getConditions().add(new Condition(column, new SQLNumberExpression(3), new SQLNumberExpression(5))); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT id FROM table_z WHERE id between 3 and 5", DatabaseType.MySQL, selectStatement, new LinkedList<>(), null); + "SELECT id FROM table_z WHERE id between 3 and 5", DatabaseType.MySQL, routeResult, new LinkedList<>(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SELECT id FROM table_z WHERE id BETWEEN 'encryptValue' AND 'encryptValue'")); } @@ -614,8 +677,10 @@ public void assertSelectInWithShardingEncryptor() { sqlExpressions.add(new SQLNumberExpression(3)); sqlExpressions.add(new SQLNumberExpression(5)); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().get(0).getConditions().add(new Condition(column, sqlExpressions)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT id FROM table_z WHERE id in (3,5)", DatabaseType.MySQL, selectStatement, new LinkedList<>(), null); + "SELECT id FROM table_z WHERE id in (3,5)", DatabaseType.MySQL, routeResult, new LinkedList<>(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SELECT id FROM table_z WHERE id IN ('encryptValue', 'encryptValue')")); } @@ -636,8 +701,10 @@ public void assertSelectInWithShardingEncryptorWithParameter() { sqlExpressions.add(new SQLPlaceholderExpression(1)); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().get(0).getConditions().add(new Condition(column, sqlExpressions)); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().get(1).getConditions().add(new Condition(column, new SQLNumberExpression(3))); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT id FROM table_z WHERE id in (?, ?) or id = 3", DatabaseType.MySQL, selectStatement, parameters, null); + "SELECT id FROM table_z WHERE id in (?, ?) or id = 3", DatabaseType.MySQL, routeResult, parameters, null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SELECT id FROM table_z WHERE id IN (?, ?) or id = 'encryptValue'")); assertThat(parameters.get(0), is((Object) "encryptValue")); assertThat(parameters.get(1), is((Object) "encryptValue")); @@ -653,8 +720,10 @@ public void assertSelectEqualWithQueryAssistedShardingEncryptor() { selectStatement.addSQLToken(new EncryptColumnToken(29, 32, column, true)); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().add(new AndCondition()); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().get(0).getConditions().add(new Condition(column, new SQLPlaceholderExpression(0))); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT id FROM table_k WHERE id=? AND name=?", DatabaseType.MySQL, selectStatement, parameters, null); + "SELECT id FROM table_k WHERE id=? AND name=?", DatabaseType.MySQL, routeResult, parameters, null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SELECT id FROM table_k WHERE query_id = ? AND name=?")); assertThat(parameters.get(0), is((Object) "assistedEncryptValue")); } @@ -669,8 +738,10 @@ public void assertSelectInWithQueryAssistedShardingEncryptor() { sqlExpressions.add(new SQLNumberExpression(3)); sqlExpressions.add(new SQLNumberExpression(5)); selectStatement.getEncryptConditions().getOrCondition().getAndConditions().get(0).getConditions().add(new Condition(column, sqlExpressions)); + routeResult = new SQLRouteResult(selectStatement); + routeResult.setLimit(selectStatement.getLimit()); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "SELECT id FROM table_k WHERE id in (3,5)", DatabaseType.MySQL, selectStatement, new LinkedList<>(), null); + "SELECT id FROM table_k WHERE id in (3,5)", DatabaseType.MySQL, routeResult, new LinkedList<>(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("SELECT id FROM table_k WHERE query_id IN ('assistedEncryptValue', 'assistedEncryptValue')")); } @@ -684,8 +755,9 @@ public void assertUpdateWithShardingEncryptor() { dmlStatement.addSQLToken(new EncryptColumnToken(32, 37, column, true)); dmlStatement.getEncryptConditions().getOrCondition().getAndConditions().add(new AndCondition()); dmlStatement.getEncryptConditions().getOrCondition().getAndConditions().get(0).getConditions().add(new Condition(column, new SQLNumberExpression(2))); + routeResult = new SQLRouteResult(dmlStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "UPDATE table_z SET id = 1 WHERE id = 2", DatabaseType.MySQL, dmlStatement, Collections.emptyList(), null); + "UPDATE table_z SET id = 1 WHERE id = 2", DatabaseType.MySQL, routeResult, Collections.emptyList(), null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("UPDATE table_z SET id = 'encryptValue' WHERE id = 'encryptValue'")); } @@ -702,8 +774,9 @@ public void assertUpdateWithQueryAssistedShardingEncryptor() { dmlStatement.addSQLToken(new EncryptColumnToken(32, 49, column, true)); dmlStatement.getEncryptConditions().getOrCondition().getAndConditions().add(new AndCondition()); dmlStatement.getEncryptConditions().getOrCondition().getAndConditions().get(0).getConditions().add(new Condition(column, new SQLNumberExpression(3), new SQLPlaceholderExpression(1))); + routeResult = new SQLRouteResult(dmlStatement); SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, - "UPDATE table_k SET id = ? WHERE id between 3 and ?", DatabaseType.MySQL, dmlStatement, parameters, null); + "UPDATE table_k SET id = ? WHERE id between 3 and ?", DatabaseType.MySQL, routeResult, parameters, null); assertThat(rewriteEngine.rewrite(false).toSQL(null, tableTokens, shardingRule, shardingDataSourceMetaData).getSql(), is("UPDATE table_k SET id = ?, query_id = ? WHERE query_id BETWEEN 'assistedEncryptValue' AND ?")); assertThat(parameters.get(0), is((Object) "encryptValue")); diff --git a/sharding-core/sharding-core-route/src/main/java/org/apache/shardingsphere/core/route/SQLRouteResult.java b/sharding-core/sharding-core-route/src/main/java/org/apache/shardingsphere/core/route/SQLRouteResult.java index 09e2c4c198218..6c565d2b6a029 100644 --- a/sharding-core/sharding-core-route/src/main/java/org/apache/shardingsphere/core/route/SQLRouteResult.java +++ b/sharding-core/sharding-core-route/src/main/java/org/apache/shardingsphere/core/route/SQLRouteResult.java @@ -22,6 +22,7 @@ import lombok.Setter; import org.apache.shardingsphere.core.optimize.GeneratedKey; import org.apache.shardingsphere.core.optimize.result.OptimizeResult; +import org.apache.shardingsphere.core.parse.parser.context.limit.Limit; import org.apache.shardingsphere.core.parse.parser.sql.SQLStatement; import org.apache.shardingsphere.core.route.type.RoutingResult; @@ -44,6 +45,10 @@ public final class SQLRouteResult { private final GeneratedKey generatedKey; + // For multiple thread read cached sqlStatement, clone limit on SQLRouteResult, because limit will be modified after cache + // TODO need more good design here + private Limit limit; + private RoutingResult routingResult; private OptimizeResult optimizeResult; diff --git a/sharding-core/sharding-core-route/src/main/java/org/apache/shardingsphere/core/route/router/sharding/ParsingSQLRouter.java b/sharding-core/sharding-core-route/src/main/java/org/apache/shardingsphere/core/route/router/sharding/ParsingSQLRouter.java index 2497bb912dc5b..13daf8273ebaa 100644 --- a/sharding-core/sharding-core-route/src/main/java/org/apache/shardingsphere/core/route/router/sharding/ParsingSQLRouter.java +++ b/sharding-core/sharding-core-route/src/main/java/org/apache/shardingsphere/core/route/router/sharding/ParsingSQLRouter.java @@ -32,6 +32,8 @@ import org.apache.shardingsphere.core.parse.cache.ParsingResultCache; import org.apache.shardingsphere.core.parse.hook.ParsingHook; import org.apache.shardingsphere.core.parse.hook.SPIParsingHook; +import org.apache.shardingsphere.core.parse.parser.context.limit.Limit; +import org.apache.shardingsphere.core.parse.parser.context.limit.LimitValue; import org.apache.shardingsphere.core.parse.parser.sql.SQLStatement; import org.apache.shardingsphere.core.parse.parser.sql.dml.insert.InsertStatement; import org.apache.shardingsphere.core.parse.parser.sql.dql.select.SelectStatement; @@ -103,7 +105,7 @@ public SQLRouteResult route(final String logicSQL, final List parameters } RoutingResult routingResult = RoutingEngineFactory.newInstance(shardingRule, shardingMetaData.getDataSource(), sqlStatement, optimizeResult).route(); if (sqlStatement instanceof SelectStatement && null != ((SelectStatement) sqlStatement).getLimit() && !routingResult.isSingleRouting()) { - processLimit(parameters, (SelectStatement) sqlStatement); + result.setLimit(getProcessedLimit(parameters, (SelectStatement) sqlStatement)); } if (needMerge) { Preconditions.checkState(1 == routingResult.getTableUnits().getTableUnits().size(), "Must have one sharding with subquery."); @@ -183,8 +185,21 @@ private void mergeShardingValues(final ShardingConditions shardingConditions) { } } - private void processLimit(final List parameters, final SelectStatement selectStatement) { + private Limit getProcessedLimit(final List parameters, final SelectStatement selectStatement) { boolean isNeedFetchAll = (!selectStatement.getGroupByItems().isEmpty() || !selectStatement.getAggregationSelectItems().isEmpty()) && !selectStatement.isSameGroupByAndOrderByItems(); - selectStatement.getLimit().processParameters(parameters, isNeedFetchAll, databaseType); + Limit result = cloneLimit(selectStatement.getLimit()); + result.processParameters(parameters, isNeedFetchAll, databaseType); + return result; + } + + private Limit cloneLimit(final Limit limit) { + Limit result = new Limit(); + if (null != limit.getOffset()) { + result.setOffset(new LimitValue(limit.getOffset().getValue(), limit.getOffset().getIndex(), limit.getOffset().isBoundOpened())); + } + if (null != limit.getRowCount()) { + result.setRowCount(new LimitValue(limit.getRowCount().getValue(), limit.getRowCount().getIndex(), limit.getRowCount().isBoundOpened())); + } + return result; } } diff --git a/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingPreparedStatement.java b/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingPreparedStatement.java index eee28a841bac0..da721b607d171 100644 --- a/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingPreparedStatement.java +++ b/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingPreparedStatement.java @@ -109,7 +109,7 @@ public ResultSet executeQuery() throws SQLException { shard(); initPreparedStatementExecutor(); MergeEngine mergeEngine = MergeEngineFactory.newInstance(connection.getShardingContext().getDatabaseType(), connection.getShardingContext().getShardingRule(), - routeResult.getSqlStatement(), connection.getShardingContext().getMetaData().getTable(), preparedStatementExecutor.executeQuery()); + routeResult, connection.getShardingContext().getMetaData().getTable(), preparedStatementExecutor.executeQuery()); result = getResultSet(mergeEngine); } finally { clearBatch(); @@ -137,7 +137,7 @@ public ResultSet getResultSet() throws SQLException { } if (routeResult.getSqlStatement() instanceof SelectStatement || routeResult.getSqlStatement() instanceof DALStatement) { MergeEngine mergeEngine = MergeEngineFactory.newInstance(connection.getShardingContext().getDatabaseType(), - connection.getShardingContext().getShardingRule(), routeResult.getSqlStatement(), connection.getShardingContext().getMetaData().getTable(), queryResults); + connection.getShardingContext().getShardingRule(), routeResult, connection.getShardingContext().getMetaData().getTable(), queryResults); currentResultSet = getCurrentResultSet(resultSets, mergeEngine); } return currentResultSet; diff --git a/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingStatement.java b/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingStatement.java index 7195ec9a09b51..a75dd21057871 100644 --- a/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingStatement.java +++ b/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingStatement.java @@ -90,7 +90,7 @@ public ResultSet executeQuery(final String sql) throws SQLException { shard(sql); initStatementExecutor(); MergeEngine mergeEngine = MergeEngineFactory.newInstance(connection.getShardingContext().getDatabaseType(), connection.getShardingContext().getShardingRule(), - routeResult.getSqlStatement(), connection.getShardingContext().getMetaData().getTable(), statementExecutor.executeQuery()); + routeResult, connection.getShardingContext().getMetaData().getTable(), statementExecutor.executeQuery()); result = getResultSet(mergeEngine); } finally { currentResultSet = null; @@ -118,7 +118,7 @@ public ResultSet getResultSet() throws SQLException { } if (routeResult.getSqlStatement() instanceof SelectStatement || routeResult.getSqlStatement() instanceof DALStatement) { MergeEngine mergeEngine = MergeEngineFactory.newInstance(connection.getShardingContext().getDatabaseType(), - connection.getShardingContext().getShardingRule(), routeResult.getSqlStatement(), connection.getShardingContext().getMetaData().getTable(), queryResults); + connection.getShardingContext().getShardingRule(), routeResult, connection.getShardingContext().getMetaData().getTable(), queryResults); currentResultSet = getCurrentResultSet(resultSets, mergeEngine); } return currentResultSet; diff --git a/sharding-proxy/sharding-proxy-backend/src/main/java/org/apache/shardingsphere/shardingproxy/backend/communication/jdbc/JDBCDatabaseCommunicationEngine.java b/sharding-proxy/sharding-proxy-backend/src/main/java/org/apache/shardingsphere/shardingproxy/backend/communication/jdbc/JDBCDatabaseCommunicationEngine.java index f2cbf6b8dd7f9..4e31d063078f3 100644 --- a/sharding-proxy/sharding-proxy-backend/src/main/java/org/apache/shardingsphere/shardingproxy/backend/communication/jdbc/JDBCDatabaseCommunicationEngine.java +++ b/sharding-proxy/sharding-proxy-backend/src/main/java/org/apache/shardingsphere/shardingproxy/backend/communication/jdbc/JDBCDatabaseCommunicationEngine.java @@ -94,7 +94,7 @@ private BackendResponse execute(final SQLRouteResult routeResult) throws SQLExce if (logicSchema instanceof ShardingSchema) { logicSchema.refreshTableMetaData(routeResult.getSqlStatement()); } - return merge(sqlStatement); + return merge(routeResult); } private boolean isExecuteDDLInXATransaction(final SQLType sqlType) { @@ -102,15 +102,15 @@ private boolean isExecuteDDLInXATransaction(final SQLType sqlType) { return TransactionType.XA == connection.getTransactionType() && SQLType.DDL == sqlType && ConnectionStatus.TRANSACTION == connection.getStateHandler().getStatus(); } - private BackendResponse merge(final SQLStatement sqlStatement) throws SQLException { + private BackendResponse merge(final SQLRouteResult routeResult) throws SQLException { if (response instanceof UpdateResponse) { - if (!isAllBroadcastTables(sqlStatement)) { + if (!isAllBroadcastTables(routeResult.getSqlStatement())) { ((UpdateResponse) response).mergeUpdateCount(); } return response; } mergedResult = MergeEngineFactory.newInstance( - databaseType, getShardingRule(), sqlStatement, logicSchema.getMetaData().getTable(), ((QueryResponse) response).getQueryResults()).merge(); + databaseType, getShardingRule(), routeResult, logicSchema.getMetaData().getTable(), ((QueryResponse) response).getQueryResults()).merge(); if (mergedResult instanceof ShowTablesMergedResult) { ((ShowTablesMergedResult) mergedResult).resetColumnLabel(logicSchema.getName()); }