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

panjuan 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 c05c7bb  fix issue #11103 (#11385)
c05c7bb is described below

commit c05c7bb06d4cc42621550add2e0bd5c879c9fcaf
Author: arthasking123 <[email protected]>
AuthorDate: Thu Jul 29 16:03:33 2021 +0800

    fix issue #11103 (#11385)
    
    * fix issue #11103
    
    * fix issue #11103
    
    * fix issue #11103
    
    * fix issue #11103
    
    * fix issue #11103
    
    * fix issue #11105
    
    * fix issue #11103,#11105
    
    * style fix
    
    * style fix
    
    * modify variable naming
---
 .../impl/EncryptAlterTableTokenGenerator.java      | 78 +++++++++++++++++++---
 .../rewrite/token/pojo/EncryptAlterTableToken.java |  3 +-
 .../impl/MySQLDDLStatementSQLVisitor.java          |  9 ++-
 .../alter/ModifyColumnDefinitionSegment.java       |  2 +
 .../encrypt/case/alter_for_query_with_plain.xml    |  7 +-
 5 files changed, 85 insertions(+), 14 deletions(-)

diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptAlterTableTokenGenerator.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptAlterTableTokenGenerator.java
index 35428df..524bbf0 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptAlterTableTokenGenerator.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptAlterTableTokenGenerator.java
@@ -24,6 +24,7 @@ import 
org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.ddl.AlterTableStatementContext;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
 import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
+import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.Substitutable;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.RemoveToken;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.ColumnDefinitionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.alter.AddColumnDefinitionSegment;
@@ -31,12 +32,14 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.alter.
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.alter.ModifyColumnDefinitionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 
+import java.util.List;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Optional;
 
 /**
- * Create table token generator for encrypt.
+ * Alter table token generator for encrypt.
  */
 public final class EncryptAlterTableTokenGenerator extends 
BaseEncryptSQLTokenGenerator implements 
CollectionSQLTokenGenerator<AlterTableStatementContext> {
     
@@ -50,7 +53,40 @@ public final class EncryptAlterTableTokenGenerator extends 
BaseEncryptSQLTokenGe
         String tableName = 
alterTableStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue();
         Collection<SQLToken> result = new 
LinkedList<>(getAddColumnTokens(tableName, 
alterTableStatementContext.getSqlStatement().getAddColumnDefinitions()));
         result.addAll(getModifyColumnTokens(tableName, 
alterTableStatementContext.getSqlStatement().getModifyColumnDefinitions()));
-        result.addAll(getDropColumnTokens(tableName, 
alterTableStatementContext.getSqlStatement().getDropColumnDefinitions()));
+        Collection<SQLToken> dropCollection = getDropColumnTokens(tableName, 
alterTableStatementContext.getSqlStatement().getDropColumnDefinitions());
+        String databaseName = 
alterTableStatementContext.getDatabaseType().getName();
+        if ("SQLServer".equals(databaseName)) {
+            result.addAll(mergeDropColumnStatement(dropCollection, "", ""));
+        } else if ("Oracle".equals(databaseName)) {
+            result.addAll(mergeDropColumnStatement(dropCollection, "(", ")"));
+        } else {
+            result.addAll(dropCollection);
+        }
+        return result;
+    }
+    
+    private Collection<SQLToken> mergeDropColumnStatement(final 
Collection<SQLToken> dropCollection, final String leftJoiner, final String 
rightJoiner) {
+        Collection<SQLToken> result = new LinkedList<>();
+        ArrayList<String> dropColumnList = new ArrayList<>();
+        int lastStartIndex = -1;
+        for (int i = 0; i < dropCollection.size(); i++) {
+            SQLToken token = (SQLToken) ((List) dropCollection).get(i);
+            if (token instanceof RemoveToken) {
+                if (i != 0) {
+                    result.add(new RemoveToken(lastStartIndex, ((RemoveToken) 
token).getStopIndex()));
+                } else {
+                    result.add(token);
+                }
+            } else {
+                EncryptAlterTableToken encryptAlterTableToken = 
(EncryptAlterTableToken) token;
+                dropColumnList.add(encryptAlterTableToken.getColumnName());
+                if (i == dropCollection.size() - 1) {
+                    result.add(new 
EncryptAlterTableToken(token.getStartIndex(), 
encryptAlterTableToken.getStopIndex(),
+                            leftJoiner + String.join(",", dropColumnList) + 
rightJoiner, "DROP COLUMN"));
+                }
+            }
+            lastStartIndex = ((Substitutable) token).getStartIndex();
+        }
         return result;
     }
     
