提交 18dec77a 编写于 作者: T terrymanu

for #2441, use LimitValueSegment instead of LimitValue on Limit's constructor

上级 fcab73c4
......@@ -27,7 +27,6 @@ import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.NumberLiteralL
import org.apache.shardingsphere.core.parse.sql.statement.dml.SelectStatement;
import org.apache.shardingsphere.core.route.SQLRouteResult;
import org.apache.shardingsphere.core.route.limit.Limit;
import org.apache.shardingsphere.core.route.limit.LimitValue;
import org.junit.Before;
import org.junit.Test;
......@@ -71,7 +70,7 @@ public final class LimitDecoratorMergedResultTest {
@Test
public void assertNextForSkipAll() throws SQLException {
routeResult.setLimit(new Limit(new LimitValue(Integer.MAX_VALUE, -1, new NumberLiteralLimitValueSegment(0, 0, Integer.MAX_VALUE, true)), null, Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, Integer.MAX_VALUE, true), null, Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
assertFalse(actual.next());
......@@ -79,7 +78,7 @@ public final class LimitDecoratorMergedResultTest {
@Test
public void assertNextWithoutRowCount() throws SQLException {
routeResult.setLimit(new Limit(new LimitValue(2, -1, new NumberLiteralLimitValueSegment(0, 0, 2, true)), null, Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, 2, true), null, Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
for (int i = 0; i < 6; i++) {
......@@ -90,8 +89,7 @@ public final class LimitDecoratorMergedResultTest {
@Test
public void assertNextWithRowCount() throws SQLException {
routeResult.setLimit(new Limit(
new LimitValue(2, -1, new NumberLiteralLimitValueSegment(0, 0, 2, true)), new LimitValue(2, -1, new NumberLiteralLimitValueSegment(0, 0, 2, false)), Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, 2, true), new NumberLiteralLimitValueSegment(0, 0, 2, false), Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.MySQL, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
assertTrue(actual.next());
......
......@@ -27,7 +27,6 @@ import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.NumberLiteralL
import org.apache.shardingsphere.core.parse.sql.statement.dml.SelectStatement;
import org.apache.shardingsphere.core.route.SQLRouteResult;
import org.apache.shardingsphere.core.route.limit.Limit;
import org.apache.shardingsphere.core.route.limit.LimitValue;
import org.junit.Before;
import org.junit.Test;
......@@ -72,7 +71,7 @@ public final class RowNumberDecoratorMergedResultTest {
@Test
public void assertNextForSkipAll() throws SQLException {
routeResult.setLimit(new Limit(new LimitValue(Integer.MAX_VALUE, -1, new NumberLiteralLimitValueSegment(0, 0, 2, true)), null, Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, Integer.MAX_VALUE, true), null, Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
assertFalse(actual.next());
......@@ -91,8 +90,7 @@ public final class RowNumberDecoratorMergedResultTest {
@Test
public void assertNextForRowCountBoundOpenedFalse() throws SQLException {
routeResult.setLimit(new Limit(
new LimitValue(2, -1, new NumberLiteralLimitValueSegment(0, 0, 2, true)), new LimitValue(4, -1, new NumberLiteralLimitValueSegment(0, 0, 4, false)), Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, 2, true), new NumberLiteralLimitValueSegment(0, 0, 4, false), Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
assertTrue(actual.next());
......@@ -102,8 +100,7 @@ public final class RowNumberDecoratorMergedResultTest {
@Test
public void assertNextForRowCountBoundOpenedTrue() throws SQLException {
routeResult.setLimit(new Limit(
new LimitValue(2, -1, new NumberLiteralLimitValueSegment(0, 0, 2, true)), new LimitValue(4, -1, new NumberLiteralLimitValueSegment(0, 0, 4, true)), Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, 2, true), new NumberLiteralLimitValueSegment(0, 0, 4, true), Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.Oracle, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
assertTrue(actual.next());
......
......@@ -27,7 +27,6 @@ import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.NumberLiteralL
import org.apache.shardingsphere.core.parse.sql.statement.dml.SelectStatement;
import org.apache.shardingsphere.core.route.SQLRouteResult;
import org.apache.shardingsphere.core.route.limit.Limit;
import org.apache.shardingsphere.core.route.limit.LimitValue;
import org.junit.Before;
import org.junit.Test;
......@@ -72,7 +71,7 @@ public final class TopAndRowNumberDecoratorMergedResultTest {
@Test
public void assertNextForSkipAll() throws SQLException {
routeResult.setLimit(new Limit(new LimitValue(Integer.MAX_VALUE, -1, new NumberLiteralLimitValueSegment(0, 0, Integer.MAX_VALUE, true)), null, Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, Integer.MAX_VALUE, true), null, Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
assertFalse(actual.next());
......@@ -80,7 +79,7 @@ public final class TopAndRowNumberDecoratorMergedResultTest {
@Test
public void assertNextWithoutOffsetWithRowCount() throws SQLException {
routeResult.setLimit(new Limit(null, new LimitValue(5, -1, new NumberLiteralLimitValueSegment(0, 0, 2, false)), Collections.emptyList()));
routeResult.setLimit(new Limit(null, new NumberLiteralLimitValueSegment(0, 0, 5, false), Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
for (int i = 0; i < 5; i++) {
......@@ -91,7 +90,7 @@ public final class TopAndRowNumberDecoratorMergedResultTest {
@Test
public void assertNextWithOffsetWithoutRowCount() throws SQLException {
routeResult.setLimit(new Limit(new LimitValue(2, -1, new NumberLiteralLimitValueSegment(0, 0, 2, true)), null, Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, 2, true), null, Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
for (int i = 0; i < 7; i++) {
......@@ -102,8 +101,7 @@ public final class TopAndRowNumberDecoratorMergedResultTest {
@Test
public void assertNextWithOffsetBoundOpenedFalse() throws SQLException {
routeResult.setLimit(new Limit(
new LimitValue(2, -1, new NumberLiteralLimitValueSegment(0, 0, 2, false)), new LimitValue(4, -1, new NumberLiteralLimitValueSegment(0, 0, 4, false)), Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, 2, false), new NumberLiteralLimitValueSegment(0, 0, 4, false), Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
assertTrue(actual.next());
......@@ -113,8 +111,7 @@ public final class TopAndRowNumberDecoratorMergedResultTest {
@Test
public void assertNextWithOffsetBoundOpenedTrue() throws SQLException {
routeResult.setLimit(new Limit(
new LimitValue(2, -1, new NumberLiteralLimitValueSegment(0, 0, 2, true)), new LimitValue(4, -1, new NumberLiteralLimitValueSegment(0, 0, 4, false)), Collections.emptyList()));
routeResult.setLimit(new Limit(new NumberLiteralLimitValueSegment(0, 0, 2, true), new NumberLiteralLimitValueSegment(0, 0, 4, false), Collections.emptyList()));
mergeEngine = new DQLMergeEngine(DatabaseType.SQLServer, routeResult, queryResults);
MergedResult actual = mergeEngine.merge();
assertTrue(actual.next());
......
......@@ -65,7 +65,6 @@ import org.apache.shardingsphere.core.rewrite.rewriter.sql.EncryptSQLRewriter;
import org.apache.shardingsphere.core.rewrite.rewriter.sql.ShardingSQLRewriter;
import org.apache.shardingsphere.core.route.SQLRouteResult;
import org.apache.shardingsphere.core.route.limit.Limit;
import org.apache.shardingsphere.core.route.limit.LimitValue;
import org.apache.shardingsphere.core.route.type.RoutingResult;
import org.apache.shardingsphere.core.route.type.RoutingUnit;
import org.apache.shardingsphere.core.route.type.TableUnit;
......@@ -353,7 +352,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment));
selectStatement.getSqlSegments().add(new TableSegment(17, 23, "table_x"));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(2, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
routeResult.setRoutingResult(new RoutingResult());
selectStatement.setLogicSQL("SELECT x.id FROM table_x x LIMIT 2, 2");
SQLRewriteEngine rewriteEngine = createSQLRewriteEngine(DatabaseType.MySQL, Collections.emptyList());
......@@ -367,7 +366,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment));
selectStatement.getSqlSegments().add(new TableSegment(68, 74, "table_x"));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(4, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
routeResult.setRoutingResult(new RoutingResult());
selectStatement.setLogicSQL("SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2");
SQLRewriteEngine rewriteEngine = createSQLRewriteEngine(DatabaseType.Oracle, Collections.emptyList());
......@@ -382,7 +381,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment));
selectStatement.getSqlSegments().add(new TableSegment(85, 91, "table_x"));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(4, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
routeResult.setRoutingResult(new RoutingResult());
selectStatement.setLogicSQL("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");
SQLRewriteEngine rewriteEngine = createSQLRewriteEngine(DatabaseType.SQLServer, Collections.emptyList());
......@@ -401,7 +400,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.getGroupByItems().add(new ColumnOrderByItemSegment(0, 0, columnSegment, OrderDirection.DESC, OrderDirection.ASC));
selectStatement.getSqlSegments().add(new TableSegment(17, 23, "table_x"));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(4, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
routeResult.setRoutingResult(new RoutingResult());
selectStatement.setLogicSQL("SELECT x.id FROM table_x x LIMIT 2, 2");
SQLRewriteEngine rewriteEngine = createSQLRewriteEngine(DatabaseType.MySQL, Collections.emptyList());
......@@ -419,7 +418,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.getOrderByItems().add(new ColumnOrderByItemSegment(0, 0, columnSegment, OrderDirection.ASC, OrderDirection.ASC));
selectStatement.getGroupByItems().add(new ColumnOrderByItemSegment(0, 0, columnSegment, OrderDirection.DESC, OrderDirection.ASC));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(4, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
routeResult.setRoutingResult(new RoutingResult());
selectStatement.setLogicSQL("SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2");
SQLRewriteEngine rewriteEngine = createSQLRewriteEngine(DatabaseType.Oracle, Collections.emptyList());
......@@ -438,7 +437,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.getOrderByItems().add(new ColumnOrderByItemSegment(0, 0, columnSegment, OrderDirection.ASC, OrderDirection.ASC));
selectStatement.getGroupByItems().add(new ColumnOrderByItemSegment(0, 0, columnSegment, OrderDirection.DESC, OrderDirection.ASC));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(4, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
routeResult.setRoutingResult(new RoutingResult());
selectStatement.setLogicSQL("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");
SQLRewriteEngine rewriteEngine = createSQLRewriteEngine(DatabaseType.SQLServer, Collections.emptyList());
......@@ -453,7 +452,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment));
selectStatement.getSqlSegments().add(new TableSegment(17, 23, "table_x"));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(4, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
RoutingResult routingResult = new RoutingResult();
routingResult.getRoutingUnits().add(new RoutingUnit("ds"));
routeResult.setRoutingResult(routingResult);
......@@ -469,7 +468,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment));
selectStatement.getSqlSegments().add(new TableSegment(68, 74, "table_x"));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(4, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
RoutingResult routingResult = new RoutingResult();
routingResult.getRoutingUnits().add(new RoutingUnit("ds"));
routeResult.setRoutingResult(routingResult);
......@@ -486,7 +485,7 @@ public final class ShardingSQLRewriterTest {
selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment));
selectStatement.getSqlSegments().add(new TableSegment(85, 91, "table_x"));
routeResult = new SQLRouteResult(selectStatement);
routeResult.setLimit(new Limit(new LimitValue(2, -1, offsetSQLSegment), new LimitValue(4, -1, rowCountSQLSegment), Collections.emptyList()));
routeResult.setLimit(new Limit(offsetSQLSegment, rowCountSQLSegment, Collections.emptyList()));
RoutingResult routingResult = new RoutingResult();
routingResult.getRoutingUnits().add(new RoutingUnit("ds"));
routeResult.setRoutingResult(routingResult);
......
......@@ -19,7 +19,9 @@ package org.apache.shardingsphere.core.route.limit;
import lombok.Getter;
import lombok.ToString;
import org.apache.shardingsphere.core.util.NumberUtil;
import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.LimitValueSegment;
import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.NumberLiteralLimitValueSegment;
import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.ParameterMarkerLimitValueSegment;
import java.util.HashMap;
import java.util.List;
......@@ -40,15 +42,16 @@ public final class Limit {
private final LimitValue rowCount;
public Limit(final LimitValue offset, final LimitValue rowCount, final List<Object> parameters) {
if (null != offset) {
offset.setValue(-1 == offset.getIndex() ? getOffsetValue() : NumberUtil.roundHalfUp(parameters.get(offset.getIndex())));
}
this.offset = offset;
if (null != rowCount) {
rowCount.setValue(-1 == rowCount.getIndex() ? getRowCountValue() : NumberUtil.roundHalfUp(parameters.get(rowCount.getIndex())));
}
this.rowCount = rowCount;
public Limit(final LimitValueSegment offsetSegment, final LimitValueSegment rowCountSegment, final List<Object> parameters) {
offset = null == offsetSegment ? null : createLimitValue(offsetSegment, parameters);
rowCount = null == rowCountSegment ? null : createLimitValue(rowCountSegment, parameters);
}
private LimitValue createLimitValue(final LimitValueSegment limitValueSegment, final List<Object> parameters) {
int segmentValue = limitValueSegment instanceof ParameterMarkerLimitValueSegment
? (int) parameters.get(((ParameterMarkerLimitValueSegment) limitValueSegment).getParameterIndex()) : ((NumberLiteralLimitValueSegment) limitValueSegment).getValue();
int index = limitValueSegment instanceof ParameterMarkerLimitValueSegment ? ((ParameterMarkerLimitValueSegment) limitValueSegment).getParameterIndex() : -1;
return new LimitValue(segmentValue, index, limitValueSegment);
}
/**
......
......@@ -33,15 +33,11 @@ import org.apache.shardingsphere.core.parse.entry.ShardingSQLParseEntry;
import org.apache.shardingsphere.core.parse.hook.ParsingHook;
import org.apache.shardingsphere.core.parse.hook.SPIParsingHook;
import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.LimitSegment;
import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.LimitValueSegment;
import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.NumberLiteralLimitValueSegment;
import org.apache.shardingsphere.core.parse.sql.segment.dml.limit.ParameterMarkerLimitValueSegment;
import org.apache.shardingsphere.core.parse.sql.statement.SQLStatement;
import org.apache.shardingsphere.core.parse.sql.statement.dml.InsertStatement;
import org.apache.shardingsphere.core.parse.sql.statement.dml.SelectStatement;
import org.apache.shardingsphere.core.route.SQLRouteResult;
import org.apache.shardingsphere.core.route.limit.Limit;
import org.apache.shardingsphere.core.route.limit.LimitValue;
import org.apache.shardingsphere.core.route.type.RoutingResult;
import org.apache.shardingsphere.core.rule.BindingTableRule;
import org.apache.shardingsphere.core.rule.ShardingRule;
......@@ -109,7 +105,8 @@ public final class ParsingSQLRouter implements ShardingRouter {
}
RoutingResult routingResult = RoutingEngineFactory.newInstance(shardingRule, shardingMetaData.getDataSource(), sqlStatement, optimizeResult).route();
if (sqlStatement instanceof SelectStatement && null != ((SelectStatement) sqlStatement).getLimit() && !routingResult.isSingleRouting()) {
result.setLimit(createLimit(((SelectStatement) sqlStatement).getLimit(), parameters));
final LimitSegment limitSegment = ((SelectStatement) sqlStatement).getLimit();
result.setLimit(new Limit(limitSegment.getOffset().orNull(), limitSegment.getRowCount().orNull(), parameters));
}
if (needMerge) {
Preconditions.checkState(1 == routingResult.getRoutingUnits().size(), "Must have one sharding with subquery.");
......@@ -188,23 +185,4 @@ public final class ParsingSQLRouter implements ShardingRouter {
shardingConditions.getShardingConditions().add(shardingCondition);
}
}
private Limit createLimit(final LimitSegment limitSegment, final List<Object> parameters) {
LimitValue offset = null;
if (limitSegment.getOffset().isPresent()) {
offset = createLimitValue(limitSegment.getOffset().get());
}
LimitValue rowCount = null;
if (limitSegment.getRowCount().isPresent()) {
rowCount = createLimitValue(limitSegment.getRowCount().get());
}
return new Limit(offset, rowCount, parameters);
}
private LimitValue createLimitValue(final LimitValueSegment limitValueSegment) {
if (limitValueSegment instanceof ParameterMarkerLimitValueSegment) {
return new LimitValue(-1, ((ParameterMarkerLimitValueSegment) limitValueSegment).getParameterIndex(), limitValueSegment);
}
return new LimitValue(((NumberLiteralLimitValueSegment) limitValueSegment).getValue(), -1, limitValueSegment);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册