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 2c8a822716b Add test cases on sharding SQLTokenGenerator's impl (#33693) 2c8a822716b is described below commit 2c8a822716b2ec17e6ad78dd12bb826a9f235315 Author: Liang Zhang <zhangli...@apache.org> AuthorDate: Sun Nov 17 01:28:44 2024 +0800 Add test cases on sharding SQLTokenGenerator's impl (#33693) * Add more test cases on ShardingAggregationDistinctTokenGenerator * Add more test cases on ShardingConstraintTokenGenerator * Add more test cases on ShardingCursorTokenGenerator * Add more test cases on ShardingCursorTokenGenerator * Add more test cases on ShardingDistinctProjectionPrefixTokenGenerator * Add more test cases on ShardingIndexTokenGenerator * Add more test cases on ShardingInsertValuesTokenGenerator * Add more test cases on ShardingOffsetTokenGenerator * Add more test cases on ShardingRemoveTokenGenerator * Add more test cases on ShardingOrderByTokenGenerator * Add more test cases on ShardingProjectionsTokenGenerator * Add more test cases on ShardingProjectionsTokenGenerator * Add more test cases on ShardingProjectionsTokenGenerator * Add more test cases on ShardingProjectionsTokenGenerator * Add more test cases on ShardingProjectionsTokenGenerator * Add more test cases on ShardingProjectionsTokenGenerator * Add more test cases on ShardingProjectionsTokenGenerator * Add more test cases on ShardingRowCountTokenGenerator * Add more test cases on ShardingTableTokenGenerator * Add more test cases on ShardingTableTokenGenerator --- .../impl/ShardingCursorTokenGenerator.java | 4 +- .../impl/ShardingProjectionsTokenGenerator.java | 69 +++++------ .../impl/ShardingRemoveTokenGenerator.java | 8 +- .../impl/ShardingTableTokenGenerator.java | 7 +- ...rdingAggregationDistinctTokenGeneratorTest.java | 53 +++++---- .../impl/ShardingConstraintTokenGeneratorTest.java | 22 ++-- .../impl/ShardingCursorTokenGeneratorTest.java | 42 ++++--- ...DistinctProjectionPrefixTokenGeneratorTest.java | 32 ++--- .../impl/ShardingIndexTokenGeneratorTest.java | 11 +- .../ShardingInsertValuesTokenGeneratorTest.java | 8 +- .../impl/ShardingOffsetTokenGeneratorTest.java | 7 +- .../impl/ShardingOrderByTokenGeneratorTest.java | 104 +++++++++++++--- .../ShardingProjectionsTokenGeneratorTest.java | 131 +++++++++------------ .../impl/ShardingRemoveTokenGeneratorTest.java | 27 +++-- .../impl/ShardingRowCountTokenGeneratorTest.java | 62 ++++++---- .../impl/ShardingTableTokenGeneratorTest.java | 75 +++++++----- 16 files changed, 362 insertions(+), 300 deletions(-) diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingCursorTokenGenerator.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingCursorTokenGenerator.java index 29608a0d9b5..58f7bfa98c9 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingCursorTokenGenerator.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingCursorTokenGenerator.java @@ -42,7 +42,7 @@ public final class ShardingCursorTokenGenerator implements OptionalSQLTokenGener @Override public SQLToken generateSQLToken(final SQLStatementContext sqlStatementContext) { - CursorNameSegment cursorName = ((CursorAvailable) sqlStatementContext).getCursorName().orElseThrow(CursorNameNotFoundException::new); - return new CursorToken(cursorName.getStartIndex(), cursorName.getStopIndex(), cursorName.getIdentifier(), sqlStatementContext, rule); + CursorNameSegment cursorNameSegment = ((CursorAvailable) sqlStatementContext).getCursorName().orElseThrow(CursorNameNotFoundException::new); + return new CursorToken(cursorNameSegment.getStartIndex(), cursorNameSegment.getStopIndex(), cursorNameSegment.getIdentifier(), sqlStatementContext, rule); } } diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingProjectionsTokenGenerator.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingProjectionsTokenGenerator.java index 502366fd97f..ccd585319af 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingProjectionsTokenGenerator.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingProjectionsTokenGenerator.java @@ -35,7 +35,6 @@ import org.apache.shardingsphere.infra.route.context.RouteMapper; import org.apache.shardingsphere.infra.route.context.RouteUnit; import org.apache.shardingsphere.sharding.rewrite.token.generator.IgnoreForSingleRoute; import org.apache.shardingsphere.sharding.rewrite.token.pojo.ProjectionsToken; -import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment; @@ -59,7 +58,16 @@ public final class ShardingProjectionsTokenGenerator implements OptionalSQLToken @Override public boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) { - return sqlStatementContext instanceof SelectStatementContext && !getDerivedProjectionTexts((SelectStatementContext) sqlStatementContext).isEmpty(); + return sqlStatementContext instanceof SelectStatementContext && containsDerivedProjections((SelectStatementContext) sqlStatementContext); + } + + private boolean containsDerivedProjections(final SelectStatementContext selectStatementContext) { + for (Projection each : selectStatementContext.getProjectionsContext().getProjections()) { + if (each instanceof AggregationProjection && !((AggregationProjection) each).getDerivedAggregationProjections().isEmpty() || each instanceof DerivedProjection) { + return true; + } + } + return false; } @Override @@ -70,24 +78,21 @@ public final class ShardingProjectionsTokenGenerator implements OptionalSQLToken private Map<RouteUnit, Collection<String>> getDerivedProjectionTexts(final SelectStatementContext selectStatementContext) { Map<RouteUnit, Collection<String>> result = new HashMap<>(routeContext.getRouteUnits().size(), 1F); - for (RouteUnit routeUnit : routeContext.getRouteUnits()) { - Collection<String> projectionTexts = getDerivedProjectionTextsByRouteUnit(selectStatementContext, routeUnit); - if (!projectionTexts.isEmpty()) { - result.put(routeUnit, projectionTexts); - } + for (RouteUnit each : routeContext.getRouteUnits()) { + result.put(each, getDerivedProjectionTexts(selectStatementContext, each)); } return result; } - private Collection<String> getDerivedProjectionTextsByRouteUnit(final SelectStatementContext selectStatementContext, final RouteUnit routeUnit) { + private Collection<String> getDerivedProjectionTexts(final SelectStatementContext selectStatementContext, final RouteUnit routeUnit) { Collection<String> result = new LinkedList<>(); for (Projection each : selectStatementContext.getProjectionsContext().getProjections()) { - if (each instanceof AggregationProjection && !((AggregationProjection) each).getDerivedAggregationProjections().isEmpty()) { + if (each instanceof AggregationProjection) { result.addAll(((AggregationProjection) each).getDerivedAggregationProjections().stream().map(this::getDerivedProjectionText).collect(Collectors.toList())); } else if (each instanceof DerivedProjection && ((DerivedProjection) each).getDerivedProjectionSegment() instanceof ColumnOrderByItemSegment) { TableExtractor tableExtractor = new TableExtractor(); tableExtractor.extractTablesFromSelect(selectStatementContext.getSqlStatement()); - result.add(getDerivedProjectionTextFromColumnOrderByItemSegment((DerivedProjection) each, tableExtractor, routeUnit, selectStatementContext.getDatabaseType())); + result.add(getDerivedProjectionText((DerivedProjection) each, tableExtractor, routeUnit, selectStatementContext.getDatabaseType())); } else if (each instanceof DerivedProjection) { result.add(getDerivedProjectionText(each)); } @@ -97,14 +102,11 @@ public final class ShardingProjectionsTokenGenerator implements OptionalSQLToken private String getDerivedProjectionText(final Projection projection) { Preconditions.checkState(projection.getAlias().isPresent()); - if (projection instanceof AggregationDistinctProjection) { - return ((AggregationDistinctProjection) projection).getDistinctInnerExpression() + " AS " + projection.getAlias().get().getValue() + " "; - } - return projection.getExpression() + " AS " + projection.getAlias().get().getValue() + " "; + String projectionExpression = projection instanceof AggregationDistinctProjection ? ((AggregationDistinctProjection) projection).getDistinctInnerExpression() : projection.getExpression(); + return projectionExpression + " AS " + projection.getAlias().get().getValue() + " "; } - private String getDerivedProjectionTextFromColumnOrderByItemSegment(final DerivedProjection projection, final TableExtractor tableExtractor, final RouteUnit routeUnit, - final DatabaseType databaseType) { + private String getDerivedProjectionText(final DerivedProjection projection, final TableExtractor tableExtractor, final RouteUnit routeUnit, final DatabaseType databaseType) { Preconditions.checkState(projection.getAlias().isPresent()); Preconditions.checkState(projection.getDerivedProjectionSegment() instanceof ColumnOrderByItemSegment); ColumnOrderByItemSegment columnOrderByItemSegment = (ColumnOrderByItemSegment) projection.getDerivedProjectionSegment(); @@ -112,33 +114,26 @@ public final class ShardingProjectionsTokenGenerator implements OptionalSQLToken return newColumnOrderByItem.getText() + " AS " + projection.getAlias().get().getValue() + " "; } - private Optional<String> getActualTables(final RouteUnit routeUnit, final String logicalTableName) { - for (RouteMapper each : routeUnit.getTableMappers()) { - if (each.getLogicName().equalsIgnoreCase(logicalTableName)) { - return Optional.of(each.getActualName()); - } - } - return Optional.empty(); - } - - private ColumnOrderByItemSegment generateNewColumnOrderByItem(final ColumnOrderByItemSegment old, final RouteUnit routeUnit, final TableExtractor tableExtractor, final DatabaseType databaseType) { + private ColumnOrderByItemSegment generateNewColumnOrderByItem(final ColumnOrderByItemSegment old, + final RouteUnit routeUnit, final TableExtractor tableExtractor, final DatabaseType databaseType) { Optional<OwnerSegment> ownerSegment = old.getColumn().getOwner(); - if (!ownerSegment.isPresent()) { - return old; - } - if (!tableExtractor.needRewrite(ownerSegment.get())) { + if (!ownerSegment.isPresent() || !tableExtractor.needRewrite(ownerSegment.get())) { return old; } - Optional<String> actualTableName = getActualTables(routeUnit, ownerSegment.get().getIdentifier().getValue()); - Preconditions.checkState(actualTableName.isPresent()); + String actualTableName = getActualTableName(routeUnit, ownerSegment.get().getIdentifier().getValue()); + OwnerSegment newOwner = new OwnerSegment(0, 0, new IdentifierValue(ownerSegment.get().getIdentifier().getQuoteCharacter().wrap(actualTableName))); ColumnSegment newColumnSegment = new ColumnSegment(0, 0, old.getColumn().getIdentifier()); - IdentifierValue newOwnerIdentifier = new IdentifierValue(ownerSegment.get().getIdentifier().getQuoteCharacter().wrap(actualTableName.get())); - OwnerSegment newOwner = new OwnerSegment(0, 0, newOwnerIdentifier); newColumnSegment.setOwner(newOwner); - return new ColumnOrderByItemSegment(newColumnSegment, old.getOrderDirection(), generateNewNullsOrderType(old.getOrderDirection(), databaseType)); + NullsOrderType nullsOrderType = new DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData().getDefaultNullsOrderType().getResolvedOrderType(old.getOrderDirection().name()); + return new ColumnOrderByItemSegment(newColumnSegment, old.getOrderDirection(), nullsOrderType); } - private NullsOrderType generateNewNullsOrderType(final OrderDirection orderDirection, final DatabaseType databaseType) { - return new DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData().getDefaultNullsOrderType().getResolvedOrderType(orderDirection.name()); + private String getActualTableName(final RouteUnit routeUnit, final String logicalTableName) { + for (RouteMapper each : routeUnit.getTableMappers()) { + if (each.getLogicName().equalsIgnoreCase(logicalTableName)) { + return each.getActualName(); + } + } + throw new IllegalStateException(String.format("Cannot find actual table name with logic table name '%s'", logicalTableName)); } } diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRemoveTokenGenerator.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRemoveTokenGenerator.java index 49eda12526c..d57b08db77c 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRemoveTokenGenerator.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRemoveTokenGenerator.java @@ -30,7 +30,7 @@ import java.util.LinkedList; /** * Sharding remove token generator. */ -public final class ShardingRemoveTokenGenerator implements CollectionSQLTokenGenerator<SQLStatementContext>, IgnoreForSingleRoute { +public final class ShardingRemoveTokenGenerator implements CollectionSQLTokenGenerator<SelectStatementContext>, IgnoreForSingleRoute { @Override public boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) { @@ -42,11 +42,9 @@ public final class ShardingRemoveTokenGenerator implements CollectionSQLTokenGen } @Override - public Collection<SQLToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) { + public Collection<SQLToken> generateSQLTokens(final SelectStatementContext sqlStatementContext) { Collection<SQLToken> result = new LinkedList<>(); - if (isContainsAggregationDistinctProjection(sqlStatementContext)) { - ((SelectStatementContext) sqlStatementContext).getSqlStatement().getGroupBy().ifPresent(optional -> result.add(new RemoveToken(optional.getStartIndex(), optional.getStopIndex()))); - } + sqlStatementContext.getSqlStatement().getGroupBy().ifPresent(optional -> result.add(new RemoveToken(optional.getStartIndex(), optional.getStopIndex()))); return result; } } diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingTableTokenGenerator.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingTableTokenGenerator.java index 0cf894ea8be..a36026ba80e 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingTableTokenGenerator.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingTableTokenGenerator.java @@ -66,9 +66,10 @@ public final class ShardingTableTokenGenerator implements CollectionSQLTokenGene private Collection<SQLToken> generateSQLTokens(final TableAvailable sqlStatementContext) { Collection<SQLToken> result = new LinkedList<>(); for (SimpleTableSegment each : sqlStatementContext.getTablesContext().getSimpleTables()) { - TableNameSegment tableName = each.getTableName(); - if (rule.findShardingTable(tableName.getIdentifier().getValue()).isPresent()) { - result.add(new ShardingTableToken(tableName.getStartIndex(), tableName.getStopIndex(), tableName.getIdentifier(), (SQLStatementContext) sqlStatementContext, rule)); + TableNameSegment tableNameSegment = each.getTableName(); + if (rule.findShardingTable(tableNameSegment.getIdentifier().getValue()).isPresent()) { + result.add( + new ShardingTableToken(tableNameSegment.getStartIndex(), tableNameSegment.getStopIndex(), tableNameSegment.getIdentifier(), (SQLStatementContext) sqlStatementContext, rule)); } } return result; diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingAggregationDistinctTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingAggregationDistinctTokenGeneratorTest.java index 3f83f418787..9a0c0108477 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingAggregationDistinctTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingAggregationDistinctTokenGeneratorTest.java @@ -18,7 +18,7 @@ package org.apache.shardingsphere.sharding.rewrite.token.generator.impl; import org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.AggregationDistinctProjection; -import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; @@ -39,35 +39,44 @@ import static org.mockito.Mockito.when; class ShardingAggregationDistinctTokenGeneratorTest { + private final ShardingAggregationDistinctTokenGenerator generator = new ShardingAggregationDistinctTokenGenerator(); + + @Test + void assertIsNotGenerateSQLTokenWithNotSelectStatementContext() { + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); + } + @Test - void assertIsGenerateSQLToken() { - ShardingAggregationDistinctTokenGenerator aggregationDistinctTokenGenerator = new ShardingAggregationDistinctTokenGenerator(); + void assertIsNotGenerateSQLTokenWithEmptyAggregationDistinctProjection() { + SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); + when(sqlStatementContext.getProjectionsContext().getAggregationDistinctProjections().isEmpty()).thenReturn(true); + assertFalse(generator.isGenerateSQLToken(sqlStatementContext)); + } + + @Test + void assertIsGenerateSQLTokenWithAggregationDistinctProjections() { + assertTrue(generator.isGenerateSQLToken(mock(SelectStatementContext.class, RETURNS_DEEP_STUBS))); + } + + @Test + void assertGenerateSQLTokenWithDerivedAlias() { + AggregationDistinctProjection aggregationDistinctProjection = mock(AggregationDistinctProjection.class); + when(aggregationDistinctProjection.getAlias()).thenReturn(Optional.of(new IdentifierValue("AVG_DERIVED_COUNT_0"))); + when(aggregationDistinctProjection.getDistinctInnerExpression()).thenReturn("TEST_DISTINCT_INNER_EXPRESSION"); SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(selectStatementContext.getProjectionsContext().getAggregationDistinctProjections()).thenReturn(Collections.emptyList()); - assertFalse(aggregationDistinctTokenGenerator.isGenerateSQLToken(selectStatementContext)); - SelectStatementContext selectStatementWithProjectionContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(selectStatementWithProjectionContext.getProjectionsContext().getAggregationDistinctProjections()).thenReturn(Collections.singletonList(mock(AggregationDistinctProjection.class))); - assertTrue(aggregationDistinctTokenGenerator.isGenerateSQLToken(selectStatementWithProjectionContext)); - InsertStatementContext insertStatementContext = mock(InsertStatementContext.class); - assertFalse(aggregationDistinctTokenGenerator.isGenerateSQLToken(insertStatementContext)); + when(selectStatementContext.getProjectionsContext().getAggregationDistinctProjections()).thenReturn(Collections.singleton(aggregationDistinctProjection)); + List<SQLToken> actual = new ArrayList<>(generator.generateSQLTokens(selectStatementContext)); + assertThat(actual.get(0).toString(), is("TEST_DISTINCT_INNER_EXPRESSION AS AVG_DERIVED_COUNT_0")); } @Test void assertGenerateSQLToken() { AggregationDistinctProjection aggregationDistinctProjection = mock(AggregationDistinctProjection.class); - String testAlias = "AVG_DERIVED_COUNT_0"; - when(aggregationDistinctProjection.getAlias()).thenReturn(Optional.of(new IdentifierValue(testAlias))); - when(aggregationDistinctProjection.getStartIndex()).thenReturn(0); - when(aggregationDistinctProjection.getStopIndex()).thenReturn(2); - String testDistinctInnerExpression = "TEST_DISTINCT_INNER_EXPRESSION"; - when(aggregationDistinctProjection.getDistinctInnerExpression()).thenReturn(testDistinctInnerExpression); + when(aggregationDistinctProjection.getDistinctInnerExpression()).thenReturn("TEST_DISTINCT_INNER_EXPRESSION"); SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(selectStatementContext.getProjectionsContext().getAggregationDistinctProjections()).thenReturn(Collections.singletonList(aggregationDistinctProjection)); - ShardingAggregationDistinctTokenGenerator aggregationDistinctTokenGenerator = new ShardingAggregationDistinctTokenGenerator(); - List<SQLToken> generateSQLTokensResult = new ArrayList<>(aggregationDistinctTokenGenerator.generateSQLTokens(selectStatementContext)); - assertThat(generateSQLTokensResult.get(0).toString(), is(testDistinctInnerExpression + " AS " + testAlias)); + when(selectStatementContext.getProjectionsContext().getAggregationDistinctProjections()).thenReturn(Collections.singleton(aggregationDistinctProjection)); when(aggregationDistinctProjection.getAlias()).thenReturn(Optional.of(new IdentifierValue("TEST_ERROR_ALIAS"))); - generateSQLTokensResult = new ArrayList<>(aggregationDistinctTokenGenerator.generateSQLTokens(selectStatementContext)); - assertThat(generateSQLTokensResult.get(0).toString(), is(testDistinctInnerExpression)); + List<SQLToken> actual = new ArrayList<>(generator.generateSQLTokens(selectStatementContext)); + assertThat(actual.get(0).toString(), is("TEST_DISTINCT_INNER_EXPRESSION")); } } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingConstraintTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingConstraintTokenGeneratorTest.java index 6921f800c8b..7634de75d30 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingConstraintTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingConstraintTokenGeneratorTest.java @@ -39,15 +39,15 @@ import static org.mockito.Mockito.when; class ShardingConstraintTokenGeneratorTest { + private final ShardingConstraintTokenGenerator generator = new ShardingConstraintTokenGenerator(mock(ShardingRule.class)); + @Test void assertIsNotGenerateSQLTokenWithNotConstraintAvailable() { - ShardingConstraintTokenGenerator generator = new ShardingConstraintTokenGenerator(mock(ShardingRule.class)); assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); } @Test void assertIsNotGenerateSQLTokenWithEmptyConstraint() { - ShardingConstraintTokenGenerator generator = new ShardingConstraintTokenGenerator(mock(ShardingRule.class)); AlterTableStatementContext alterTableStatementContext = mock(AlterTableStatementContext.class, RETURNS_DEEP_STUBS); when(alterTableStatementContext.getConstraints().isEmpty()).thenReturn(true); assertFalse(generator.isGenerateSQLToken(alterTableStatementContext)); @@ -55,33 +55,29 @@ class ShardingConstraintTokenGeneratorTest { @Test void assertIsGenerateSQLToken() { - ShardingConstraintTokenGenerator generator = new ShardingConstraintTokenGenerator(mock(ShardingRule.class)); AlterTableStatementContext alterTableStatementContext = mock(AlterTableStatementContext.class, RETURNS_DEEP_STUBS); assertTrue(generator.isGenerateSQLToken(alterTableStatementContext)); } @Test void assertGenerateSQLTokensWithNotConstraintAvailable() { - ShardingConstraintTokenGenerator generator = new ShardingConstraintTokenGenerator(mock(ShardingRule.class)); Collection<SQLToken> actual = generator.generateSQLTokens(mock(SQLStatementContext.class)); assertTrue(actual.isEmpty()); } @Test void assertGenerateSQLTokens() { - ConstraintSegment constraintSegment = mock(ConstraintSegment.class); - when(constraintSegment.getStartIndex()).thenReturn(1); - when(constraintSegment.getStopIndex()).thenReturn(3); - IdentifierValue constraintIdentifier = mock(IdentifierValue.class); - when(constraintSegment.getIdentifier()).thenReturn(constraintIdentifier); - AlterTableStatementContext alterTableStatementContext = mock(AlterTableStatementContext.class); - when(alterTableStatementContext.getConstraints()).thenReturn(Collections.singleton(constraintSegment)); - ShardingConstraintTokenGenerator generator = new ShardingConstraintTokenGenerator(mock(ShardingRule.class)); - Collection<SQLToken> actual = generator.generateSQLTokens(alterTableStatementContext); + Collection<SQLToken> actual = generator.generateSQLTokens(mockAlterTableStatementContext()); assertThat(actual.size(), is(1)); assertConstraintToken((ConstraintToken) actual.iterator().next()); } + private AlterTableStatementContext mockAlterTableStatementContext() { + AlterTableStatementContext result = mock(AlterTableStatementContext.class); + when(result.getConstraints()).thenReturn(Collections.singleton(new ConstraintSegment(1, 3, mock(IdentifierValue.class)))); + return result; + } + private void assertConstraintToken(final ConstraintToken actual) { assertThat(actual.getStartIndex(), is(1)); assertThat(actual.getStopIndex(), is(3)); diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingCursorTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingCursorTokenGeneratorTest.java index 6085dfdd835..79d6d2374d2 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingCursorTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingCursorTokenGeneratorTest.java @@ -17,11 +17,8 @@ package org.apache.shardingsphere.sharding.rewrite.token.generator.impl; -import org.apache.shardingsphere.infra.binder.context.statement.ddl.CloseStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.ddl.CursorStatementContext; -import org.apache.shardingsphere.infra.binder.context.statement.ddl.FetchStatementContext; -import org.apache.shardingsphere.infra.binder.context.statement.ddl.MoveStatementContext; -import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken; import org.apache.shardingsphere.sharding.rewrite.token.pojo.CursorToken; import org.apache.shardingsphere.sharding.rule.ShardingRule; @@ -40,30 +37,31 @@ import static org.mockito.Mockito.when; class ShardingCursorTokenGeneratorTest { + private final ShardingCursorTokenGenerator generator = new ShardingCursorTokenGenerator(mock(ShardingRule.class)); + + @Test + void assertIsNotGenerateSQLTokenWithNotCursorAvailable() { + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); + } + + @Test + void assertIsNotGenerateSQLTokenWithoutCursorName() { + CursorStatementContext sqlStatementContext = mock(CursorStatementContext.class); + when(sqlStatementContext.getCursorName()).thenReturn(Optional.empty()); + assertFalse(generator.isGenerateSQLToken(sqlStatementContext)); + } + @Test - void assertIsGenerateSQLToken() { - ShardingCursorTokenGenerator generator = new ShardingCursorTokenGenerator(mock(ShardingRule.class)); - assertFalse(generator.isGenerateSQLToken(mock(SelectStatementContext.class))); - Optional<CursorNameSegment> cursorName = Optional.of(new CursorNameSegment(0, 0, new IdentifierValue("t_order_cursor"))); - CursorStatementContext cursorStatementContext = mock(CursorStatementContext.class); - when(cursorStatementContext.getCursorName()).thenReturn(cursorName); - assertTrue(generator.isGenerateSQLToken(cursorStatementContext)); - CloseStatementContext closeStatementContext = mock(CloseStatementContext.class); - when(closeStatementContext.getCursorName()).thenReturn(cursorName); - assertTrue(generator.isGenerateSQLToken(closeStatementContext)); - MoveStatementContext moveStatementContext = mock(MoveStatementContext.class); - when(moveStatementContext.getCursorName()).thenReturn(cursorName); - assertTrue(generator.isGenerateSQLToken(moveStatementContext)); - FetchStatementContext fetchStatementContext = mock(FetchStatementContext.class); - when(fetchStatementContext.getCursorName()).thenReturn(cursorName); - assertTrue(generator.isGenerateSQLToken(fetchStatementContext)); + void assertIsGenerateSQLTokenWithCursorName() { + CursorStatementContext sqlStatementContext = mock(CursorStatementContext.class); + when(sqlStatementContext.getCursorName()).thenReturn(Optional.of(mock(CursorNameSegment.class))); + assertTrue(generator.isGenerateSQLToken(sqlStatementContext)); } @Test void assertGenerateSQLToken() { - ShardingCursorTokenGenerator generator = new ShardingCursorTokenGenerator(mock(ShardingRule.class)); CursorStatementContext statementContext = mock(CursorStatementContext.class); - when(statementContext.getCursorName()).thenReturn(Optional.of(new CursorNameSegment(0, 0, new IdentifierValue("t_order_cursor")))); + when(statementContext.getCursorName()).thenReturn(Optional.of(new CursorNameSegment(0, 0, new IdentifierValue("foo_cursor")))); SQLToken actual = generator.generateSQLToken(statementContext); assertThat(actual, instanceOf(CursorToken.class)); } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingDistinctProjectionPrefixTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingDistinctProjectionPrefixTokenGeneratorTest.java index c2c83ab7126..3816eacfe74 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingDistinctProjectionPrefixTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingDistinctProjectionPrefixTokenGeneratorTest.java @@ -17,14 +17,10 @@ package org.apache.shardingsphere.sharding.rewrite.token.generator.impl; -import org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.AggregationDistinctProjection; -import org.apache.shardingsphere.infra.binder.context.statement.UnknownSQLStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.junit.jupiter.api.Test; -import java.util.LinkedList; -import java.util.List; - import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -35,24 +31,28 @@ import static org.mockito.Mockito.when; class ShardingDistinctProjectionPrefixTokenGeneratorTest { + private final ShardingDistinctProjectionPrefixTokenGenerator generator = new ShardingDistinctProjectionPrefixTokenGenerator(); + + @Test + void assertIsNotGenerateSQLTokenWithNotSelectStatementContext() { + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); + } + @Test - void assertIsGenerateSQLToken() { - ShardingDistinctProjectionPrefixTokenGenerator generator = new ShardingDistinctProjectionPrefixTokenGenerator(); - assertFalse(generator.isGenerateSQLToken(mock(UnknownSQLStatementContext.class))); + void assertIsNotGenerateSQLTokenWithEmptyAggregationDistinctProjection() { SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - List<AggregationDistinctProjection> aggregationDistinctProjections = new LinkedList<>(); - when(selectStatementContext.getProjectionsContext().getAggregationDistinctProjections()).thenReturn(aggregationDistinctProjections); + when(selectStatementContext.getProjectionsContext().getAggregationDistinctProjections().isEmpty()).thenReturn(true); assertFalse(generator.isGenerateSQLToken(selectStatementContext)); - aggregationDistinctProjections.add(mock(AggregationDistinctProjection.class)); + } + + @Test + void assertIsGenerateSQLTokenWithAggregationDistinctProjections() { + SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); assertTrue(generator.isGenerateSQLToken(selectStatementContext)); } @Test void assertGenerateSQLToken() { - SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - final int testStartIndex = 1; - when(selectStatementContext.getProjectionsContext().getStartIndex()).thenReturn(testStartIndex); - ShardingDistinctProjectionPrefixTokenGenerator generator = new ShardingDistinctProjectionPrefixTokenGenerator(); - assertThat(generator.generateSQLToken(selectStatementContext).toString(), is("DISTINCT ")); + assertThat(generator.generateSQLToken(mock(SelectStatementContext.class, RETURNS_DEEP_STUBS)).toString(), is("DISTINCT ")); } } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingIndexTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingIndexTokenGeneratorTest.java index c929376c821..d517be835d6 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingIndexTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingIndexTokenGeneratorTest.java @@ -47,18 +47,17 @@ import static org.mockito.Mockito.when; class ShardingIndexTokenGeneratorTest { + private final ShardingIndexTokenGenerator generator = new ShardingIndexTokenGenerator(mock(ShardingRule.class)); + @Test void assertIsNotGenerateSQLTokenWithNotIndexAvailable() { - SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class); - ShardingIndexTokenGenerator generator = new ShardingIndexTokenGenerator(mock(ShardingRule.class)); - assertFalse(generator.isGenerateSQLToken(sqlStatementContext)); + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); } @Test void assertIsNotGenerateSQLTokenWithEmptyIndex() { AlterIndexStatementContext sqlStatementContext = mock(AlterIndexStatementContext.class, RETURNS_DEEP_STUBS); when(sqlStatementContext.getIndexes().isEmpty()).thenReturn(true); - ShardingIndexTokenGenerator generator = new ShardingIndexTokenGenerator(mock(ShardingRule.class)); assertFalse(generator.isGenerateSQLToken(sqlStatementContext)); } @@ -66,13 +65,11 @@ class ShardingIndexTokenGeneratorTest { void assertIsGenerateSQLToken() { AlterIndexStatementContext sqlStatementContext = mock(AlterIndexStatementContext.class, RETURNS_DEEP_STUBS); when(sqlStatementContext.getDatabaseType()).thenReturn(TypedSPILoader.getService(DatabaseType.class, "PostgreSQL")); - ShardingIndexTokenGenerator generator = new ShardingIndexTokenGenerator(mock(ShardingRule.class)); assertTrue(generator.isGenerateSQLToken(sqlStatementContext)); } @Test void assertGenerateSQLTokensWithNotIndexAvailable() { - ShardingIndexTokenGenerator generator = new ShardingIndexTokenGenerator(mock(ShardingRule.class)); Collection<SQLToken> actual = generator.generateSQLTokens(mock(SQLStatementContext.class)); assertTrue(actual.isEmpty()); } @@ -82,7 +79,6 @@ class ShardingIndexTokenGeneratorTest { IndexSegment indexSegment = new IndexSegment(1, 3, new IndexNameSegment(1, 3, mock(IdentifierValue.class))); indexSegment.setOwner(new OwnerSegment(0, 0, new IdentifierValue("foo_schema"))); AlterIndexStatementContext sqlStatementContext = mockAlterIndexStatementContext(indexSegment); - ShardingIndexTokenGenerator generator = new ShardingIndexTokenGenerator(mock(ShardingRule.class)); ShardingSphereSchema schema = mock(ShardingSphereSchema.class); generator.setSchemas(Collections.singletonMap("foo_schema", schema)); Collection<SQLToken> actual = generator.generateSQLTokens(sqlStatementContext); @@ -93,7 +89,6 @@ class ShardingIndexTokenGeneratorTest { void assertGenerateSQLTokensWithoutSchemaOwner() throws ReflectiveOperationException { IndexSegment indexSegment = new IndexSegment(1, 3, new IndexNameSegment(1, 3, mock(IdentifierValue.class))); AlterIndexStatementContext sqlStatementContext = mockAlterIndexStatementContext(indexSegment); - ShardingIndexTokenGenerator generator = new ShardingIndexTokenGenerator(mock(ShardingRule.class)); ShardingSphereSchema schema = mock(ShardingSphereSchema.class); generator.setDefaultSchema(schema); Collection<SQLToken> actual = generator.generateSQLTokens(sqlStatementContext); diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingInsertValuesTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingInsertValuesTokenGeneratorTest.java index 29f09cdfc42..cc99c797419 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingInsertValuesTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingInsertValuesTokenGeneratorTest.java @@ -40,9 +40,10 @@ import static org.mockito.Mockito.when; class ShardingInsertValuesTokenGeneratorTest { + private final ShardingInsertValuesTokenGenerator generator = new ShardingInsertValuesTokenGenerator(); + @Test void assertIsNotGenerateSQLTokenWithNotInsertStatementContext() { - ShardingInsertValuesTokenGenerator generator = new ShardingInsertValuesTokenGenerator(); assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); } @@ -50,19 +51,16 @@ class ShardingInsertValuesTokenGeneratorTest { void assertIsNotGenerateSQLTokenWithEmptyInsertValues() { InsertStatementContext insertStatementContext = mock(InsertStatementContext.class, RETURNS_DEEP_STUBS); when(insertStatementContext.getSqlStatement().getValues().isEmpty()).thenReturn(true); - ShardingInsertValuesTokenGenerator generator = new ShardingInsertValuesTokenGenerator(); assertFalse(generator.isGenerateSQLToken(insertStatementContext)); } @Test void assertIsGenerateSQLToken() { - ShardingInsertValuesTokenGenerator generator = new ShardingInsertValuesTokenGenerator(); assertTrue(generator.isGenerateSQLToken(mock(InsertStatementContext.class, RETURNS_DEEP_STUBS))); } @Test void assertGenerateSQLTokenWithNullRouteContext() { - ShardingInsertValuesTokenGenerator generator = new ShardingInsertValuesTokenGenerator(); InsertValuesToken insertValuesToken = generator.generateSQLToken(mockInsertStatementContext()); assertThat(insertValuesToken.getInsertValues().size(), is(1)); assertTrue(insertValuesToken.getInsertValues().get(0).getValues().isEmpty()); @@ -70,7 +68,6 @@ class ShardingInsertValuesTokenGeneratorTest { @Test void assertGenerateSQLTokenWithEmptyDataNode() { - ShardingInsertValuesTokenGenerator generator = new ShardingInsertValuesTokenGenerator(); generator.setRouteContext(new RouteContext()); InsertValuesToken actual = generator.generateSQLToken(mockInsertStatementContext()); assertThat(actual.getInsertValues().size(), is(1)); @@ -79,7 +76,6 @@ class ShardingInsertValuesTokenGeneratorTest { @Test void assertGenerateSQLTokenWithDataNodes() { - ShardingInsertValuesTokenGenerator generator = new ShardingInsertValuesTokenGenerator(); RouteContext routeContext = new RouteContext(); routeContext.getOriginalDataNodes().add(Collections.singleton(new DataNode("foo_ds", "foo_tbl"))); generator.setRouteContext(routeContext); diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingOffsetTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingOffsetTokenGeneratorTest.java index 759a38a5572..6d3cfb38b2b 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingOffsetTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingOffsetTokenGeneratorTest.java @@ -37,21 +37,20 @@ import static org.mockito.Mockito.when; class ShardingOffsetTokenGeneratorTest { + private final ShardingOffsetTokenGenerator generator = new ShardingOffsetTokenGenerator(); + @Test void assertIsNotGenerateSQLTokenWithNotSelectStatementContext() { - ShardingOffsetTokenGenerator generator = new ShardingOffsetTokenGenerator(); assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); } @Test void assertIsNotGenerateSQLTokenWithoutOffsetSegment() { - ShardingOffsetTokenGenerator generator = new ShardingOffsetTokenGenerator(); assertFalse(generator.isGenerateSQLToken(mock(SelectStatementContext.class, RETURNS_DEEP_STUBS))); } @Test void assertIsNotGenerateSQLTokenWithParameterMarkerPaginationValueSegment() { - ShardingOffsetTokenGenerator generator = new ShardingOffsetTokenGenerator(); SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); when(sqlStatementContext.getPaginationContext().getOffsetSegment()).thenReturn(Optional.of(mock(ParameterMarkerPaginationValueSegment.class))); assertFalse(generator.isGenerateSQLToken(sqlStatementContext)); @@ -59,7 +58,6 @@ class ShardingOffsetTokenGeneratorTest { @Test void assertIsGenerateSQLTokenWithNumberLiteralPaginationValueSegment() { - ShardingOffsetTokenGenerator generator = new ShardingOffsetTokenGenerator(); SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); when(sqlStatementContext.getPaginationContext().getOffsetSegment()).thenReturn(Optional.of(mock(NumberLiteralPaginationValueSegment.class))); assertTrue(generator.isGenerateSQLToken(sqlStatementContext)); @@ -67,7 +65,6 @@ class ShardingOffsetTokenGeneratorTest { @Test void assertGenerateSQLToken() { - ShardingOffsetTokenGenerator generator = new ShardingOffsetTokenGenerator(); assertThat(generator.generateSQLToken(mockSelectStatementContext()).toString(), is("2")); } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingOrderByTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingOrderByTokenGeneratorTest.java index fc27eb43947..765fcc4bf6c 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingOrderByTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingOrderByTokenGeneratorTest.java @@ -18,15 +18,18 @@ package org.apache.shardingsphere.sharding.rewrite.token.generator.impl; import org.apache.shardingsphere.infra.binder.context.segment.select.orderby.OrderByItem; -import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.sharding.rewrite.token.pojo.OrderByToken; import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.GroupBySegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.WindowSegment; -import org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLSelectStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -34,6 +37,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Optional; import static org.hamcrest.CoreMatchers.is; @@ -53,39 +57,101 @@ class ShardingOrderByTokenGeneratorTest { private static final int TEST_OTHER_CLASS_ORDER_BY_ITEM_INDEX = 5; + private final ShardingOrderByTokenGenerator generator = new ShardingOrderByTokenGenerator(); + @Mock private OrderDirection orderDirection; @Test - void assertIsGenerateSQLToken() { - ShardingOrderByTokenGenerator generator = new ShardingOrderByTokenGenerator(); - assertFalse(generator.isGenerateSQLToken(mock(InsertStatementContext.class))); + void assertIsNotGenerateSQLTokenWithNotSelectStatementContext() { + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); + } + + @Test + void assertIsNotGenerateSQLTokenWithNotGeneratedOrderByContext() { + assertFalse(generator.isGenerateSQLToken(mock(SelectStatementContext.class, RETURNS_DEEP_STUBS))); + } + + @Test + void assertIsGenerateSQLTokenWithGeneratedOrderByContext() { SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(selectStatementContext.getOrderByContext().isGenerated()).thenReturn(Boolean.FALSE); - assertFalse(generator.isGenerateSQLToken(selectStatementContext)); - when(selectStatementContext.getOrderByContext().isGenerated()).thenReturn(Boolean.TRUE); + when(selectStatementContext.getOrderByContext().isGenerated()).thenReturn(true); assertTrue(generator.isGenerateSQLToken(selectStatementContext)); } @Test - void assertGenerateSQLToken() { - WindowSegment windowSegment = mock(WindowSegment.class); - when(windowSegment.getStopIndex()).thenReturn(2); - MySQLSelectStatement selectStatement = mock(MySQLSelectStatement.class); - when(selectStatement.getWindow()).thenReturn(Optional.of(windowSegment)); - SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(selectStatementContext.getSqlStatement()).thenReturn(selectStatement); - Collection<OrderByItem> orderByItems = getOrderByItems(); - when(selectStatementContext.getOrderByContext().getItems()).thenReturn(orderByItems); - ShardingOrderByTokenGenerator generator = new ShardingOrderByTokenGenerator(); + void assertGenerateSQLTokenWithWindow() { + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getWindow()).thenReturn(Optional.of(new WindowSegment(0, 10))); + SelectStatementContext selectStatementContext = mockSelectStatementContext(selectStatement); + OrderByToken actual = generator.generateSQLToken(selectStatementContext); + assertThat(actual.getColumnLabels().get(0), is(TEST_COLUMN_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); + assertThat(actual.getColumnLabels().get(1), is(TEST_EXPRESSION_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); + assertThat(actual.getColumnLabels().get(2), is(String.valueOf(TEST_OTHER_CLASS_ORDER_BY_ITEM_INDEX))); + assertThat(actual.getOrderDirections().get(0), is(orderDirection)); + assertThat(actual.getStopIndex(), is(11)); + } + + @Test + void assertGenerateSQLTokenWithHaving() { + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getHaving()).thenReturn(Optional.of(new HavingSegment(0, 10, mock()))); + SelectStatementContext selectStatementContext = mockSelectStatementContext(selectStatement); + OrderByToken actual = generator.generateSQLToken(selectStatementContext); + assertThat(actual.getColumnLabels().get(0), is(TEST_COLUMN_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); + assertThat(actual.getColumnLabels().get(1), is(TEST_EXPRESSION_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); + assertThat(actual.getColumnLabels().get(2), is(String.valueOf(TEST_OTHER_CLASS_ORDER_BY_ITEM_INDEX))); + assertThat(actual.getOrderDirections().get(0), is(orderDirection)); + assertThat(actual.getStopIndex(), is(11)); + } + + @Test + void assertGenerateSQLTokenWithGroupBy() { + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getGroupBy()).thenReturn(Optional.of(new GroupBySegment(0, 10, Collections.emptyList()))); + SelectStatementContext selectStatementContext = mockSelectStatementContext(selectStatement); + OrderByToken actual = generator.generateSQLToken(selectStatementContext); + assertThat(actual.getColumnLabels().get(0), is(TEST_COLUMN_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); + assertThat(actual.getColumnLabels().get(1), is(TEST_EXPRESSION_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); + assertThat(actual.getColumnLabels().get(2), is(String.valueOf(TEST_OTHER_CLASS_ORDER_BY_ITEM_INDEX))); + assertThat(actual.getOrderDirections().get(0), is(orderDirection)); + assertThat(actual.getStopIndex(), is(11)); + } + + @Test + void assertGenerateSQLTokenWithWhere() { + SelectStatement selectStatement = mock(SelectStatement.class); + when(selectStatement.getWhere()).thenReturn(Optional.of(new WhereSegment(0, 10, mock()))); + SelectStatementContext selectStatementContext = mockSelectStatementContext(selectStatement); OrderByToken actual = generator.generateSQLToken(selectStatementContext); assertThat(actual.getColumnLabels().get(0), is(TEST_COLUMN_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); assertThat(actual.getColumnLabels().get(1), is(TEST_EXPRESSION_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); assertThat(actual.getColumnLabels().get(2), is(String.valueOf(TEST_OTHER_CLASS_ORDER_BY_ITEM_INDEX))); assertThat(actual.getOrderDirections().get(0), is(orderDirection)); + assertThat(actual.getStopIndex(), is(11)); + } + + @Test + void assertGenerateSQLTokenWithNothing() { + SelectStatement selectStatement = mock(SelectStatement.class); + SelectStatementContext selectStatementContext = mockSelectStatementContext(selectStatement); + OrderByToken actual = generator.generateSQLToken(selectStatementContext); + assertThat(actual.getColumnLabels().get(0), is(TEST_COLUMN_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); + assertThat(actual.getColumnLabels().get(1), is(TEST_EXPRESSION_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL)); + assertThat(actual.getColumnLabels().get(2), is(String.valueOf(TEST_OTHER_CLASS_ORDER_BY_ITEM_INDEX))); + assertThat(actual.getOrderDirections().get(0), is(orderDirection)); + assertThat(actual.getStopIndex(), is(1)); + } + + private SelectStatementContext mockSelectStatementContext(final SelectStatement selectStatement) { + SelectStatementContext result = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); + when(result.getSqlStatement()).thenReturn(selectStatement); + Collection<OrderByItem> orderByItems = createOrderByItems(); + when(result.getOrderByContext().getItems()).thenReturn(orderByItems); + return result; } - private Collection<OrderByItem> getOrderByItems() { + private Collection<OrderByItem> createOrderByItems() { ColumnOrderByItemSegment columnOrderByItemSegment = mock(ColumnOrderByItemSegment.class); when(columnOrderByItemSegment.getText()).thenReturn(TEST_COLUMN_ORDER_BY_ITEM_SEGMENT_COLUMN_LABEL); when(columnOrderByItemSegment.getOrderDirection()).thenReturn(orderDirection); diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingProjectionsTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingProjectionsTokenGeneratorTest.java index a17a4b1c56e..203b0828d15 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingProjectionsTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingProjectionsTokenGeneratorTest.java @@ -21,139 +21,120 @@ import org.apache.shardingsphere.infra.binder.context.segment.select.projection. import org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.AggregationDistinctProjection; import org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.AggregationProjection; import org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.DerivedProjection; -import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; +import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.route.context.RouteMapper; import org.apache.shardingsphere.infra.route.context.RouteUnit; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.sharding.rewrite.token.pojo.ProjectionsToken; +import org.apache.shardingsphere.sql.parser.statement.core.enums.AggregationType; import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment; +import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; -import org.apache.shardingsphere.sql.parser.statement.mysql.dml.MySQLSelectStatement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Optional; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) class ShardingProjectionsTokenGeneratorTest { - private static final String TEST_AGGREGATION_DISTINCT_PROJECTION_DISTINCT_INNER_EXPRESSION = "TEST_AGGREGATION_DISTINCT_PROJECTION_DISTINCT_INNER_EXPRESSION"; + private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "FIXTURE"); - private static final String TEST_AGGREGATION_DISTINCT_PROJECTION_ALIAS = "TEST_AGGREGATION_DISTINCT_PROJECTION_ALIAS"; - - private static final String TEST_DERIVED_PROJECTION_ALIAS = "TEST_DERIVED_PROJECTION_ALIAS"; - - private static final String TEST_LOGIC_TABLE_NAME = "TEST_LOGIC_TABLE_NAME"; - - private static final String TEST_ACTUAL_TABLE_NAME_WRAPPED = "TEST_ACTUAL_TABLE_NAME_WRAPPED"; - - private static final String TEST_OTHER_DERIVED_PROJECTION_ALIAS = "TEST_OTHER_DERIVED_PROJECTION_ALIAS"; - - private static final String TEST_OTHER_DERIVED_PROJECTION_EXPRESSION = "TEST_OTHER_DERIVED_PROJECTION_EXPRESSION"; - - @Mock private RouteUnit routeUnit; + private ShardingProjectionsTokenGenerator generator; + @BeforeEach void setup() { - RouteMapper routeMapper = mock(RouteMapper.class); - when(routeMapper.getLogicName()).thenReturn(TEST_LOGIC_TABLE_NAME); - when(routeMapper.getActualName()).thenReturn("TEST_ACTUAL_TABLE_NAME"); - when(routeUnit.getTableMappers()).thenReturn(Collections.singleton(routeMapper)); + routeUnit = new RouteUnit(mock(RouteMapper.class), Collections.singleton(new RouteMapper("foo_tbl", "foo_tbl_0"))); + generator = createProjectionsTokenGenerator(); + } + + private ShardingProjectionsTokenGenerator createProjectionsTokenGenerator() { + RouteContext routeContext = new RouteContext(); + routeContext.getRouteUnits().add(routeUnit); + ShardingProjectionsTokenGenerator result = new ShardingProjectionsTokenGenerator(); + result.setRouteContext(routeContext); + return result; } @Test - void assertIsGenerateInsertToken() { - assertFalse(getProjectionsTokenGenerator().isGenerateSQLToken(mock(InsertStatementContext.class))); + void assertIsNotGenerateSQLTokenWithNoSelectStatementContext() { + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); } @Test - void assertIsNotGenerateSelectToken() { - assertFalse(getProjectionsTokenGenerator().isGenerateSQLToken(mock(SelectStatementContext.class, RETURNS_DEEP_STUBS))); + void assertIsNotGenerateSQLTokenWithNotContainsDerivedProjection() { + SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); + when(sqlStatementContext.getProjectionsContext().getProjections()).thenReturn(Collections.singleton(mock())); + assertFalse(generator.isGenerateSQLToken(sqlStatementContext)); } @Test - void assertIsGenerateSelectToken() { - SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - AggregationProjection aggregationProjection = getAggregationProjection(); - when(selectStatementContext.getProjectionsContext().getProjections()).thenReturn(Collections.singleton(aggregationProjection)); - assertTrue(getProjectionsTokenGenerator().isGenerateSQLToken(selectStatementContext)); + void assertIsGenerateSQLTokenWithDerivedProjections() { + SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); + when(sqlStatementContext.getProjectionsContext().getProjections()).thenReturn(Arrays.asList(mock(AggregationProjection.class), mock(DerivedProjection.class))); + assertTrue(generator.isGenerateSQLToken(sqlStatementContext)); + } + + @Test + void assertIsGenerateSQLTokenWithDerivedAggregationProjections() { + SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); + AggregationProjection aggregationProjection = mock(AggregationProjection.class, RETURNS_DEEP_STUBS); + when(sqlStatementContext.getProjectionsContext().getProjections()).thenReturn(Collections.singleton(aggregationProjection)); + assertTrue(generator.isGenerateSQLToken(sqlStatementContext)); } @Test void assertGenerateSQLToken() { SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(selectStatementContext.getDatabaseType()).thenReturn(TypedSPILoader.getService(DatabaseType.class, "FIXTURE")); - Collection<Projection> projections = Arrays.asList(getAggregationProjection(), getDerivedProjection(), getOtherDerivedProjection()); + when(selectStatementContext.getDatabaseType()).thenReturn(databaseType); + Collection<Projection> projections = Arrays.asList( + createAggregationProjection(), createDerivedProjectionWithOwner(), createDerivedProjectionWithoutOwner(), createOtherDerivedProjection(), mock()); when(selectStatementContext.getProjectionsContext().getProjections()).thenReturn(projections); when(selectStatementContext.getProjectionsContext().getStopIndex()).thenReturn(2); - when(selectStatementContext.getSqlStatement()).thenReturn(new MySQLSelectStatement()); - ShardingProjectionsTokenGenerator generator = getProjectionsTokenGenerator(); + when(selectStatementContext.getSqlStatement()).thenReturn(mock(SelectStatement.class)); ProjectionsToken actual = generator.generateSQLToken(selectStatementContext); - assertThat(actual.toString(routeUnit), is(", " + TEST_AGGREGATION_DISTINCT_PROJECTION_DISTINCT_INNER_EXPRESSION + " AS " + TEST_AGGREGATION_DISTINCT_PROJECTION_ALIAS + " " - + ", " + TEST_ACTUAL_TABLE_NAME_WRAPPED + ".null" + " AS " + TEST_DERIVED_PROJECTION_ALIAS + " " - + ", " + TEST_OTHER_DERIVED_PROJECTION_EXPRESSION + " AS " + TEST_OTHER_DERIVED_PROJECTION_ALIAS + " ")); + assertThat(actual.toString(routeUnit), + is(", foo_agg_expr AS foo_agg_alias , foo_tbl_0.foo_derived_col AS foo_derived_alias , bar_derived_col AS bar_derived_alias , other_expr AS other_alias ")); } - private ShardingProjectionsTokenGenerator getProjectionsTokenGenerator() { - RouteContext routeContext = mock(RouteContext.class); - when(routeContext.getRouteUnits()).thenReturn(Collections.singleton(routeUnit)); - ShardingProjectionsTokenGenerator result = new ShardingProjectionsTokenGenerator(); - result.setRouteContext(routeContext); + private AggregationProjection createAggregationProjection() { + AggregationDistinctProjection derivedProjection = new AggregationDistinctProjection(0, 0, AggregationType.COUNT, "", + new IdentifierValue("foo_agg_alias"), "foo_agg_expr", databaseType); + AggregationProjection result = new AggregationDistinctProjection(0, 0, AggregationType.COUNT, "", null, "", databaseType); + result.getDerivedAggregationProjections().add(derivedProjection); return result; } - private AggregationProjection getAggregationProjection() { - AggregationDistinctProjection derivedAggregationDistinctProjection = mock(AggregationDistinctProjection.class); - when(derivedAggregationDistinctProjection.getDistinctInnerExpression()).thenReturn(TEST_AGGREGATION_DISTINCT_PROJECTION_DISTINCT_INNER_EXPRESSION); - when(derivedAggregationDistinctProjection.getAlias()).thenReturn(Optional.of(new IdentifierValue(TEST_AGGREGATION_DISTINCT_PROJECTION_ALIAS))); - AggregationProjection result = mock(AggregationProjection.class); - when(result.getDerivedAggregationProjections()).thenReturn(Collections.singletonList(derivedAggregationDistinctProjection)); - return result; + private DerivedProjection createDerivedProjectionWithOwner() { + ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("foo_derived_col")); + columnSegment.setOwner(new OwnerSegment(0, 0, new IdentifierValue("foo_tbl"))); + return new DerivedProjection("", new IdentifierValue("foo_derived_alias"), new ColumnOrderByItemSegment(columnSegment, OrderDirection.DESC, NullsOrderType.FIRST)); } - private DerivedProjection getDerivedProjection() { - OwnerSegment ownerSegment = mock(OwnerSegment.class, RETURNS_DEEP_STUBS); - when(ownerSegment.getIdentifier().getValue()).thenReturn(TEST_LOGIC_TABLE_NAME); - when(ownerSegment.getIdentifier().getQuoteCharacter().wrap(anyString())).thenReturn(TEST_ACTUAL_TABLE_NAME_WRAPPED); - ColumnOrderByItemSegment oldColumnOrderByItemSegment = mock(ColumnOrderByItemSegment.class, RETURNS_DEEP_STUBS); - when(oldColumnOrderByItemSegment.getColumn().getOwner()).thenReturn(Optional.of(ownerSegment)); - when(oldColumnOrderByItemSegment.getOrderDirection()).thenReturn(mock(OrderDirection.class)); - when(oldColumnOrderByItemSegment.getColumn().getIdentifier()).thenReturn(mock(IdentifierValue.class)); - DerivedProjection result = mock(DerivedProjection.class); - when(result.getAlias()).thenReturn(Optional.of(new IdentifierValue(TEST_DERIVED_PROJECTION_ALIAS))); - when(result.getDerivedProjectionSegment()).thenReturn(oldColumnOrderByItemSegment); - return result; + private DerivedProjection createDerivedProjectionWithoutOwner() { + ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("bar_derived_col")); + return new DerivedProjection("", new IdentifierValue("bar_derived_alias"), new ColumnOrderByItemSegment(columnSegment, OrderDirection.DESC, NullsOrderType.FIRST)); } - private DerivedProjection getOtherDerivedProjection() { - DerivedProjection result = mock(DerivedProjection.class); - when(result.getDerivedProjectionSegment()).thenReturn(null); - when(result.getAlias()).thenReturn(Optional.of(new IdentifierValue(TEST_OTHER_DERIVED_PROJECTION_ALIAS))); - when(result.getExpression()).thenReturn(TEST_OTHER_DERIVED_PROJECTION_EXPRESSION); - return result; + private DerivedProjection createOtherDerivedProjection() { + return new DerivedProjection("other_expr", new IdentifierValue("other_alias"), mock()); } } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRemoveTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRemoveTokenGeneratorTest.java index a51a44ad2b3..906e1c84c5f 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRemoveTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRemoveTokenGeneratorTest.java @@ -17,10 +17,11 @@ package org.apache.shardingsphere.sharding.rewrite.token.generator.impl; -import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.database.core.DefaultDatabase; +import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType; import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData; @@ -28,7 +29,6 @@ import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken; import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.generic.RemoveToken; import org.apache.shardingsphere.sql.parser.statement.core.enums.AggregationType; -import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType; import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationDistinctProjectionSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment; @@ -54,32 +54,33 @@ import static org.mockito.Mockito.when; class ShardingRemoveTokenGeneratorTest { + private final ShardingRemoveTokenGenerator generator = new ShardingRemoveTokenGenerator(); + @Test - void assertIsGenerateSQLTokenWithNonSelectStatement() { - assertFalse(new ShardingRemoveTokenGenerator().isGenerateSQLToken(mock(InsertStatementContext.class))); + void assertIsGenerateSQLTokenWithNotSelectStatement() { + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); } @Test - void assertIsGenerateSQLTokenWithEmptyAggregationDistinctProjections() { + void assertIsGenerateSQLTokenWithEmptyAggregationDistinctProjection() { SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); when(selectStatementContext.getProjectionsContext().getAggregationDistinctProjections().isEmpty()).thenReturn(true); - assertFalse(new ShardingRemoveTokenGenerator().isGenerateSQLToken(selectStatementContext)); + assertFalse(generator.isGenerateSQLToken(selectStatementContext)); } @Test - void assertIsGenerateSQLTokenWithNonEmptyAggregationDistinctProjections() { - SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - assertTrue(new ShardingRemoveTokenGenerator().isGenerateSQLToken(selectStatementContext)); + void assertIsGenerateSQLTokenWithAggregationDistinctProjections() { + assertTrue(generator.isGenerateSQLToken(mock(SelectStatementContext.class, RETURNS_DEEP_STUBS))); } @Test void assertGenerateSQLTokens() { - Collection<? extends SQLToken> sqlTokens = new ShardingRemoveTokenGenerator().generateSQLTokens(createUpdatesStatementContext()); - assertThat(sqlTokens.size(), is(1)); - assertThat(sqlTokens.iterator().next(), instanceOf(RemoveToken.class)); + Collection<? extends SQLToken> actual = generator.generateSQLTokens(createSelectStatementContext()); + assertThat(actual.size(), is(1)); + assertThat(actual.iterator().next(), instanceOf(RemoveToken.class)); } - private SelectStatementContext createUpdatesStatementContext() { + private SelectStatementContext createSelectStatementContext() { MySQLSelectStatement selectStatement = new MySQLSelectStatement(); selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_user")))); selectStatement.setGroupBy(new GroupBySegment(0, 0, Collections.singletonList(new IndexOrderByItemSegment(0, 0, 1, OrderDirection.ASC, NullsOrderType.FIRST)))); diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRowCountTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRowCountTokenGeneratorTest.java index 5a6b222df4c..687f01bcde0 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRowCountTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingRowCountTokenGeneratorTest.java @@ -18,18 +18,19 @@ package org.apache.shardingsphere.sharding.rewrite.token.generator.impl; import org.apache.shardingsphere.infra.binder.context.segment.select.pagination.PaginationContext; -import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.sharding.rewrite.token.pojo.RowCountToken; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.NumberLiteralPaginationValueSegment; +import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ParameterMarkerPaginationValueSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.NumberLiteralLimitValueSegment; import org.junit.jupiter.api.Test; import java.util.Optional; import static org.hamcrest.CoreMatchers.is; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; @@ -37,35 +38,44 @@ import static org.mockito.Mockito.when; class ShardingRowCountTokenGeneratorTest { + private final ShardingRowCountTokenGenerator generator = new ShardingRowCountTokenGenerator(); + + @Test + void assertIsNotGenerateSQLTokenWithNotSelectStatementContext() { + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); + } + + @Test + void assertIsNotGenerateSQLTokenWithoutRowCountSegment() { + assertFalse(generator.isGenerateSQLToken(mock(SelectStatementContext.class, RETURNS_DEEP_STUBS))); + } + @Test - void assertIsGenerateSQLToken() { - InsertStatementContext insertStatementContext = mock(InsertStatementContext.class); - ShardingRowCountTokenGenerator shardingRowCountTokenGenerator = new ShardingRowCountTokenGenerator(); - assertFalse(shardingRowCountTokenGenerator.isGenerateSQLToken(insertStatementContext)); + void assertIsNotGenerateSQLTokenWithNotNumberLiteralPaginationValueSegment() { SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(selectStatementContext.getPaginationContext().getRowCountSegment().isPresent()).thenReturn(Boolean.FALSE); - NumberLiteralPaginationValueSegment numberLiteralPaginationValueSegment = mock(NumberLiteralPaginationValueSegment.class); - assertFalse(shardingRowCountTokenGenerator.isGenerateSQLToken(selectStatementContext)); - when(selectStatementContext.getPaginationContext().getRowCountSegment()).thenReturn(Optional.of(numberLiteralPaginationValueSegment)); - assertTrue(shardingRowCountTokenGenerator.isGenerateSQLToken(selectStatementContext)); + when(selectStatementContext.getPaginationContext().getRowCountSegment()).thenReturn(Optional.of(mock(ParameterMarkerPaginationValueSegment.class))); + assertFalse(generator.isGenerateSQLToken(selectStatementContext)); } @Test - void assertGenerateSQLToken() { - final long testOffsetSegmentValue = 12L; - NumberLiteralLimitValueSegment offsetSegment = new NumberLiteralLimitValueSegment(1, 2, testOffsetSegmentValue); - final long testRowCountSegmentValue = 8L; - NumberLiteralLimitValueSegment rowCountSegment = new NumberLiteralLimitValueSegment(4, 5, testRowCountSegmentValue); - PaginationContext paginationContext = new PaginationContext(offsetSegment, rowCountSegment, null); + void assertIsGenerateSQLTokenWithNumberLiteralPaginationValueSegment() { SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - when(selectStatementContext.getPaginationContext()).thenReturn(paginationContext); - when(selectStatementContext.getGroupByContext().getItems().isEmpty()).thenReturn(Boolean.FALSE); - when(selectStatementContext.isSameGroupByAndOrderByItems()).thenReturn(Boolean.FALSE); - ShardingRowCountTokenGenerator shardingRowCountTokenGenerator = new ShardingRowCountTokenGenerator(); - RowCountToken rowCountToken = shardingRowCountTokenGenerator.generateSQLToken(selectStatementContext); - assertThat(rowCountToken.toString(), is(String.valueOf(Integer.MAX_VALUE))); - when(selectStatementContext.isSameGroupByAndOrderByItems()).thenReturn(Boolean.TRUE); - rowCountToken = shardingRowCountTokenGenerator.generateSQLToken(selectStatementContext); - assertThat(rowCountToken.toString(), is(String.valueOf(testOffsetSegmentValue + testRowCountSegmentValue))); + when(selectStatementContext.getPaginationContext().getRowCountSegment()).thenReturn(Optional.of(mock(NumberLiteralPaginationValueSegment.class))); + assertTrue(generator.isGenerateSQLToken(selectStatementContext)); + } + + @Test + void assertGenerateSQLToken() { + RowCountToken actual = generator.generateSQLToken(mockSelectStatementContext()); + assertThat(actual.toString(), is(String.valueOf(20L))); + } + + private SelectStatementContext mockSelectStatementContext() { + NumberLiteralLimitValueSegment offsetSegment = new NumberLiteralLimitValueSegment(0, 0, 12L); + NumberLiteralLimitValueSegment rowCountSegment = new NumberLiteralLimitValueSegment(0, 0, 8L); + SelectStatementContext result = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); + when(result.getPaginationContext()).thenReturn(new PaginationContext(offsetSegment, rowCountSegment, null)); + when(result.isSameGroupByAndOrderByItems()).thenReturn(true); + return result; } } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingTableTokenGeneratorTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingTableTokenGeneratorTest.java index f9820949a94..e80460e7042 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingTableTokenGeneratorTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rewrite/token/generator/impl/ShardingTableTokenGeneratorTest.java @@ -17,73 +17,92 @@ package org.apache.shardingsphere.sharding.rewrite.token.generator.impl; +import org.apache.shardingsphere.infra.binder.context.aware.CursorAware; import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; -import org.apache.shardingsphere.infra.binder.context.statement.UnknownSQLStatementContext; -import org.apache.shardingsphere.infra.binder.context.statement.ddl.CreateTableStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext; import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.sharding.rewrite.token.pojo.ShardingTableToken; import org.apache.shardingsphere.sharding.rule.ShardingRule; -import org.apache.shardingsphere.sharding.rule.ShardingTable; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment; import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Optional; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; +@ExtendWith(MockitoExtension.class) class ShardingTableTokenGeneratorTest { + @Mock + private ShardingRule rule; + + private ShardingTableTokenGenerator generator; + + @BeforeEach + void setUp() { + generator = new ShardingTableTokenGenerator(rule); + } + + @Test + void assertIsNotGenerateSQLTokenWithCursorAware() { + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class, withSettings().extraInterfaces(CursorAware.class)))); + } + + @Test + void assertIsNotGenerateSQLTokenWithNotTableAvailable() { + generator.setRouteContext(new RouteContext()); + assertFalse(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); + } + @Test - void assertIsGenerateSQLTokenWhenConfigAllBindingTables() { - ShardingRule shardingRule = mock(ShardingRule.class); - Collection<String> logicTableNames = Arrays.asList("t_order", "t_order_item"); - when(shardingRule.getShardingLogicTableNames(logicTableNames)).thenReturn(logicTableNames); - when(shardingRule.isAllBindingTables(logicTableNames)).thenReturn(true); + void assertIsGenerateSQLTokenWithAllBindingTables() { + Collection<String> logicTableNames = Arrays.asList("foo_tbl", "bar_tbl"); + when(rule.getShardingLogicTableNames(logicTableNames)).thenReturn(logicTableNames); + when(rule.isAllBindingTables(logicTableNames)).thenReturn(true); SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); when(sqlStatementContext.getTablesContext().getTableNames()).thenReturn(logicTableNames); - assertTrue(new ShardingTableTokenGenerator(shardingRule).isGenerateSQLToken(sqlStatementContext)); + assertTrue(generator.isGenerateSQLToken(sqlStatementContext)); } @Test - void assertIsGenerateSQLTokenWhenContainsTableSharding() { - ShardingTableTokenGenerator generator = new ShardingTableTokenGenerator(mock(ShardingRule.class)); + void assertIsGenerateSQLTokenWithTableSharding() { RouteContext routeContext = mock(RouteContext.class); when(routeContext.containsTableSharding()).thenReturn(true); generator.setRouteContext(routeContext); - SQLStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); - assertTrue(generator.isGenerateSQLToken(sqlStatementContext)); + assertTrue(generator.isGenerateSQLToken(mock(SQLStatementContext.class))); } @Test - void assertGenerateSQLTokenWhenSQLStatementIsTableAvailable() { - ShardingRule shardingRule = mock(ShardingRule.class); - when(shardingRule.findShardingTable(anyString())).thenReturn(Optional.of(mock(ShardingTable.class))); - ShardingTableTokenGenerator generator = new ShardingTableTokenGenerator(shardingRule); - CreateTableStatementContext sqlStatementContext = mock(CreateTableStatementContext.class, RETURNS_DEEP_STUBS); - when(sqlStatementContext.getTablesContext().getSimpleTables()).thenReturn(Collections.singletonList(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))))); - Collection<SQLToken> actual = generator.generateSQLTokens(sqlStatementContext); - assertThat(actual.size(), is(1)); - assertThat(actual.iterator().next(), instanceOf(ShardingTableToken.class)); + void assertGenerateSQLTokenWithNotTableAvailable() { + assertTrue(generator.generateSQLTokens(mock(SQLStatementContext.class)).isEmpty()); } @Test - void assertGenerateSQLTokenWhenSQLStatementIsNotTableAvailable() { - ShardingTableTokenGenerator generator = new ShardingTableTokenGenerator(mock(ShardingRule.class)); - SQLStatementContext sqlStatementContext = mock(UnknownSQLStatementContext.class); - assertThat(generator.generateSQLTokens(sqlStatementContext), is(Collections.emptyList())); + void assertGenerateSQLTokenWithTableAvailable() { + when(rule.findShardingTable("foo_tbl")).thenReturn(Optional.of(mock())); + SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); + when(sqlStatementContext.getTablesContext().getSimpleTables()).thenReturn(Arrays.asList( + new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("foo_tbl"))), + new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("bar_tbl"))))); + Collection<SQLToken> actual = generator.generateSQLTokens(sqlStatementContext); + assertThat(actual.size(), is(1)); + assertThat(actual.iterator().next(), instanceOf(ShardingTableToken.class)); } }