Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.shardingsphere.sharding.rule.ShardingTable;

import java.util.Optional;
import java.util.stream.Collectors;

/**
* Sharding index reviser.
Expand All @@ -39,9 +40,21 @@ public Optional<IndexMetaData> revise(final String tableName, final IndexMetaDat
if (shardingTable.getActualDataNodes().isEmpty()) {
return Optional.empty();
}
String actualTableName = tableName;
String logicIndexName = IndexMetaDataUtils.getGeneratedLogicIndexName(originalMetaData.getName(), actualTableName);
if (!IndexMetaDataUtils.isGeneratedActualIndexNameMatch(originalMetaData.getName(), logicIndexName, actualTableName)) {
String generatedAnonymousIndexName = getGeneratedAnonymousIndexName(originalMetaData);
if (IndexMetaDataUtils.isGeneratedActualIndexNameMatch(originalMetaData.getName(), generatedAnonymousIndexName, actualTableName)) {
logicIndexName = generatedAnonymousIndexName;
}
}
IndexMetaData result = new IndexMetaData(
IndexMetaDataUtils.getLogicIndexName(originalMetaData.getName(), shardingTable.getActualDataNodes().iterator().next().getTableName()), originalMetaData.getColumns());
logicIndexName, originalMetaData.getColumns());
result.setUnique(originalMetaData.isUnique());
return Optional.of(result);
}

private String getGeneratedAnonymousIndexName(final IndexMetaData originalMetaData) {
return originalMetaData.getColumns().stream().map(each -> each + "_").collect(Collectors.joining("", "", "idx"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private String getIndexValue(final RouteUnit routeUnit) {
}
Map<String, String> logicAndActualTables = ShardingTokenUtils.getLogicAndActualTableMap(routeUnit, sqlStatementContext, rule);
String actualTableName = logicTableName.map(logicAndActualTables::get).orElseGet(() -> logicAndActualTables.isEmpty() ? null : logicAndActualTables.values().iterator().next());
return IndexMetaDataUtils.getActualIndexName(identifier.getValue(), actualTableName);
return IndexMetaDataUtils.getActualIndexName(identifier.getValue(), actualTableName, sqlStatementContext.getSqlStatement().getDatabaseType());
}

private Optional<String> findLogicTableNameFromMetaData(final String logicIndexName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@

package org.apache.shardingsphere.sharding.metadata.reviser.index;

import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
import org.apache.shardingsphere.infra.datanode.DataNode;
import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sharding.rule.ShardingTable;
import org.junit.jupiter.api.Test;
Expand All @@ -35,19 +38,49 @@

class ShardingIndexReviserTest {

private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");

@Test
void assertReviseWithEmptyActualDataNode() {
assertThat(new ShardingIndexReviser(mock(ShardingTable.class)).revise("foo_tbl", new IndexMetaData("foo_idx"), mock(ShardingRule.class)), is(Optional.empty()));
}

@Test
void assertReviseWithActualDataNodes() {
Optional<IndexMetaData> actual = new ShardingIndexReviser(mockShardingTable()).revise("tbl_0", new IndexMetaData("foo_idx", Collections.singletonList("foo_col")), mock(ShardingRule.class));
void assertReviseWithHashedActualIndexName() {
Optional<IndexMetaData> actual = new ShardingIndexReviser(mockShardingTable())
.revise("tbl_0", new IndexMetaData(IndexMetaDataUtils.getActualIndexName("named_index_boundary_case_abcdefghijklmnopqrstuvwxyz", "tbl_0", databaseType),
Collections.singletonList("foo_col")), mock(ShardingRule.class));
assertTrue(actual.isPresent());
assertThat(actual.get().getName(), is("foo_idx"));
assertThat(actual.get().getName(), is("named_index_boundary_case_abcdefghijklmnopqrstuvwxyz"));
assertThat(actual.get().getColumns().size(), is(1));
}

@Test
void assertReviseWithLegacyActualIndexName() {
Optional<IndexMetaData> actual = new ShardingIndexReviser(mockShardingTable())
.revise("tbl_0", new IndexMetaData(IndexMetaDataUtils.getLegacyActualIndexName("foo_idx", "tbl_0"), Collections.singletonList("foo_col")), mock(ShardingRule.class));
assertTrue(actual.isPresent());
assertThat(actual.get().getName(), is("foo_idx"));
}

@Test
void assertReviseWithLegacyActualIndexNameForSecondActualTable() {
Optional<IndexMetaData> actual = new ShardingIndexReviser(mockShardingTable())
.revise("tbl_1", new IndexMetaData(IndexMetaDataUtils.getLegacyActualIndexName("foo_idx", "tbl_1"), Collections.singletonList("foo_col")), mock(ShardingRule.class));
assertTrue(actual.isPresent());
assertThat(actual.get().getName(), is("foo_idx"));
}

@Test
void assertReviseWithTruncatedAnonymousActualIndexName() {
String logicIndexName = "very_long_status_column_name_for_sharding_rewrite_validation_account_identifier_idx";
Optional<IndexMetaData> actual = new ShardingIndexReviser(mockShardingTable())
.revise("tbl_0", new IndexMetaData(IndexMetaDataUtils.getActualIndexName(logicIndexName, "tbl_0", databaseType),
Arrays.asList("very_long_status_column_name_for_sharding_rewrite_validation", "account_identifier")), mock(ShardingRule.class));
assertTrue(actual.isPresent());
assertThat(actual.get().getName(), is(logicIndexName));
}

private static ShardingTable mockShardingTable() {
ShardingTable result = mock(ShardingTable.class);
when(result.getActualDataNodes()).thenReturn(Arrays.asList(new DataNode("foo_schema", (String) null, "tbl_0"), new DataNode("foo_schema", (String) null, "tbl_1")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
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;
Expand All @@ -41,12 +42,13 @@

class IndexTokenTest {

private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");

@Test
void assertToStringWithNotShardingTable() {
SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.emptyList());
when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
IndexToken indexToken = new IndexToken(0, 0, new IdentifierValue("foo_idx"), selectStatementContext, mock(ShardingRule.class), mockSchema());
assertThat(indexToken.toString(mockRouteUnit()), is("foo_idx"));
}
Expand All @@ -55,18 +57,28 @@ void assertToStringWithNotShardingTable() {
void assertToStringWithShardingTable() {
SelectStatementContext selectStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.emptyList());
when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
ShardingRule rule = mock(ShardingRule.class);
when(rule.isShardingTable("foo_tbl")).thenReturn(true);
IndexToken indexToken = new IndexToken(0, 0, new IdentifierValue("foo_idx"), selectStatementContext, rule, mockSchema());
assertThat(indexToken.toString(mockRouteUnit()), is("foo_idx_foo_tbl_0"));
assertThat(indexToken.toString(mockRouteUnit()), is(IndexMetaDataUtils.getActualIndexName("foo_idx", "foo_tbl_0", databaseType)));
}

@Test
void assertToStringWithShardingTableAndGeneratedIndex() {
CreateIndexStatement sqlStatement = CreateIndexStatement.builder().databaseType(databaseType).build();
CommonSQLStatementContext sqlStatementContext = new CommonSQLStatementContext(sqlStatement);
IndexToken indexToken = new IndexToken(0, 0, new IdentifierValue("bar_idx"), sqlStatementContext, mock(ShardingRule.class), mockSchema());
assertThat(indexToken.toString(mockRouteUnit()), is(" bar_idx_foo_tbl_0 "));
assertThat(indexToken.toString(mockRouteUnit()), is(" " + IndexMetaDataUtils.getActualIndexName("bar_idx", "foo_tbl_0", databaseType) + " "));
}

@Test
void assertToStringWithLongGeneratedIndex() {
CreateIndexStatement sqlStatement = CreateIndexStatement.builder().databaseType(databaseType).build();
CommonSQLStatementContext sqlStatementContext = new CommonSQLStatementContext(sqlStatement);
String logicIndexName = "very_long_generated_index_boundary_case_for_sharding_length_safety_validation";
IndexToken indexToken = new IndexToken(0, 0, new IdentifierValue(logicIndexName), sqlStatementContext, mock(ShardingRule.class), mockSchema());
assertThat(indexToken.toString(mockRouteUnit()), is(" " + IndexMetaDataUtils.getActualIndexName(logicIndexName, "foo_tbl_0", databaseType) + " "));
}

private ShardingSphereSchema mockSchema() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,16 @@ private void replaceBindingTables(final MemoryQueryResultRow memoryResultSetRow,

private void replaceIndexes(final MemoryQueryResultRow memoryResultSetRow, final String actualTableName, final ShardingSphereTable table) {
for (ShardingSphereIndex each : table.getAllIndexes()) {
String actualIndexName = IndexMetaDataUtils.getActualIndexName(each.getName(), actualTableName);
String actualIndexName = IndexMetaDataUtils.getShortenedActualIndexName(each.getName(), actualTableName);
memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replace(actualIndexName, each.getName()));
String legacyActualIndexName = IndexMetaDataUtils.getLegacyActualIndexName(each.getName(), actualTableName);
memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replace(legacyActualIndexName, each.getName()));
}
}

private void replaceConstraints(final MemoryQueryResultRow memoryResultSetRow, final String actualTableName, final ShardingSphereTable table, final ShardingRule rule) {
for (ShardingSphereConstraint each : table.getAllConstraints()) {
String actualIndexName = IndexMetaDataUtils.getActualIndexName(each.getName(), actualTableName);
String actualIndexName = IndexMetaDataUtils.getLegacyActualIndexName(each.getName(), actualTableName);
memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replace(actualIndexName, each.getName()));
Optional<ShardingTable> shardingTable = rule.findShardingTable(each.getReferencedTableName());
if (!shardingTable.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
import org.apache.shardingsphere.sharding.rule.ShardingTable;

import java.sql.SQLException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
* Sharding merged result for show index for MySQL.
Expand All @@ -51,8 +53,13 @@ protected List<MemoryQueryResultRow> init(final ShardingRule shardingRule, final
String actualTableName = memoryResultSetRow.getCell(1).toString();
String actualIndexName = memoryResultSetRow.getCell(3).toString();
Optional<ShardingTable> shardingTable = shardingRule.findShardingTableByActualTable(actualTableName);
shardingTable.ifPresent(optional -> memoryResultSetRow.setCell(1, optional.getLogicTable()));
memoryResultSetRow.setCell(3, IndexMetaDataUtils.getLogicIndexName(actualIndexName, actualTableName));
Collection<String> candidateLogicIndexNames = new LinkedList<>();
if (shardingTable.isPresent()) {
String logicTableName = shardingTable.get().getLogicTable();
memoryResultSetRow.setCell(1, logicTableName);
candidateLogicIndexNames = schema.getTable(logicTableName).getAllIndexes().stream().map(eachIndex -> eachIndex.getName()).collect(Collectors.toList());
}
memoryResultSetRow.setCell(3, IndexMetaDataUtils.findGeneratedLogicIndexName(actualIndexName, actualTableName, candidateLogicIndexNames).orElse(actualIndexName));
result.add(memoryResultSetRow);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
import org.apache.shardingsphere.infra.instance.ComputeNodeInstanceContext;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereConstraint;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
import org.apache.shardingsphere.infra.metadata.database.schema.util.IndexMetaDataUtils;
import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
Expand Down Expand Up @@ -132,6 +134,29 @@ void assertGetValueWithoutTableRule() throws SQLException {
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin"));
}

@Test
void assertGetValueWithLegacyIndexName() throws SQLException {
MySQLShardingShowCreateTableMergedResult actual = new MySQLShardingShowCreateTableMergedResult(
rule, mock(SQLStatementContext.class), createSchemaWithIndex(),
Collections.singletonList(mockQueryResultWithIndex(IndexMetaDataUtils.getLegacyActualIndexName("foo_idx", "foo_tbl_0"))));
assertTrue(actual.next());
assertThat(actual.getValue(2, String.class), is("CREATE TABLE `foo_tbl` (\n"
+ " `id` int(11) NOT NULL,\n"
+ " KEY `foo_idx` (`id`)\n"
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin"));
}

@Test
void assertGetValueWithShortenedIndexName() throws SQLException {
MySQLShardingShowCreateTableMergedResult actual = new MySQLShardingShowCreateTableMergedResult(
rule, mock(SQLStatementContext.class), createSchemaWithIndex(), Collections.singletonList(mockQueryResultWithIndex(IndexMetaDataUtils.getActualIndexName("foo_idx", "foo_tbl_0"))));
assertTrue(actual.next());
assertThat(actual.getValue(2, String.class), is("CREATE TABLE `foo_tbl` (\n"
+ " `id` int(11) NOT NULL,\n"
+ " KEY `foo_idx` (`id`)\n"
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin"));
}

private QueryResult mockQueryResultWithoutTableRule() throws SQLException {
QueryResult result = mock(QueryResult.class, RETURNS_DEEP_STUBS);
when(result.getMetaData().getColumnCount()).thenReturn(2);
Expand All @@ -148,4 +173,22 @@ private QueryResult mockQueryResultWithoutTableRule() throws SQLException {
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin");
return result;
}

private ShardingSphereSchema createSchemaWithIndex() {
ShardingSphereTable table =
new ShardingSphereTable("foo_tbl", Collections.emptyList(), Collections.singleton(new ShardingSphereIndex("foo_idx", Collections.emptyList(), false)), Collections.emptyList());
return new ShardingSphereSchema("foo_db", mock(DatabaseType.class), Collections.singleton(table), Collections.emptyList());
}

private QueryResult mockQueryResultWithIndex(final String actualIndexName) throws SQLException {
QueryResult result = mock(QueryResult.class, RETURNS_DEEP_STUBS);
when(result.getMetaData().getColumnCount()).thenReturn(2);
when(result.next()).thenReturn(true, false);
when(result.getValue(1, Object.class)).thenReturn("foo_tbl_0");
when(result.getValue(2, Object.class)).thenReturn("CREATE TABLE `foo_tbl_0` (\n"
+ " `id` int(11) NOT NULL,\n"
+ " KEY `" + actualIndexName + "` (`id`)\n"
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin");
return result;
}
}
Loading
Loading