diff --git a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/extractor/impl/dml/select/LimitExtractor.java b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/extractor/impl/dml/select/LimitExtractor.java index f6e7e68f3c3ee6b047c8f8c4a773e34befa21ee1..95d26b2d8fc5d6d71d2846120b3651a8275a75bb 100644 --- a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/extractor/impl/dml/select/LimitExtractor.java +++ b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/extractor/impl/dml/select/LimitExtractor.java @@ -49,12 +49,7 @@ public final class LimitExtractor implements OptionalSQLSegmentExtractor { Optional limitNode = ExtractorUtils.findFirstChildNode(ancestorNode, RuleName.LIMIT_CLAUSE); return limitNode.isPresent() ? Optional.of(new LimitSegment(limitNode.get().getStart().getStartIndex(), limitNode.get().getStop().getStopIndex(), - extractRowCount(limitNode.get(), parameterMarkerIndexes).orNull(), extractOffset(limitNode.get(), parameterMarkerIndexes).orNull())) : Optional.absent(); - } - - private Optional extractRowCount(final ParserRuleContext limitNode, final Map parameterMarkerIndexes) { - Optional rowCountNode = ExtractorUtils.findFirstChildNode(limitNode, RuleName.LIMIT_ROW_COUNT); - return rowCountNode.isPresent() ? Optional.of(extractLimitValue(rowCountNode.get(), parameterMarkerIndexes)) : Optional.absent(); + extractOffset(limitNode.get(), parameterMarkerIndexes).orNull(), extractRowCount(limitNode.get(), parameterMarkerIndexes).orNull())) : Optional.absent(); } private Optional extractOffset(final ParserRuleContext limitNode, final Map parameterMarkerIndexes) { @@ -62,6 +57,11 @@ public final class LimitExtractor implements OptionalSQLSegmentExtractor { return offsetNode.isPresent() ? Optional.of(extractLimitValue(offsetNode.get(), parameterMarkerIndexes)) : Optional.absent(); } + private Optional extractRowCount(final ParserRuleContext limitNode, final Map parameterMarkerIndexes) { + Optional rowCountNode = ExtractorUtils.findFirstChildNode(limitNode, RuleName.LIMIT_ROW_COUNT); + return rowCountNode.isPresent() ? Optional.of(extractLimitValue(rowCountNode.get(), parameterMarkerIndexes)) : Optional.absent(); + } + private LimitValueSegment extractLimitValue(final ParserRuleContext limitValueNode, final Map parameterMarkerIndexes) { Optional parameterMarkerExpression = parameterMarkerExpressionExtractor.extract(limitValueNode, parameterMarkerIndexes); if (parameterMarkerExpression.isPresent()) { diff --git a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/filler/common/dml/SelectItemFiller.java b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/filler/common/dml/SelectItemFiller.java index 5230256b26b83a292d99bbb3d3015554e3c46367..6ca6d17917e1c4c267312a423cb6bcd7ab5f1be8 100644 --- a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/filler/common/dml/SelectItemFiller.java +++ b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/filler/common/dml/SelectItemFiller.java @@ -109,7 +109,7 @@ public final class SelectItemFiller implements SQLSegmentFiller": offset = createLimitValueSegment(expression, false); break; case ">=": offset = createLimitValueSegment(expression, true); break; + case "<": + rowCount = createLimitValueSegment(expression, false); + break; + case "<=": + rowCount = createLimitValueSegment(expression, true); + break; default: break; } } - selectStatement.setLimit(new LimitSegment(-1, -1, rowCount, offset)); + selectStatement.setLimit(new LimitSegment(-1, -1, offset, rowCount)); } private LimitValueSegment createLimitValueSegment(final ExpressionSegment expression, final boolean boundOpened) { diff --git a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/sql/segment/dml/limit/LimitSegment.java b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/sql/segment/dml/limit/LimitSegment.java index 4cc7ff859d31237cd1e7e2437263e5b2d3ada20e..8161747486a06efa440aea34737bd1aeec4145f6 100644 --- a/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/sql/segment/dml/limit/LimitSegment.java +++ b/sharding-core/sharding-core-parse/sharding-core-parse-common/src/main/java/org/apache/shardingsphere/core/parse/sql/segment/dml/limit/LimitSegment.java @@ -35,18 +35,9 @@ public final class LimitSegment implements SQLSegment { private final int stopIndex; - private final LimitValueSegment rowCount; - private final LimitValueSegment offset; - /** - * Get row count. - * - * @return row count - */ - public Optional getRowCount() { - return Optional.fromNullable(rowCount); - } + private final LimitValueSegment rowCount; /** * Get offset. @@ -56,4 +47,13 @@ public final class LimitSegment implements SQLSegment { public Optional getOffset() { return Optional.fromNullable(offset); } + + /** + * Get row count. + * + * @return row count + */ + public Optional getRowCount() { + return Optional.fromNullable(rowCount); + } } diff --git a/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/ShardingSQLRewriterTest.java b/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/ShardingSQLRewriterTest.java index 7f9b7417bb82ad2a86d2342a0622f1f3e2de35e9..cf025ec85ab8287bf8a49fd2c410e1f18bc7a927 100644 --- a/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/ShardingSQLRewriterTest.java +++ b/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/ShardingSQLRewriterTest.java @@ -339,14 +339,14 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForLimit() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(36, 36, 2, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(33, 33, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(36, 36, 2, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); selectStatement.addSQLToken(new TableToken(17, 23, "table_x", QuoteCharacter.NONE)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(2, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(2, -1, rowCountSQLSegment)); routeResult.setLimit(limit); routeResult.setRoutingResult(new RoutingResult()); selectStatement.setLogicSQL("SELECT x.id FROM table_x x LIMIT 2, 2"); @@ -356,14 +356,14 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForRowNum() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(98, 98, 4, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(119, 119, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(98, 98, 4, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); selectStatement.addSQLToken(new TableToken(68, 74, "table_x", QuoteCharacter.NONE)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); routeResult.setLimit(limit); 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"); @@ -374,14 +374,14 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForTopAndRowNumber() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(26, 26, 4, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(123, 123, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(26, 26, 4, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); selectStatement.addSQLToken(new TableToken(85, 91, "table_x", QuoteCharacter.NONE)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); routeResult.setLimit(limit); 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"); @@ -392,9 +392,9 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForLimitForMemoryGroupBy() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(36, 36, 2, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(33, 33, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(36, 36, 2, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); ColumnSegment columnSegment = new ColumnSegment(0, 0, "id"); columnSegment.setOwner(new TableSegment(0, 0, "x")); selectStatement.getOrderByItems().add(new ColumnOrderByItemSegment(0, 0, columnSegment, OrderDirection.ASC, OrderDirection.ASC)); @@ -402,8 +402,8 @@ public final class ShardingSQLRewriterTest { selectStatement.addSQLToken(new TableToken(17, 23, "table_x", QuoteCharacter.NONE)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); routeResult.setLimit(limit); routeResult.setRoutingResult(new RoutingResult()); selectStatement.setLogicSQL("SELECT x.id FROM table_x x LIMIT 2, 2"); @@ -413,9 +413,9 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForRowNumForMemoryGroupBy() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(98, 98, 4, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(119, 119, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(98, 98, 4, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); selectStatement.addSQLToken(new TableToken(68, 74, "table_x", QuoteCharacter.NONE)); ColumnSegment columnSegment = new ColumnSegment(0, 0, "id"); columnSegment.setOwner(new TableSegment(0, 0, "x")); @@ -423,8 +423,8 @@ public final class ShardingSQLRewriterTest { selectStatement.getGroupByItems().add(new ColumnOrderByItemSegment(0, 0, columnSegment, OrderDirection.DESC, OrderDirection.ASC)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); routeResult.setLimit(limit); 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"); @@ -435,9 +435,9 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForTopAndRowNumberForMemoryGroupBy() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(26, 26, 4, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(123, 123, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(26, 26, 4, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); selectStatement.addSQLToken(new TableToken(85, 91, "table_x", QuoteCharacter.NONE)); ColumnSegment columnSegment = new ColumnSegment(0, 0, "id"); columnSegment.setOwner(new TableSegment(0, 0, "x")); @@ -445,8 +445,8 @@ public final class ShardingSQLRewriterTest { selectStatement.getGroupByItems().add(new ColumnOrderByItemSegment(0, 0, columnSegment, OrderDirection.DESC, OrderDirection.ASC)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); routeResult.setLimit(limit); 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"); @@ -457,14 +457,14 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForLimitForNotRewriteLimit() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(36, 36, 2, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(33, 33, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(36, 36, 2, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); selectStatement.addSQLToken(new TableToken(17, 23, "table_x", QuoteCharacter.NONE)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); routeResult.setLimit(limit); RoutingResult routingResult = new RoutingResult(); routingResult.getRoutingUnits().add(new RoutingUnit("ds")); @@ -476,14 +476,14 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForRowNumForNotRewriteLimit() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(98, 98, 4, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(119, 119, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(98, 98, 4, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); selectStatement.addSQLToken(new TableToken(68, 74, "table_x", QuoteCharacter.NONE)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); routeResult.setLimit(limit); RoutingResult routingResult = new RoutingResult(); routingResult.getRoutingUnits().add(new RoutingUnit("ds")); @@ -496,14 +496,14 @@ public final class ShardingSQLRewriterTest { @Test public void assertRewriteForTopAndRowNumberForNotRewriteLimit() { - LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(26, 26, 4, false); LimitValueSegment offsetSQLSegment = new NumberLiteralLimitValueSegment(123, 123, 2, true); - selectStatement.setLimit(new LimitSegment(0, 0, rowCountSQLSegment, offsetSQLSegment)); + LimitValueSegment rowCountSQLSegment = new NumberLiteralLimitValueSegment(26, 26, 4, false); + selectStatement.setLimit(new LimitSegment(0, 0, offsetSQLSegment, rowCountSQLSegment)); selectStatement.addSQLToken(new TableToken(85, 91, "table_x", QuoteCharacter.NONE)); routeResult = new SQLRouteResult(selectStatement); Limit limit = new Limit(); - limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); limit.setOffset(new LimitValue(2, -1, offsetSQLSegment)); + limit.setRowCount(new LimitValue(4, -1, rowCountSQLSegment)); routeResult.setLimit(limit); RoutingResult routingResult = new RoutingResult(); routingResult.getRoutingUnits().add(new RoutingUnit("ds"));