This is an automated email from the ASF dual-hosted git repository.

jianglongtao pushed a commit to branch fix-33341
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git

commit e9390375598f97f7bfac2329da6c8968e0eb77cc
Author: Raigor <[email protected]>
AuthorDate: Wed Sep 25 10:38:30 2024 +0800

    Pick #32700, fix alter view exception (#11)
---
 .../dal/show/ShowCreateTableMergedResult.java      | 23 ++++++++++++++++++++++
 .../ddl/ShardingDDLStatementValidator.java         | 21 +++++++++++++++++++-
 .../impl/ShardingAlterViewStatementValidator.java  | 17 ++++++++++------
 .../impl/ShardingCreateViewStatementValidator.java | 21 ++------------------
 .../ShardingAlterViewStatementValidatorTest.java   | 14 +++++++------
 5 files changed, 64 insertions(+), 32 deletions(-)

diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/merge/dal/show/ShowCreateTableMergedResult.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/merge/dal/show/ShowCreateTableMergedResult.java
index ebf27fa5c39..e7d8250644b 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/merge/dal/show/ShowCreateTableMergedResult.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/merge/dal/show/ShowCreateTableMergedResult.java
@@ -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;
@@ -26,12 +27,17 @@ import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp
 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.
@@ -47,6 +53,7 @@ public final class ShowCreateTableMergedResult extends 
LogicTablesMergedResult {
     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()));
@@ -63,4 +70,20 @@ public final class ShowCreateTableMergedResult extends 
LogicTablesMergedResult {
             }
         }
     }
+    
+    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()));
+            }
+        }
+    }
 }
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/ShardingDDLStatementValidator.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/ShardingDDLStatementValidator.java
index 2b2aa2b793b..aee3d14a37d 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/ShardingDDLStatementValidator.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/ShardingDDLStatementValidator.java
@@ -27,6 +27,7 @@ import org.apache.shardingsphere.sharding.rule.ShardingRule;
 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;
 
 /**
@@ -85,7 +86,7 @@ public abstract class ShardingDDLStatementValidator 
implements ShardingStatement
     
     /**
      * Judge whether route unit and data node are different size.
-     * 
+     *
      * @param shardingRule sharding rule
      * @param routeContext route context
      * @param tableName table name
@@ -105,4 +106,22 @@ public abstract class ShardingDDLStatementValidator 
implements ShardingStatement
     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;
+    }
 }
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/impl/ShardingAlterViewStatementValidator.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/impl/ShardingAlterViewStatementValidator.java
index 53da20cb234..37bbdfb79f8 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/impl/ShardingAlterViewStatementValidator.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/impl/ShardingAlterViewStatementValidator.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.infra.hint.HintValueContext;
 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;
@@ -46,19 +47,23 @@ public final class ShardingAlterViewStatementValidator 
extends ShardingDDLStatem
                             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));
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/impl/ShardingCreateViewStatementValidator.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/impl/ShardingCreateViewStatementValidator.java
index 0e80e1a5399..3a4f2914af5 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/impl/ShardingCreateViewStatementValidator.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/impl/ShardingCreateViewStatementValidator.java
@@ -37,7 +37,6 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectState
 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;
 
@@ -56,7 +55,8 @@ public final class ShardingCreateViewStatementValidator 
extends ShardingDDLState
         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");
         }
     }
@@ -70,23 +70,6 @@ public final class ShardingCreateViewStatementValidator 
extends ShardingDDLState
         }
     }
     
-    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;
diff --git 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/ShardingAlterViewStatementValidatorTest.java
 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/ShardingAlterViewStatementValidatorTest.java
index 308999a27d9..ad85024e834 100644
--- 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/ShardingAlterViewStatementValidatorTest.java
+++ 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/ddl/ShardingAlterViewStatementValidatorTest.java
@@ -21,7 +21,7 @@ import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementCont
 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;
@@ -53,6 +53,7 @@ class ShardingAlterViewStatementValidatorTest {
         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);
@@ -65,20 +66,21 @@ class ShardingAlterViewStatementValidatorTest {
         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)));
     }

Reply via email to