Skip to content

Commit

Permalink
Pick #32700, fix alter view exception (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
RaigorJiang authored Sep 25, 2024
1 parent 6e2af4d commit e939037
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.shardingsphere.sharding.merge.dal.show;

import com.cedarsoftware.util.CaseInsensitiveMap;
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.datanode.DataNode;
import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
Expand All @@ -26,12 +27,17 @@
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.rule.BindingTableRule;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sharding.rule.ShardingTable;

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

/**
* Merged result for show create table.
Expand All @@ -47,6 +53,7 @@ public ShowCreateTableMergedResult(final ShardingRule shardingRule,
protected void setCellValue(final MemoryQueryResultRow memoryResultSetRow, final String logicTableName, final String actualTableName,
final ShardingSphereTable table, final ShardingRule shardingRule) {
memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replaceFirst(actualTableName, logicTableName));
setViewCellValue(memoryResultSetRow, logicTableName, actualTableName, shardingRule);
for (ShardingSphereIndex each : table.getIndexValues()) {
String actualIndexName = IndexMetaDataUtils.getActualIndexName(each.getName(), actualTableName);
memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replace(actualIndexName, each.getName()));
Expand All @@ -63,4 +70,20 @@ protected void setCellValue(final MemoryQueryResultRow memoryResultSetRow, final
}
}
}

private void setViewCellValue(final MemoryQueryResultRow memoryResultSetRow, final String logicTableName, final String actualTableName, final ShardingRule shardingRule) {
Optional<ShardingTable> shardingTable = shardingRule.findShardingTable(logicTableName);
Optional<BindingTableRule> bindingTableRule = shardingRule.findBindingTableRule(logicTableName);
if (shardingTable.isPresent() && bindingTableRule.isPresent()) {
Collection<DataNode> actualDataNodes = shardingTable.get().getActualDataNodes().stream().filter(each -> each.getTableName().equalsIgnoreCase(actualTableName)).collect(Collectors.toList());
Map<String, String> logicAndActualTablesFromBindingTables = new CaseInsensitiveMap<>();
for (DataNode each : actualDataNodes) {
logicAndActualTablesFromBindingTables
.putAll(shardingRule.getLogicAndActualTablesFromBindingTable(each.getDataSourceName(), logicTableName, actualTableName, bindingTableRule.get().getAllLogicTables()));
}
for (Entry<String, String> entry : logicAndActualTablesFromBindingTables.entrySet()) {
memoryResultSetRow.setCell(2, memoryResultSetRow.getCell(2).toString().replaceFirst(entry.getValue(), entry.getKey()));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;

import java.util.Arrays;
import java.util.Collection;

/**
Expand Down Expand Up @@ -85,7 +86,7 @@ protected void validateTableNotExist(final ShardingSphereSchema schema, final Co

/**
* Judge whether route unit and data node are different size.
*
*
* @param shardingRule sharding rule
* @param routeContext route context
* @param tableName table name
Expand All @@ -105,4 +106,22 @@ protected boolean isRouteUnitDataNodeDifferentSize(final ShardingRule shardingRu
protected boolean isSchemaContainsIndex(final ShardingSphereSchema schema, final IndexSegment index) {
return schema.getAllTableNames().stream().anyMatch(each -> schema.getTable(each).containsIndex(index.getIndexName().getIdentifier().getValue()));
}

/**
* Judge whether sharding tables not binding with view.
*
* @param tableSegments table segments
* @param shardingRule sharding rule
* @param viewName view name
* @return sharding tables not binding with view or not
*/
protected boolean isShardingTablesNotBindingWithView(final Collection<SimpleTableSegment> tableSegments, final ShardingRule shardingRule, final String viewName) {
for (SimpleTableSegment each : tableSegments) {
String logicTable = each.getTableName().getIdentifier().getValue();
if (shardingRule.isShardingTable(logicTable) && !shardingRule.isAllBindingTables(Arrays.asList(viewName, logicTable))) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
import org.apache.shardingsphere.sharding.exception.metadata.EngagedViewException;
import org.apache.shardingsphere.sharding.exception.syntax.RenamedViewWithoutSameConfigurationException;
import org.apache.shardingsphere.sharding.route.engine.validator.ddl.ShardingDDLStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
Expand All @@ -46,19 +47,23 @@ public void preValidate(final ShardingRule shardingRule, final SQLStatementConte
final List<Object> params, final ShardingSphereDatabase database, final ConfigurationProperties props) {
AlterViewStatement alterViewStatement = (AlterViewStatement) sqlStatementContext.getSqlStatement();
Optional<SelectStatement> selectStatement = AlterViewStatementHandler.getSelectStatement(alterViewStatement);
if (selectStatement.isPresent()) {
TableExtractor extractor = new TableExtractor();
extractor.extractTablesFromSelect(selectStatement.get());
validateShardingTable(shardingRule, "ALTER VIEW", extractor.getRewriteTables());
}
String originView = alterViewStatement.getView().getTableName().getIdentifier().getValue();
selectStatement.ifPresent(optional -> validateAlterViewShardingTables(shardingRule, optional, originView));
Optional<SimpleTableSegment> renamedView = AlterViewStatementHandler.getRenameView(alterViewStatement);
if (renamedView.isPresent()) {
String targetView = renamedView.get().getTableName().getIdentifier().getValue();
String originView = alterViewStatement.getView().getTableName().getIdentifier().getValue();
validateBroadcastShardingView(shardingRule, originView, targetView);
}
}

private void validateAlterViewShardingTables(final ShardingRule shardingRule, final SelectStatement selectStatement, final String viewName) {
TableExtractor extractor = new TableExtractor();
extractor.extractTablesFromSelect(selectStatement);
if (isShardingTablesNotBindingWithView(extractor.getRewriteTables(), shardingRule, viewName)) {
throw new EngagedViewException("sharding");
}
}

private void validateBroadcastShardingView(final ShardingRule shardingRule, final String originView, final String targetView) {
ShardingSpherePreconditions.checkState(!shardingRule.isShardingTable(originView) && !shardingRule.isShardingTable(targetView)
|| shardingRule.isAllBindingTables(Arrays.asList(originView, targetView)), () -> new RenamedViewWithoutSameConfigurationException(originView, targetView));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.SelectStatementHandler;
import org.apache.shardingsphere.sqlfederation.rule.SQLFederationRule;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

Expand All @@ -56,7 +55,8 @@ public void preValidate(final ShardingRule shardingRule, final SQLStatementConte
extractor.extractTablesFromSelect(((CreateViewStatement) sqlStatementContext.getSqlStatement()).getSelect());
Collection<SimpleTableSegment> tableSegments = extractor.getRewriteTables();
boolean sqlFederationEnabled = globalRuleMetaData.getSingleRule(SQLFederationRule.class).getConfiguration().isSqlFederationEnabled();
if (!sqlFederationEnabled && isShardingTablesWithoutBinding(shardingRule, sqlStatementContext, tableSegments)) {
String viewName = ((CreateViewStatement) sqlStatementContext.getSqlStatement()).getView().getTableName().getIdentifier().getValue();
if (!sqlFederationEnabled && isShardingTablesNotBindingWithView(tableSegments, shardingRule, viewName)) {
throw new EngagedViewException("sharding");
}
}
Expand All @@ -70,23 +70,6 @@ public void postValidate(final ShardingRule shardingRule, final SQLStatementCont
}
}

private boolean isShardingTablesWithoutBinding(final ShardingRule shardingRule, final SQLStatementContext sqlStatementContext,
final Collection<SimpleTableSegment> tableSegments) {
for (SimpleTableSegment each : tableSegments) {
String logicTable = each.getTableName().getIdentifier().getValue();
if (shardingRule.isShardingTable(logicTable) && !isBindingTables(
shardingRule, ((CreateViewStatement) sqlStatementContext.getSqlStatement()).getView().getTableName().getIdentifier().getValue(), logicTable)) {
return true;
}
}
return false;
}

private boolean isBindingTables(final ShardingRule shardingRule, final String logicViewName, final String logicTable) {
Collection<String> bindTables = Arrays.asList(logicTable, logicViewName);
return shardingRule.isAllBindingTables(bindTables);
}

private boolean isContainsNotSupportedViewStatement(final SelectStatement selectStatement, final RouteContext routeContext) {
if (routeContext.getRouteUnits().size() <= 1) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.apache.shardingsphere.infra.binder.context.statement.ddl.AlterViewStatementContext;
import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.sharding.exception.syntax.UnsupportedShardingOperationException;
import org.apache.shardingsphere.sharding.exception.metadata.EngagedViewException;
import org.apache.shardingsphere.sharding.route.engine.validator.ddl.impl.ShardingAlterViewStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
Expand Down Expand Up @@ -53,6 +53,7 @@ void assertPreValidateAlterViewForMySQL() {
MySQLSelectStatement selectStatement = new MySQLSelectStatement();
selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
MySQLAlterViewStatement sqlStatement = new MySQLAlterViewStatement();
sqlStatement.setView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_view"))));
sqlStatement.setSelect(selectStatement);
SQLStatementContext sqlStatementContext = new AlterViewStatementContext(sqlStatement);
ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
Expand All @@ -65,20 +66,21 @@ void assertPreValidateAlterViewWithShardingTableForMySQL() {
MySQLSelectStatement selectStatement = new MySQLSelectStatement();
selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
MySQLAlterViewStatement sqlStatement = new MySQLAlterViewStatement();
sqlStatement.setView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_view"))));
sqlStatement.setSelect(selectStatement);
ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
SQLStatementContext sqlStatementContext = new AlterViewStatementContext(sqlStatement);
when(shardingRule.isShardingTable("t_order")).thenReturn(true);
assertThrows(UnsupportedShardingOperationException.class,
assertThrows(EngagedViewException.class,
() -> new ShardingAlterViewStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList(), database, mock(ConfigurationProperties.class)));
}

@Test
void assertPreValidateAlterRenamedView() {
OpenGaussAlterViewStatement selectStatement = new OpenGaussAlterViewStatement();
selectStatement.setView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
selectStatement.setRenameView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_new"))));
SQLStatementContext sqlStatementContext = new AlterViewStatementContext(selectStatement);
OpenGaussAlterViewStatement sqlStatement = new OpenGaussAlterViewStatement();
sqlStatement.setView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_view"))));
sqlStatement.setRenameView(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order_new"))));
SQLStatementContext sqlStatementContext = new AlterViewStatementContext(sqlStatement);
ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
assertDoesNotThrow(() -> new ShardingAlterViewStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList(), database, mock(ConfigurationProperties.class)));
}
Expand Down

0 comments on commit e939037

Please sign in to comment.