@@ -90,7 +126,9 @@ public final class EncryptAlterTableTokenGenerator extends 
BaseEncryptSQLTokenGe
             ColumnDefinitionSegment segment = each.getColumnDefinition();
             String columnName = 
segment.getColumnName().getIdentifier().getValue();
             Optional<EncryptAlgorithm> encryptor = 
getEncryptRule().findEncryptor(tableName, columnName);
-            if (encryptor.isPresent()) {
+            Optional<EncryptAlgorithm> encryptorPrevious = 
getEncryptRule().findEncryptor(tableName,
+                    
Optional.ofNullable(each.getPreviousColumnDefinition()).map(columnDefinitionSegment
 -> 
columnDefinitionSegment.getColumnName().getIdentifier().getValue()).orElse(""));
+            if (encryptor.isPresent() || encryptorPrevious.isPresent()) {
                 result.addAll(getModifyColumnTokens(tableName, columnName, 
each, segment));
             }
         }
@@ -122,6 +160,9 @@ public final class EncryptAlterTableTokenGenerator extends 
BaseEncryptSQLTokenGe
             Optional<EncryptAlgorithm> encryptor = 
getEncryptRule().findEncryptor(tableName, columnName);
             if (encryptor.isPresent()) {
                 result.addAll(getDropColumnTokens(tableName, columnName, each, 
dropColumnDefinitionSegment));
+            } else {
+                result.add(new 
RemoveToken(dropColumnDefinitionSegment.getStartIndex() - 1, 
each.getStopIndex()));
+                result.add(new EncryptAlterTableToken(each.getStopIndex() + 1, 
each.getStopIndex(), columnName, "DROP COLUMN"));
             }
         }
         return result;
@@ -144,8 +185,13 @@ public final class EncryptAlterTableTokenGenerator extends 
BaseEncryptSQLTokenGe
     
     private EncryptAlterTableToken getCipherColumn(final String tableName, 
final String columnName,
                                                    final 
ModifyColumnDefinitionSegment modifyColumnDefinitionSegment, final 
ColumnDefinitionSegment columnDefinitionSegment) {
-        String cipherColumn = getEncryptRule().getCipherColumn(tableName, 
columnName);
-        return new 
EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1, 
columnDefinitionSegment.getDataType().getStartIndex() - 1, cipherColumn, 
"MODIFY COLUMN");
+        String previousColumnName = 
Optional.ofNullable(modifyColumnDefinitionSegment.getPreviousColumnDefinition()).map(segment
 -> segment.getColumnName().getIdentifier().getValue()).orElse("");
