|
21 | 21 | import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; |
22 | 22 | import org.apache.shardingsphere.infra.binder.context.statement.type.dml.InsertStatementContext; |
23 | 23 | import org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext; |
| 24 | +import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; |
| 25 | +import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey; |
24 | 26 | import org.apache.shardingsphere.infra.datanode.DataNode; |
25 | 27 | import org.apache.shardingsphere.infra.hint.HintValueContext; |
| 28 | +import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; |
26 | 29 | import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; |
27 | 30 | import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit; |
28 | 31 | import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; |
|
40 | 43 | import java.util.Arrays; |
41 | 44 | import java.util.Collections; |
42 | 45 | import java.util.Map; |
| 46 | +import java.util.Properties; |
43 | 47 |
|
44 | 48 | import static org.hamcrest.CoreMatchers.is; |
45 | 49 | import static org.hamcrest.MatcherAssert.assertThat; |
@@ -70,11 +74,25 @@ void assertRewriteWithStandardParameterBuilder() { |
70 | 74 | } |
71 | 75 |
|
72 | 76 | private QueryContext mockQueryContext(final SQLStatementContext sqlStatementContext, final String sql) { |
| 77 | + return mockQueryContext(sqlStatementContext, sql, Integer.MAX_VALUE); |
| 78 | + } |
| 79 | + |
| 80 | + private QueryContext mockQueryContext(final SQLStatementContext sqlStatementContext, final String sql, final int maxUnionSizePerDataSource) { |
73 | 81 | QueryContext result = mock(QueryContext.class, RETURNS_DEEP_STUBS); |
74 | 82 | when(result.getSqlStatementContext()).thenReturn(sqlStatementContext); |
75 | 83 | when(result.getSql()).thenReturn(sql); |
76 | 84 | when(result.getParameters()).thenReturn(Collections.singletonList(1)); |
77 | 85 | when(result.getHintValueContext()).thenReturn(new HintValueContext()); |
| 86 | + ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class); |
| 87 | + ConfigurationProperties props = new ConfigurationProperties(createPropsWithMaxUnionSizePerDataSource(maxUnionSizePerDataSource)); |
| 88 | + when(metaData.getProps()).thenReturn(props); |
| 89 | + when(result.getMetaData()).thenReturn(metaData); |
| 90 | + return result; |
| 91 | + } |
| 92 | + |
| 93 | + private Properties createPropsWithMaxUnionSizePerDataSource(final int maxUnionSizePerDataSource) { |
| 94 | + Properties result = new Properties(); |
| 95 | + result.setProperty(ConfigurationPropertyKey.MAX_UNION_SIZE_PER_DATASOURCE.getKey(), String.valueOf(maxUnionSizePerDataSource)); |
78 | 96 | return result; |
79 | 97 | } |
80 | 98 |
|
@@ -207,4 +225,64 @@ private Map<String, StorageUnit> mockStorageUnits(final DatabaseType databaseTyp |
207 | 225 | when(result.getStorageType()).thenReturn(databaseType); |
208 | 226 | return Collections.singletonMap("ds_0", result); |
209 | 227 | } |
| 228 | + |
| 229 | + @Test |
| 230 | + void assertRewriteWithBatchUnionWhenExceedsMaxUnionSizePerDataSource() { |
| 231 | + SelectStatementContext statementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); |
| 232 | + when(statementContext.getOrderByContext().getItems()).thenReturn(Collections.emptyList()); |
| 233 | + when(statementContext.getPaginationContext().isHasPagination()).thenReturn(false); |
| 234 | + DatabaseType databaseType = mock(DatabaseType.class); |
| 235 | + when(statementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType); |
| 236 | + ShardingSphereDatabase database = mockDatabase(databaseType); |
| 237 | + QueryContext queryContext = mockQueryContext(statementContext, "SELECT ?", 2); |
| 238 | + SQLRewriteContext sqlRewriteContext = new SQLRewriteContext(database, queryContext); |
| 239 | + RouteContext routeContext = new RouteContext(); |
| 240 | + for (int i = 0; i < 5; i++) { |
| 241 | + routeContext.getRouteUnits().add(new RouteUnit(new RouteMapper("ds", "ds_0"), Collections.singletonList(new RouteMapper("tbl", "tbl_" + i)))); |
| 242 | + } |
| 243 | + RouteSQLRewriteResult actual = new RouteSQLRewriteEngine( |
| 244 | + new SQLTranslatorRule(new DefaultSQLTranslatorRuleConfigurationBuilder().build()), database, mock(RuleMetaData.class)).rewrite(sqlRewriteContext, routeContext, queryContext); |
| 245 | + assertThat(actual.getSqlRewriteUnits().size(), is(3)); |
| 246 | + } |
| 247 | + |
| 248 | + @Test |
| 249 | + void assertRewriteWithMaxUnionSizePerDataSourceEqualsRouteUnitsCount() { |
| 250 | + SelectStatementContext statementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); |
| 251 | + when(statementContext.getOrderByContext().getItems()).thenReturn(Collections.emptyList()); |
| 252 | + when(statementContext.getPaginationContext().isHasPagination()).thenReturn(false); |
| 253 | + DatabaseType databaseType = mock(DatabaseType.class); |
| 254 | + when(statementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType); |
| 255 | + ShardingSphereDatabase database = mockDatabase(databaseType); |
| 256 | + QueryContext queryContext = mockQueryContext(statementContext, "SELECT ?", 2); |
| 257 | + SQLRewriteContext sqlRewriteContext = new SQLRewriteContext(database, queryContext); |
| 258 | + RouteContext routeContext = new RouteContext(); |
| 259 | + RouteUnit firstRouteUnit = new RouteUnit(new RouteMapper("ds", "ds_0"), Collections.singletonList(new RouteMapper("tbl", "tbl_0"))); |
| 260 | + RouteUnit secondRouteUnit = new RouteUnit(new RouteMapper("ds", "ds_0"), Collections.singletonList(new RouteMapper("tbl", "tbl_1"))); |
| 261 | + routeContext.getRouteUnits().add(firstRouteUnit); |
| 262 | + routeContext.getRouteUnits().add(secondRouteUnit); |
| 263 | + RouteSQLRewriteResult actual = new RouteSQLRewriteEngine( |
| 264 | + new SQLTranslatorRule(new DefaultSQLTranslatorRuleConfigurationBuilder().build()), database, mock(RuleMetaData.class)).rewrite(sqlRewriteContext, routeContext, queryContext); |
| 265 | + assertThat(actual.getSqlRewriteUnits().size(), is(1)); |
| 266 | + assertThat(actual.getSqlRewriteUnits().values().iterator().next().getSql(), is("SELECT ? UNION ALL SELECT ?")); |
| 267 | + } |
| 268 | + |
| 269 | + @Test |
| 270 | + void assertRewriteWithMaxUnionSizePerDataSourceOne() { |
| 271 | + SelectStatementContext statementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS); |
| 272 | + when(statementContext.getOrderByContext().getItems()).thenReturn(Collections.emptyList()); |
| 273 | + when(statementContext.getPaginationContext().isHasPagination()).thenReturn(false); |
| 274 | + DatabaseType databaseType = mock(DatabaseType.class); |
| 275 | + when(statementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType); |
| 276 | + ShardingSphereDatabase database = mockDatabase(databaseType); |
| 277 | + QueryContext queryContext = mockQueryContext(statementContext, "SELECT ?", 1); |
| 278 | + SQLRewriteContext sqlRewriteContext = new SQLRewriteContext(database, queryContext); |
| 279 | + RouteContext routeContext = new RouteContext(); |
| 280 | + RouteUnit firstRouteUnit = new RouteUnit(new RouteMapper("ds", "ds_0"), Collections.singletonList(new RouteMapper("tbl", "tbl_0"))); |
| 281 | + RouteUnit secondRouteUnit = new RouteUnit(new RouteMapper("ds", "ds_0"), Collections.singletonList(new RouteMapper("tbl", "tbl_1"))); |
| 282 | + routeContext.getRouteUnits().add(firstRouteUnit); |
| 283 | + routeContext.getRouteUnits().add(secondRouteUnit); |
| 284 | + RouteSQLRewriteResult actual = new RouteSQLRewriteEngine( |
| 285 | + new SQLTranslatorRule(new DefaultSQLTranslatorRuleConfigurationBuilder().build()), database, mock(RuleMetaData.class)).rewrite(sqlRewriteContext, routeContext, queryContext); |
| 286 | + assertThat(actual.getSqlRewriteUnits().size(), is(2)); |
| 287 | + } |
210 | 288 | } |
0 commit comments