You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2025/07/02 08:50:08 UTC
(shardingsphere) branch master updated: Add DialectPaginationOption.containsTop (#35855)
This is an automated email from the ASF dual-hosted git repository.
zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 0feddb5c76d Add DialectPaginationOption.containsTop (#35855)
0feddb5c76d is described below
commit 0feddb5c76d9ce35e8fb61edbecb9eae68f008e5
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Wed Jul 2 16:49:57 2025 +0800
Add DialectPaginationOption.containsTop (#35855)
* Refactor PaginationContextEngine
* Refactor PaginationContextEngine
* Add DialectPaginationOption.containsTop
* Add DialectPaginationOption.containsTop
* Add DialectPaginationOption.containsTop
* Add DialectPaginationOption.containsTop
* Add DialectPaginationOption.containsTop
* Add DialectPaginationOption.containsTop
---
.../protocol/MySQLDateBinaryProtocolValue.java | 1 +
.../merge/dql/ShardingDQLResultMergerTest.java | 32 +++----------
.../RowNumberDecoratorMergedResultTest.java | 31 +++++--------
.../pagination/engine/PaginationContextEngine.java | 46 ++++---------------
.../engine/RowNumberPaginationContextEngine.java | 6 +--
...textEngine.java => TopProjectionExtractor.java} | 52 +++++-----------------
.../engine/PaginationContextEngineTest.java | 25 ++++++++---
.../RowNumberPaginationContextEngineTest.java | 2 +-
.../database/metadata/DialectDatabaseMetaData.java | 2 +-
.../option/pagination/DialectPaginationOption.java | 2 +
.../metadata/database/OracleDatabaseMetaData.java | 2 +-
.../database/SQLServerDatabaseMetaData.java | 2 +-
.../sql/execute/result/query/QueryResult.java | 2 +-
13 files changed, 64 insertions(+), 141 deletions(-)
diff --git a/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLDateBinaryProtocolValue.java b/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLDateBinaryProtocolValue.java
index 5ba7133c384..5f6454720ff 100644
--- a/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLDateBinaryProtocolValue.java
+++ b/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLDateBinaryProtocolValue.java
@@ -87,6 +87,7 @@ public final class MySQLDateBinaryProtocolValue implements MySQLBinaryProtocolVa
writeNanos(payload, nanos);
}
+ @SuppressWarnings("UseOfObsoleteDateTimeApi")
private LocalDateTime getLocalDateTime(final Object value) {
if (value instanceof LocalDate) {
return ((LocalDate) value).atStartOfDay();
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
index 3a473adbd9b..94d4f5f6875 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
@@ -36,7 +36,6 @@ import org.apache.shardingsphere.sharding.merge.dql.groupby.GroupByMemoryMergedR
import org.apache.shardingsphere.sharding.merge.dql.groupby.GroupByStreamMergedResult;
import org.apache.shardingsphere.sharding.merge.dql.orderby.OrderByStreamMergedResult;
import org.apache.shardingsphere.sharding.merge.dql.pagination.LimitDecoratorMergedResult;
-import org.apache.shardingsphere.sharding.merge.dql.pagination.RowNumberDecoratorMergedResult;
import org.apache.shardingsphere.sharding.merge.dql.pagination.TopAndRowNumberDecoratorMergedResult;
import org.apache.shardingsphere.sql.parser.statement.core.enums.AggregationType;
import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection;
@@ -52,7 +51,6 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.ite
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.NumberLiteralRowNumberValueSegment;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.top.TopProjectionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
@@ -136,9 +134,6 @@ class ShardingDQLResultMergerTest {
SubquerySegment subquerySegment = mock(SubquerySegment.class);
SelectStatement subSelectStatement = mock(SelectStatement.class);
ProjectionsSegment subProjectionsSegment = mock(ProjectionsSegment.class);
- TopProjectionSegment topProjectionSegment = mock(TopProjectionSegment.class);
- when(topProjectionSegment.getAlias()).thenReturn("row_id");
- when(subProjectionsSegment.getProjections()).thenReturn(Collections.singletonList(topProjectionSegment));
when(subSelectStatement.getProjections()).thenReturn(subProjectionsSegment);
when(subquerySegment.getSelect()).thenReturn(subSelectStatement);
when(subqueryTableSegment.getSubquery()).thenReturn(subquerySegment);
@@ -147,8 +142,7 @@ class ShardingDQLResultMergerTest {
SelectStatementContext selectStatementContext = new SelectStatementContext(
oracleDatabaseType, selectStatement, null, createShardingSphereMetaData(database), "foo_db", Collections.emptyList());
MergedResult actual = resultMerger.merge(createQueryResults(), selectStatementContext, createDatabase(), mock(ConnectionContext.class));
- assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class));
- assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(IteratorStreamMergedResult.class));
+ assertThat(actual, instanceOf(IteratorStreamMergedResult.class));
}
@Test
@@ -207,9 +201,6 @@ class ShardingDQLResultMergerTest {
SubquerySegment subquerySegment = mock(SubquerySegment.class);
SelectStatement subSelectStatement = mock(SelectStatement.class);
ProjectionsSegment subProjectionsSegment = mock(ProjectionsSegment.class);
- TopProjectionSegment topProjectionSegment = mock(TopProjectionSegment.class);
- when(topProjectionSegment.getAlias()).thenReturn("row_id");
- when(subProjectionsSegment.getProjections()).thenReturn(Collections.singletonList(topProjectionSegment));
when(subSelectStatement.getProjections()).thenReturn(subProjectionsSegment);
when(subquerySegment.getSelect()).thenReturn(subSelectStatement);
when(subqueryTableSegment.getSubquery()).thenReturn(subquerySegment);
@@ -221,8 +212,7 @@ class ShardingDQLResultMergerTest {
SelectStatementContext selectStatementContext = new SelectStatementContext(oracleDatabaseType,
selectStatement, null, createShardingSphereMetaData(database), "foo_db", Collections.emptyList());
MergedResult actual = resultMerger.merge(createQueryResults(), selectStatementContext, createDatabase(), mock(ConnectionContext.class));
- assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class));
- assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(OrderByStreamMergedResult.class));
+ assertThat(actual, instanceOf(OrderByStreamMergedResult.class));
}
@Test
@@ -284,9 +274,6 @@ class ShardingDQLResultMergerTest {
SubquerySegment subquerySegment = mock(SubquerySegment.class);
SelectStatement subSelectStatement = mock(SelectStatement.class);
ProjectionsSegment subProjectionsSegment = mock(ProjectionsSegment.class);
- TopProjectionSegment topProjectionSegment = mock(TopProjectionSegment.class);
- when(topProjectionSegment.getAlias()).thenReturn("row_id");
- when(subProjectionsSegment.getProjections()).thenReturn(Collections.singletonList(topProjectionSegment));
when(subSelectStatement.getProjections()).thenReturn(subProjectionsSegment);
when(subquerySegment.getSelect()).thenReturn(subSelectStatement);
when(subqueryTableSegment.getSubquery()).thenReturn(subquerySegment);
@@ -299,8 +286,7 @@ class ShardingDQLResultMergerTest {
SelectStatementContext selectStatementContext = new SelectStatementContext(
oracleDatabaseType, selectStatement, null, createShardingSphereMetaData(database), "foo_db", Collections.emptyList());
MergedResult actual = resultMerger.merge(createQueryResults(), selectStatementContext, createDatabase(), mock(ConnectionContext.class));
- assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class));
- assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByStreamMergedResult.class));
+ assertThat(actual, instanceOf(GroupByStreamMergedResult.class));
}
@Test
@@ -361,9 +347,6 @@ class ShardingDQLResultMergerTest {
SubquerySegment subquerySegment = mock(SubquerySegment.class);
SelectStatement subSelectStatement = mock(SelectStatement.class);
ProjectionsSegment subProjectionsSegment = mock(ProjectionsSegment.class);
- TopProjectionSegment topProjectionSegment = mock(TopProjectionSegment.class);
- when(topProjectionSegment.getAlias()).thenReturn("row_id");
- when(subProjectionsSegment.getProjections()).thenReturn(Collections.singletonList(topProjectionSegment));
when(subSelectStatement.getProjections()).thenReturn(subProjectionsSegment);
when(subquerySegment.getSelect()).thenReturn(subSelectStatement);
when(subqueryTableSegment.getSubquery()).thenReturn(subquerySegment);
@@ -376,8 +359,7 @@ class ShardingDQLResultMergerTest {
SelectStatementContext selectStatementContext = new SelectStatementContext(
oracleDatabaseType, selectStatement, null, createShardingSphereMetaData(database), "foo_db", Collections.emptyList());
MergedResult actual = resultMerger.merge(createQueryResults(), selectStatementContext, createDatabase(), mock(ConnectionContext.class));
- assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class));
- assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByStreamMergedResult.class));
+ assertThat(actual, instanceOf(GroupByStreamMergedResult.class));
}
@Test
@@ -439,9 +421,6 @@ class ShardingDQLResultMergerTest {
SubquerySegment subquerySegment = mock(SubquerySegment.class);
SelectStatement subSelectStatement = mock(SelectStatement.class);
ProjectionsSegment subProjectionsSegment = mock(ProjectionsSegment.class);
- TopProjectionSegment topProjectionSegment = mock(TopProjectionSegment.class);
- when(topProjectionSegment.getAlias()).thenReturn("row_id");
- when(subProjectionsSegment.getProjections()).thenReturn(Collections.singletonList(topProjectionSegment));
when(subSelectStatement.getProjections()).thenReturn(subProjectionsSegment);
when(subquerySegment.getSelect()).thenReturn(subSelectStatement);
when(subqueryTableSegment.getSubquery()).thenReturn(subquerySegment);
@@ -454,8 +433,7 @@ class ShardingDQLResultMergerTest {
SelectStatementContext selectStatementContext = new SelectStatementContext(
oracleDatabaseType, selectStatement, null, createShardingSphereMetaData(database), "foo_db", Collections.emptyList());
MergedResult actual = resultMerger.merge(createQueryResults(), selectStatementContext, createDatabase(), mock(ConnectionContext.class));
- assertThat(actual, instanceOf(RowNumberDecoratorMergedResult.class));
- assertThat(((RowNumberDecoratorMergedResult) actual).getMergedResult(), instanceOf(GroupByMemoryMergedResult.class));
+ assertThat(actual, instanceOf(GroupByMemoryMergedResult.class));
}
@Test
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
index df7ea5ed781..2dee91490e5 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
@@ -34,8 +34,6 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.Bina
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.NumberLiteralRowNumberValueSegment;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.top.TopProjectionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
@@ -71,9 +69,6 @@ class RowNumberDecoratorMergedResultTest {
SubquerySegment subquerySegment = mock(SubquerySegment.class);
SelectStatement subSelectStatement = mock(SelectStatement.class);
ProjectionsSegment subProjectionsSegment = mock(ProjectionsSegment.class);
- TopProjectionSegment topProjectionSegment = mock(TopProjectionSegment.class);
- when(topProjectionSegment.getAlias()).thenReturn("row_id");
- when(subProjectionsSegment.getProjections()).thenReturn(Collections.singletonList(topProjectionSegment));
when(subSelectStatement.getProjections()).thenReturn(subProjectionsSegment);
when(subquerySegment.getSelect()).thenReturn(subSelectStatement);
when(subqueryTableSegment.getSubquery()).thenReturn(subquerySegment);
@@ -83,8 +78,11 @@ class RowNumberDecoratorMergedResultTest {
ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);
when(database.getName()).thenReturn("foo_db");
SelectStatementContext selectStatementContext = new SelectStatementContext(databaseType, selectStatement, null, createShardingSphereMetaData(database), "foo_db", Collections.emptyList());
- MergedResult actual = resultMerger.merge(Arrays.asList(mockQueryResult(), mockQueryResult(), mockQueryResult(), mockQueryResult()), selectStatementContext, database,
- mock(ConnectionContext.class));
+ MergedResult actual = resultMerger.merge(
+ Arrays.asList(mockQueryResult(), mockQueryResult(), mockQueryResult(), mockQueryResult()), selectStatementContext, database, mock(ConnectionContext.class));
+ for (int i = 0; i < 8; i++) {
+ assertTrue(actual.next());
+ }
assertFalse(actual.next());
}
@@ -119,10 +117,6 @@ class RowNumberDecoratorMergedResultTest {
SubquerySegment subquerySegment = mock(SubquerySegment.class);
SelectStatement subSelectStatement = mock(SelectStatement.class);
ProjectionsSegment subProjectionsSegment = mock(ProjectionsSegment.class);
- TopProjectionSegment topProjectionSegment = mock(TopProjectionSegment.class);
- when(topProjectionSegment.getAlias()).thenReturn("row_id");
- when(topProjectionSegment.getTop()).thenReturn(new NumberLiteralRowNumberValueSegment(0, 0, 4L, false));
- when(subProjectionsSegment.getProjections()).thenReturn(Collections.singletonList(topProjectionSegment));
when(subSelectStatement.getProjections()).thenReturn(subProjectionsSegment);
when(subquerySegment.getSelect()).thenReturn(subSelectStatement);
when(subqueryTableSegment.getSubquery()).thenReturn(subquerySegment);
@@ -134,8 +128,9 @@ class RowNumberDecoratorMergedResultTest {
SelectStatementContext selectStatementContext = new SelectStatementContext(databaseType, selectStatement, null, createShardingSphereMetaData(database), "foo_db", Collections.emptyList());
MergedResult actual = resultMerger.merge(Arrays.asList(mockQueryResult(), mockQueryResult(), mockQueryResult(), mockQueryResult()), selectStatementContext, database,
mock(ConnectionContext.class));
- assertTrue(actual.next());
- assertTrue(actual.next());
+ for (int i = 0; i < 8; i++) {
+ assertTrue(actual.next());
+ }
assertFalse(actual.next());
}
@@ -154,10 +149,6 @@ class RowNumberDecoratorMergedResultTest {
SubquerySegment subquerySegment = mock(SubquerySegment.class);
SelectStatement subSelectStatement = mock(SelectStatement.class);
ProjectionsSegment subProjectionsSegment = mock(ProjectionsSegment.class);
- TopProjectionSegment topProjectionSegment = mock(TopProjectionSegment.class);
- when(topProjectionSegment.getAlias()).thenReturn("row_id");
- when(topProjectionSegment.getTop()).thenReturn(new NumberLiteralRowNumberValueSegment(0, 0, 4L, true));
- when(subProjectionsSegment.getProjections()).thenReturn(Collections.singletonList(topProjectionSegment));
when(subSelectStatement.getProjections()).thenReturn(subProjectionsSegment);
when(subquerySegment.getSelect()).thenReturn(subSelectStatement);
when(subqueryTableSegment.getSubquery()).thenReturn(subquerySegment);
@@ -169,9 +160,9 @@ class RowNumberDecoratorMergedResultTest {
SelectStatementContext selectStatementContext = new SelectStatementContext(databaseType, selectStatement, null, createShardingSphereMetaData(database), "foo_db", Collections.emptyList());
MergedResult actual =
resultMerger.merge(Arrays.asList(mockQueryResult(), mockQueryResult(), mockQueryResult(), mockQueryResult()), selectStatementContext, database, mock(ConnectionContext.class));
- assertTrue(actual.next());
- assertTrue(actual.next());
- assertTrue(actual.next());
+ for (int i = 0; i < 8; i++) {
+ assertTrue(actual.next());
+ }
assertFalse(actual.next());
}
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngine.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngine.java
index 326d1860e23..77448c084a4 100644
--- a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngine.java
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngine.java
@@ -22,17 +22,12 @@ import org.apache.shardingsphere.infra.binder.context.segment.select.pagination.
import org.apache.shardingsphere.infra.binder.context.segment.select.projection.ProjectionsContext;
import org.apache.shardingsphere.infra.database.core.metadata.database.metadata.option.pagination.DialectPaginationOption;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.top.TopProjectionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
-import org.apache.shardingsphere.sql.parser.statement.core.util.SQLUtils;
import java.util.Collection;
-import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
@@ -43,7 +38,7 @@ import java.util.Optional;
@RequiredArgsConstructor
public final class PaginationContextEngine {
- private final DialectPaginationOption paginationOption;
+ private final DialectPaginationOption option;
/**
* Create pagination context.
@@ -64,40 +59,15 @@ public final class PaginationContextEngine {
for (WhereSegment each : whereSegments) {
expressions.add(each.getExpr());
}
- Optional<TopProjectionSegment> topProjectionSegment = findTopProjection(selectStatement);
- if (topProjectionSegment.isPresent()) {
- return new TopPaginationContextEngine().createPaginationContext(topProjectionSegment.get(), expressions, params);
- }
- if (!expressions.isEmpty() && paginationOption.isContainsRowNumber()) {
- return new RowNumberPaginationContextEngine(paginationOption).createPaginationContext(expressions, projectionsContext, params);
- }
- return new PaginationContext(null, null, params);
- }
-
- private Optional<TopProjectionSegment> findTopProjection(final SelectStatement selectStatement) {
- for (ProjectionSegment each : selectStatement.getProjections().getProjections()) {
- if (each instanceof SubqueryProjectionSegment) {
- return findTopProjection0(((SubqueryProjectionSegment) each).getSubquery().getSelect());
+ if (option.isContainsTop()) {
+ Optional<TopProjectionSegment> topProjectionSegment = TopProjectionExtractor.findTopProjection(selectStatement);
+ if (topProjectionSegment.isPresent()) {
+ return new TopPaginationContextEngine().createPaginationContext(topProjectionSegment.get(), expressions, params);
}
}
- return findTopProjection0(selectStatement);
- }
-
- private Optional<TopProjectionSegment> findTopProjection0(final SelectStatement selectStatement) {
- for (ProjectionSegment each : selectStatement.getProjections().getProjections()) {
- if (each instanceof TopProjectionSegment) {
- return Optional.of((TopProjectionSegment) each);
- }
+ if (!expressions.isEmpty() && option.isContainsRowNumber()) {
+ return new RowNumberPaginationContextEngine(option).createPaginationContext(expressions, projectionsContext, params);
}
- List<SubqueryTableSegment> subqueryTableSegments = selectStatement.getFrom().map(SQLUtils::getSubqueryTableSegmentFromTableSegment).orElse(Collections.emptyList());
- for (SubqueryTableSegment subquery : subqueryTableSegments) {
- SelectStatement subquerySelect = subquery.getSubquery().getSelect();
- for (ProjectionSegment each : subquerySelect.getProjections().getProjections()) {
- if (each instanceof TopProjectionSegment) {
- return Optional.of((TopProjectionSegment) each);
- }
- }
- }
- return Optional.empty();
+ return new PaginationContext(null, null, params);
}
}
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngine.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngine.java
index 80eebe1c623..a7e2c56f849 100644
--- a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngine.java
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngine.java
@@ -45,7 +45,7 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public final class RowNumberPaginationContextEngine {
- private final DialectPaginationOption paginationOption;
+ private final DialectPaginationOption option;
/**
* Create pagination context.
@@ -76,7 +76,7 @@ public final class RowNumberPaginationContextEngine {
}
private Optional<String> findRowNumberAlias(final ProjectionsContext projectionsContext) {
- String rowNumberColumnName = paginationOption.getRowNumberColumnName();
+ String rowNumberColumnName = option.getRowNumberColumnName();
if (Strings.isNullOrEmpty(rowNumberColumnName)) {
return Optional.empty();
}
@@ -89,7 +89,7 @@ public final class RowNumberPaginationContextEngine {
ExpressionSegment left = ((BinaryOperationExpression) predicate).getLeft();
if (left instanceof ColumnSegment) {
String leftColumnValue = ((ColumnSegment) left).getIdentifier().getValue();
- return leftColumnValue.equalsIgnoreCase(paginationOption.getRowNumberColumnName()) || leftColumnValue.equalsIgnoreCase(rowNumberAlias);
+ return leftColumnValue.equalsIgnoreCase(option.getRowNumberColumnName()) || leftColumnValue.equalsIgnoreCase(rowNumberAlias);
}
return false;
}
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngine.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/TopProjectionExtractor.java
similarity index 52%
copy from infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngine.java
copy to infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/TopProjectionExtractor.java
index 326d1860e23..dbb32b21e5b 100644
--- a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngine.java
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/TopProjectionExtractor.java
@@ -17,64 +17,32 @@
package org.apache.shardingsphere.infra.binder.context.segment.select.pagination.engine;
-import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.infra.binder.context.segment.select.pagination.PaginationContext;
-import org.apache.shardingsphere.infra.binder.context.segment.select.projection.ProjectionsContext;
-import org.apache.shardingsphere.infra.database.core.metadata.database.metadata.option.pagination.DialectPaginationOption;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.top.TopProjectionSegment;
-import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
import org.apache.shardingsphere.sql.parser.statement.core.util.SQLUtils;
-import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
/**
- * Pagination context engine.
+ * Top projection extractor.
*/
-@RequiredArgsConstructor
-public final class PaginationContextEngine {
-
- private final DialectPaginationOption paginationOption;
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class TopProjectionExtractor {
/**
- * Create pagination context.
+ * Find top projection.
*
- * @param selectStatement SQL statement
- * @param projectionsContext projections context
- * @param params SQL parameters
- * @param whereSegments where segments
- * @return pagination context
+ * @param selectStatement select statement
+ * @return top projection
*/
- public PaginationContext createPaginationContext(final SelectStatement selectStatement, final ProjectionsContext projectionsContext,
- final List<Object> params, final Collection<WhereSegment> whereSegments) {
- Optional<LimitSegment> limitSegment = selectStatement.getLimit();
- if (limitSegment.isPresent()) {
- return new LimitPaginationContextEngine().createPaginationContext(limitSegment.get(), params);
- }
- Collection<ExpressionSegment> expressions = new LinkedList<>();
- for (WhereSegment each : whereSegments) {
- expressions.add(each.getExpr());
- }
- Optional<TopProjectionSegment> topProjectionSegment = findTopProjection(selectStatement);
- if (topProjectionSegment.isPresent()) {
- return new TopPaginationContextEngine().createPaginationContext(topProjectionSegment.get(), expressions, params);
- }
- if (!expressions.isEmpty() && paginationOption.isContainsRowNumber()) {
- return new RowNumberPaginationContextEngine(paginationOption).createPaginationContext(expressions, projectionsContext, params);
- }
- return new PaginationContext(null, null, params);
- }
-
- private Optional<TopProjectionSegment> findTopProjection(final SelectStatement selectStatement) {
+ public static Optional<TopProjectionSegment> findTopProjection(final SelectStatement selectStatement) {
for (ProjectionSegment each : selectStatement.getProjections().getProjections()) {
if (each instanceof SubqueryProjectionSegment) {
return findTopProjection0(((SubqueryProjectionSegment) each).getSubquery().getSelect());
@@ -83,7 +51,7 @@ public final class PaginationContextEngine {
return findTopProjection0(selectStatement);
}
- private Optional<TopProjectionSegment> findTopProjection0(final SelectStatement selectStatement) {
+ private static Optional<TopProjectionSegment> findTopProjection0(final SelectStatement selectStatement) {
for (ProjectionSegment each : selectStatement.getProjections().getProjections()) {
if (each instanceof TopProjectionSegment) {
return Optional.of((TopProjectionSegment) each);
diff --git a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngineTest.java b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngineTest.java
index 8e4887322e5..287c9bccdea 100644
--- a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngineTest.java
+++ b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/PaginationContextEngineTest.java
@@ -30,6 +30,7 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.paginatio
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.NumberLiteralRowNumberValueSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.RowNumberValueSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.top.TopProjectionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
@@ -52,7 +53,7 @@ class PaginationContextEngineTest {
selectStatement.setLimit(new LimitSegment(0, 10, new NumberLiteralLimitValueSegment(0, 10, 100L),
new NumberLiteralLimitValueSegment(11, 20, 200L)));
PaginationContext paginationContext = new PaginationContextEngine(
- new DialectPaginationOption(false, "")).createPaginationContext(selectStatement, mock(ProjectionsContext.class), Collections.emptyList(), Collections.emptyList());
+ new DialectPaginationOption(false, "", false)).createPaginationContext(selectStatement, mock(ProjectionsContext.class), Collections.emptyList(), Collections.emptyList());
assertTrue(paginationContext.getOffsetSegment().isPresent());
assertThat(paginationContext.getOffsetSegment().get(), instanceOf(LimitValueSegment.class));
assertTrue(paginationContext.getRowCountSegment().isPresent());
@@ -63,12 +64,24 @@ class PaginationContextEngineTest {
void assertCreatePaginationContextWithTopSegment() {
SelectStatement subquerySelectStatement = new SelectStatement();
subquerySelectStatement.setProjections(new ProjectionsSegment(0, 0));
- subquerySelectStatement.getProjections().getProjections().add(new TopProjectionSegment(0, 10, null, ""));
+ RowNumberValueSegment topValueSegment = new NumberLiteralRowNumberValueSegment(0, 0, 100L, false);
+ subquerySelectStatement.getProjections().getProjections().add(new TopProjectionSegment(0, 10, topValueSegment, ""));
SelectStatement selectStatement = new SelectStatement();
selectStatement.setProjections(new ProjectionsSegment(0, 0));
selectStatement.getProjections().getProjections().add(new SubqueryProjectionSegment(new SubquerySegment(0, 0, subquerySelectStatement, ""), ""));
PaginationContext paginationContext = new PaginationContextEngine(
- new DialectPaginationOption(false, "")).createPaginationContext(selectStatement, mock(ProjectionsContext.class), Collections.emptyList(), Collections.emptyList());
+ new DialectPaginationOption(false, "", true)).createPaginationContext(selectStatement, mock(ProjectionsContext.class), Collections.emptyList(), Collections.emptyList());
+ assertFalse(paginationContext.getOffsetSegment().isPresent());
+ assertTrue(paginationContext.getRowCountSegment().isPresent());
+ assertThat(paginationContext.getRowCountSegment().get(), instanceOf(NumberLiteralRowNumberValueSegment.class));
+ }
+
+ @Test
+ void assertCreatePaginationContextWithoutTopSegment() {
+ SelectStatement selectStatement = new SelectStatement();
+ selectStatement.setProjections(new ProjectionsSegment(0, 0));
+ PaginationContext paginationContext = new PaginationContextEngine(
+ new DialectPaginationOption(false, "", true)).createPaginationContext(selectStatement, mock(ProjectionsContext.class), Collections.emptyList(), Collections.emptyList());
assertFalse(paginationContext.getOffsetSegment().isPresent());
assertFalse(paginationContext.getRowCountSegment().isPresent());
}
@@ -83,7 +96,7 @@ class PaginationContextEngineTest {
selectStatement.setWhere(where);
ProjectionsContext projectionsContext = new ProjectionsContext(0, 0, false, Collections.emptyList());
PaginationContext paginationContext = new PaginationContextEngine(
- new DialectPaginationOption(true, "ROW_NUMBER")).createPaginationContext(selectStatement, projectionsContext, Collections.emptyList(), Collections.singletonList(where));
+ new DialectPaginationOption(true, "ROW_NUMBER", false)).createPaginationContext(selectStatement, projectionsContext, Collections.emptyList(), Collections.singletonList(where));
assertFalse(paginationContext.getOffsetSegment().isPresent());
assertTrue(paginationContext.getRowCountSegment().isPresent());
assertThat(paginationContext.getRowCountSegment().get(), instanceOf(NumberLiteralRowNumberValueSegment.class));
@@ -99,7 +112,7 @@ class PaginationContextEngineTest {
selectStatement.setWhere(where);
ProjectionsContext projectionsContext = new ProjectionsContext(0, 0, false, Collections.emptyList());
PaginationContext paginationContext = new PaginationContextEngine(
- new DialectPaginationOption(false, "")).createPaginationContext(selectStatement, projectionsContext, Collections.emptyList(), Collections.singletonList(where));
+ new DialectPaginationOption(false, "", false)).createPaginationContext(selectStatement, projectionsContext, Collections.emptyList(), Collections.singletonList(where));
assertFalse(paginationContext.getOffsetSegment().isPresent());
assertFalse(paginationContext.getRowCountSegment().isPresent());
}
@@ -110,7 +123,7 @@ class PaginationContextEngineTest {
selectStatement.setProjections(new ProjectionsSegment(0, 0));
ProjectionsContext projectionsContext = new ProjectionsContext(0, 0, false, Collections.emptyList());
PaginationContext paginationContext = new PaginationContextEngine(
- new DialectPaginationOption(false, "")).createPaginationContext(selectStatement, projectionsContext, Collections.emptyList(), Collections.emptyList());
+ new DialectPaginationOption(false, "", false)).createPaginationContext(selectStatement, projectionsContext, Collections.emptyList(), Collections.emptyList());
assertFalse(paginationContext.getOffsetSegment().isPresent());
assertFalse(paginationContext.getRowCountSegment().isPresent());
}
diff --git a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngineTest.java b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngineTest.java
index dd0c0748dad..31c8e149c24 100644
--- a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngineTest.java
+++ b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/select/pagination/engine/RowNumberPaginationContextEngineTest.java
@@ -50,7 +50,7 @@ class RowNumberPaginationContextEngineTest {
private static final String ROW_NUMBER_COLUMN_ALIAS = "predicateRowNumberAlias";
- private final RowNumberPaginationContextEngine paginationContextEngine = new RowNumberPaginationContextEngine(new DialectPaginationOption(true, "ROWNUM"));
+ private final RowNumberPaginationContextEngine paginationContextEngine = new RowNumberPaginationContextEngine(new DialectPaginationOption(true, "ROWNUM", false));
@Test
void assertCreatePaginationContextWhenRowNumberAliasNotPresent() {
diff --git a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/metadata/DialectDatabaseMetaData.java b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/metadata/DialectDatabaseMetaData.java
index c4b8eacb444..5296fb5c5ea 100644
--- a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/metadata/DialectDatabaseMetaData.java
+++ b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/metadata/DialectDatabaseMetaData.java
@@ -145,7 +145,7 @@ public interface DialectDatabaseMetaData extends DatabaseTypedSPI {
* @return pagination option
*/
default DialectPaginationOption getPaginationOption() {
- return new DialectPaginationOption(false, "");
+ return new DialectPaginationOption(false, "", false);
}
/**
diff --git a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/metadata/option/pagination/DialectPaginationOption.java b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/metadata/option/pagination/DialectPaginationOption.java
index fea40c90a87..948fcbda0d1 100644
--- a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/metadata/option/pagination/DialectPaginationOption.java
+++ b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/metadata/option/pagination/DialectPaginationOption.java
@@ -30,4 +30,6 @@ public final class DialectPaginationOption {
private final boolean containsRowNumber;
private final String rowNumberColumnName;
+
+ private final boolean containsTop;
}
diff --git a/infra/database/type/oracle/src/main/java/org/apache/shardingsphere/infra/database/oracle/metadata/database/OracleDatabaseMetaData.java b/infra/database/type/oracle/src/main/java/org/apache/shardingsphere/infra/database/oracle/metadata/database/OracleDatabaseMetaData.java
index fe4a10333e7..c23a3e5c76f 100644
--- a/infra/database/type/oracle/src/main/java/org/apache/shardingsphere/infra/database/oracle/metadata/database/OracleDatabaseMetaData.java
+++ b/infra/database/type/oracle/src/main/java/org/apache/shardingsphere/infra/database/oracle/metadata/database/OracleDatabaseMetaData.java
@@ -74,7 +74,7 @@ public final class OracleDatabaseMetaData implements DialectDatabaseMetaData {
@Override
public DialectPaginationOption getPaginationOption() {
- return new DialectPaginationOption(true, "ROWNUM");
+ return new DialectPaginationOption(true, "ROWNUM", false);
}
@Override
diff --git a/infra/database/type/sqlserver/src/main/java/org/apache/shardingsphere/infra/database/sqlserver/metadata/database/SQLServerDatabaseMetaData.java b/infra/database/type/sqlserver/src/main/java/org/apache/shardingsphere/infra/database/sqlserver/metadata/database/SQLServerDatabaseMetaData.java
index 2e7ffaf6787..3d17ae1a828 100644
--- a/infra/database/type/sqlserver/src/main/java/org/apache/shardingsphere/infra/database/sqlserver/metadata/database/SQLServerDatabaseMetaData.java
+++ b/infra/database/type/sqlserver/src/main/java/org/apache/shardingsphere/infra/database/sqlserver/metadata/database/SQLServerDatabaseMetaData.java
@@ -55,7 +55,7 @@ public final class SQLServerDatabaseMetaData implements DialectDatabaseMetaData
@Override
public DialectPaginationOption getPaginationOption() {
- return new DialectPaginationOption(true, "ROW_NUMBER");
+ return new DialectPaginationOption(true, "ROW_NUMBER", true);
}
@Override
diff --git a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/QueryResult.java b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/QueryResult.java
index 32f47ca1c20..0ef5bdc7093 100644
--- a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/QueryResult.java
+++ b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/QueryResult.java
@@ -58,7 +58,7 @@ public interface QueryResult extends ExecuteResult, AutoCloseable {
* @return calendar value
* @throws SQLException SQL exception
*/
- Object getCalendarValue(int columnIndex, Class<?> type, Calendar calendar) throws SQLException;
+ Object getCalendarValue(int columnIndex, Class<?> type, @SuppressWarnings("UseOfObsoleteDateTimeApi") Calendar calendar) throws SQLException;
/**
* Get input stream.