+        String cipherColumnPrevious = (!previousColumnName.isEmpty())
+                ? getEncryptRule().getCipherColumn(tableName, 
previousColumnName) : "";
+        String encryptColumnName = cipherColumnPrevious.isEmpty()
+                ? getEncryptRule().getCipherColumn(tableName, columnName) : 
columnDefinitionSegment.getColumnName().getQualifiedName() + "_cipher";
+        String encryptCommand = cipherColumnPrevious.isEmpty() ? "MODIFY 
COLUMN" : "CHANGE COLUMN " + cipherColumnPrevious;
+        return new 
EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1, 
columnDefinitionSegment.getDataType().getStartIndex() - 1, encryptColumnName, 
encryptCommand);
     }
     
     private EncryptAlterTableToken getCipherColumn(final String tableName, 
final String columnName, final ColumnSegment columnSegment) {
@@ -161,9 +207,14 @@ public final class EncryptAlterTableTokenGenerator extends 
BaseEncryptSQLTokenGe
     
     private Optional<EncryptAlterTableToken> getAssistedQueryColumn(final 
String tableName, final String columnName,
                                                                     final 
ModifyColumnDefinitionSegment modifyColumnDefinitionSegment, final 
ColumnDefinitionSegment columnDefinitionSegment) {
-        Optional<String> assistedQueryColumn = 
getEncryptRule().findAssistedQueryColumn(tableName, columnName);
-        return assistedQueryColumn.map(optional -> new EncryptAlterTableToken(
-                modifyColumnDefinitionSegment.getStopIndex() + 1, 
columnDefinitionSegment.getDataType().getStartIndex() - 1, optional, ", MODIFY 
COLUMN"));
+        String previousColumnName = 
Optional.ofNullable(modifyColumnDefinitionSegment.getPreviousColumnDefinition()).map(segment
 -> segment.getColumnName().getIdentifier().getValue()).orElse("");
+        Optional<String> assistedQueryColumnPrevious = 
(!previousColumnName.isEmpty())
+                ? getEncryptRule().findAssistedQueryColumn(tableName, 
previousColumnName) : Optional.of("");
+        String encryptColumnName = 
assistedQueryColumnPrevious.orElse("").isEmpty()
+                ? getEncryptRule().findAssistedQueryColumn(tableName, 
columnName).orElse("") : 
columnDefinitionSegment.getColumnName().getQualifiedName() + "_assisted";
+        String encryptCommand = 
assistedQueryColumnPrevious.orElse("").isEmpty() ? ", MODIFY COLUMN" : ", 
CHANGE COLUMN " + assistedQueryColumnPrevious.get();
+        return Optional.of(new EncryptAlterTableToken(
+                modifyColumnDefinitionSegment.getStopIndex() + 1, 
columnDefinitionSegment.getDataType().getStartIndex() - 1, encryptColumnName, 
encryptCommand));
     }
     
     private Optional<EncryptAlterTableToken> getAssistedQueryColumn(final 
String tableName, final String columnName, final ColumnSegment columnSegment) {
@@ -179,9 +230,14 @@ public final class EncryptAlterTableTokenGenerator extends 
BaseEncryptSQLTokenGe
     
     private Optional<EncryptAlterTableToken> getPlainColumn(final String 
tableName, final String columnName,
                                                             final 
ModifyColumnDefinitionSegment modifyColumnDefinitionSegment, final 
ColumnDefinitionSegment columnDefinitionSegment) {
-        Optional<String> plainColumn = 
getEncryptRule().findPlainColumn(tableName, columnName);
-        return plainColumn.map(optional -> new EncryptAlterTableToken(
-                modifyColumnDefinitionSegment.getStopIndex() + 1, 
columnDefinitionSegment.getDataType().getStartIndex() - 1, optional, ", MODIFY 
COLUMN"));
+        String previousColumnName = 
Optional.ofNullable(modifyColumnDefinitionSegment.getPreviousColumnDefinition()).map(segment
 -> segment.getColumnName().getIdentifier().getValue()).orElse("");
+        Optional<String> plainColumnPrevious = (!previousColumnName.isEmpty())
+                ? getEncryptRule().findPlainColumn(tableName, 
previousColumnName) : Optional.of("");
+        String encryptColumnName = plainColumnPrevious.orElse("").isEmpty()
+                ? getEncryptRule().findPlainColumn(tableName, 
columnName).orElse("") : 
columnDefinitionSegment.getColumnName().getQualifiedName() + "_plain";
+        String encryptCommand = plainColumnPrevious.orElse("").isEmpty() ? ", 
MODIFY COLUMN" : ", CHANGE COLUMN " + plainColumnPrevious.get();
+        return Optional.of(new EncryptAlterTableToken(
+                modifyColumnDefinitionSegment.getStopIndex() + 1, 
columnDefinitionSegment.getDataType().getStartIndex() - 1, encryptColumnName, 
encryptCommand));
     }
     
     private Optional<EncryptAlterTableToken> getPlainColumn(final String 
tableName, final String columnName, final ColumnSegment columnSegment) {
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/pojo/EncryptAlterTableToken.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/pojo/EncryptAlterTableToken.java
index b4dec8b..b3bb0ba 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/pojo/EncryptAlterTableToken.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/pojo/EncryptAlterTableToken.java
@@ -22,8 +22,9 @@ import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
 import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.Substitutable;
 
 /**
- * Create table token for encrypt.
+ * Alter table token for encrypt.
  */
+
 @Getter
 public final class EncryptAlterTableToken extends SQLToken implements 
Substitutable {
     
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLDDLStatementSQLVisitor.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLDDLStatementSQLVisitor.java
index 8edf5a6..3f3331b 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLDDLStatementSQLVisitor.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLDDLStatementSQLVisitor.java
@@ -161,7 +161,7 @@ import java.util.Properties;
  */
 @NoArgsConstructor
 public final class MySQLDDLStatementSQLVisitor extends 
MySQLStatementSQLVisitor implements DDLSQLVisitor, SQLStatementVisitor {
-    
+
     public MySQLDDLStatementSQLVisitor(final Properties props) {
         super(props);
     }
@@ -354,7 +354,14 @@ public final class MySQLDDLStatementSQLVisitor extends 
MySQLStatementSQLVisitor
     }
     
     private ModifyColumnDefinitionSegment 
generateModifyColumnDefinitionSegment(final ChangeColumnContext ctx) {
+        ColumnDefinitionSegment columnDefinition = (ColumnDefinitionSegment) 
visit(ctx.columnDefinition());
+        columnDefinition.setColumnName(new ColumnSegment(
+                columnDefinition.getColumnName().getStartIndex(),
+                columnDefinition.getColumnName().getStopIndex(),
+                new IdentifierValue(ctx.columnInternalRef.getText())
+        ));
         ModifyColumnDefinitionSegment result = new 
ModifyColumnDefinitionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), (ColumnDefinitionSegment) 
visit(ctx.columnDefinition()));
+        result.setPreviousColumnDefinition(columnDefinition);
         if (null != ctx.place()) {
             result.setColumnPosition((ColumnPositionSegment) 
visit(ctx.place()));
         }
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/ddl/column/alter/ModifyColumnDefinitionSegment.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/ddl/column/alter/ModifyColumnDefinitionSegment.java
index 57628d6..736dc28 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/ddl/column/alter/ModifyColumnDefinitionSegment.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/ddl/column/alter/ModifyColumnDefinitionSegment.java
@@ -40,6 +40,8 @@ public final class ModifyColumnDefinitionSegment implements 
AlterDefinitionSegme
     
     private final ColumnDefinitionSegment columnDefinition;
     
+    private ColumnDefinitionSegment previousColumnDefinition;
+    
     private ColumnPositionSegment columnPosition;
     
     /**
diff --git 
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/alter_for_query_with_plain.xml
 
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/alter_for_query_with_plain.xml
index 6f45f3c..9ef3893 100644
--- 
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/alter_for_query_with_plain.xml
+++ 
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/alter_for_query_with_plain.xml
@@ -27,6 +27,11 @@
         <output sql="ALTER TABLE t_account_bak MODIFY COLUMN cipher_password 
varchar(255) not null default '' , MODIFY COLUMN assisted_query_password 
varchar(255) not null default '' , MODIFY COLUMN plain_password varchar(255) 
not null default ''" />
     </rewrite-assertion>
     
+    <rewrite-assertion id="change_column_for_plain">
+        <input sql="ALTER TABLE t_account_bak CHANGE COLUMN password 
password_new varchar(255) not null default ''" />
+        <output sql="ALTER TABLE t_account_bak CHANGE COLUMN cipher_password 
password_new_cipher varchar(255) not null default '' , CHANGE COLUMN 
assisted_query_password password_new_assisted varchar(255) not null default '' 
, CHANGE COLUMN plain_password password_new_plain varchar(255) not null default 
''" />
+    </rewrite-assertion>
+    
     <rewrite-assertion id="drop_column_for_plain">
         <input sql="ALTER TABLE t_account_bak DROP COLUMN password" />
         <output sql="ALTER TABLE t_account_bak DROP COLUMN cipher_password  , 
DROP COLUMN assisted_query_password  , DROP COLUMN plain_password " />
@@ -39,6 +44,6 @@
     
     <rewrite-assertion id="drop_mix_columns_for_plain">
         <input sql="ALTER TABLE t_account_bak DROP COLUMN password , DROP 
COLUMN id" />
-        <output sql="ALTER TABLE t_account_bak DROP COLUMN cipher_password  , 
DROP COLUMN assisted_query_password  , DROP COLUMN plain_password  , DROP 
COLUMN id" />
+        <output sql="ALTER TABLE t_account_bak DROP COLUMN cipher_password  , 
DROP COLUMN assisted_query_password  , DROP COLUMN plain_password  , DROP 
COLUMN id " />
     </rewrite-assertion>
 </rewrite-assertions>

Reply via email to