You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/07/29 08:06:14 UTC

[shardingsphere] branch master updated: fix issue #11103 (#11385)

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 <ar...@126.com>
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>