You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by wu...@apache.org on 2023/06/11 07:39:20 UTC

[shardingsphere] branch master updated: Refactor EncryptAlterTableTokenGenerator (#26255)

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

wuweijie 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 ad6bda50d95 Refactor EncryptAlterTableTokenGenerator (#26255)
ad6bda50d95 is described below

commit ad6bda50d95fc58658f2e600012613e369105e1b
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Sun Jun 11 15:39:12 2023 +0800

    Refactor EncryptAlterTableTokenGenerator (#26255)
    
    * Remove EncryptRule.findEncryptColumn
    
    * Refactor EncryptAlterTableTokenGenerator
    
    * Refactor EncryptAlterTableTokenGenerator
    
    * Refactor EncryptAlterTableTokenGenerator
    
    * Refactor EncryptAlterTableTokenGenerator
---
 .../generator/EncryptAlterTableTokenGenerator.java | 172 ++++++++++-----------
 .../shardingsphere/encrypt/rule/EncryptTable.java  |  13 ++
 .../impl/EncryptAlterTableTokenGeneratorTest.java  |  97 ++++++------
 3 files changed, 147 insertions(+), 135 deletions(-)

diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAlterTableTokenGenerator.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAlterTableTokenGenerator.java
index 53bf8e3c428..da5b1ec3f44 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAlterTableTokenGenerator.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAlterTableTokenGenerator.java
@@ -20,12 +20,12 @@ package org.apache.shardingsphere.encrypt.rewrite.token.generator;
 import lombok.Setter;
 import org.apache.shardingsphere.encrypt.api.encrypt.standard.StandardEncryptAlgorithm;
 import org.apache.shardingsphere.encrypt.exception.metadata.EncryptColumnAlterException;
-import org.apache.shardingsphere.encrypt.exception.metadata.EncryptColumnNotFoundException;
 import org.apache.shardingsphere.encrypt.rewrite.aware.EncryptRuleAware;
 import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptAlterTableToken;
 import org.apache.shardingsphere.encrypt.rule.EncryptColumn;
 import org.apache.shardingsphere.encrypt.rule.EncryptColumnItem;
 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.encrypt.rule.EncryptTable;
 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;
@@ -63,10 +63,14 @@ public final class EncryptAlterTableTokenGenerator implements CollectionSQLToken
     @Override
     public Collection<SQLToken> generateSQLTokens(final AlterTableStatementContext alterTableStatementContext) {
         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(getChangeColumnTokens(tableName, alterTableStatementContext.getSqlStatement().getChangeColumnDefinitions()));
-        List<SQLToken> dropColumnTokens = getDropColumnTokens(tableName, alterTableStatementContext.getSqlStatement().getDropColumnDefinitions());
+        Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(tableName);
+        if (!encryptTable.isPresent()) {
+            return Collections.emptyList();
+        }
+        Collection<SQLToken> result = new LinkedList<>(getAddColumnTokens(tableName, encryptTable.get(), alterTableStatementContext.getSqlStatement().getAddColumnDefinitions()));
+        result.addAll(getModifyColumnTokens(tableName, encryptTable.get(), alterTableStatementContext.getSqlStatement().getModifyColumnDefinitions()));
+        result.addAll(getChangeColumnTokens(tableName, encryptTable.get(), alterTableStatementContext.getSqlStatement().getChangeColumnDefinitions()));
+        List<SQLToken> dropColumnTokens = getDropColumnTokens(tableName, encryptTable.get(), alterTableStatementContext.getSqlStatement().getDropColumnDefinitions());
         String databaseName = alterTableStatementContext.getDatabaseType().getType();
         if ("SQLServer".equals(databaseName)) {
             result.addAll(mergeDropColumnStatement(dropColumnTokens, "", ""));
@@ -78,155 +82,125 @@ public final class EncryptAlterTableTokenGenerator implements CollectionSQLToken
         return result;
     }
     
-    private Collection<SQLToken> mergeDropColumnStatement(final List<SQLToken> dropSQLTokens, final String leftJoiner, final String rightJoiner) {
-        Collection<SQLToken> result = new LinkedList<>();
-        Collection<String> dropColumns = new LinkedList<>();
-        int lastStartIndex = -1;
-        for (int i = 0; i < dropSQLTokens.size(); i++) {
-            SQLToken token = dropSQLTokens.get(i);
-            if (token instanceof RemoveToken) {
-                result.add(0 == i ? token : new RemoveToken(lastStartIndex, ((RemoveToken) token).getStopIndex()));
-            } else {
-                EncryptAlterTableToken encryptAlterTableToken = (EncryptAlterTableToken) token;
-                dropColumns.add(encryptAlterTableToken.getColumnName());
-                if (i == dropSQLTokens.size() - 1) {
-                    result.add(new EncryptAlterTableToken(token.getStartIndex(), encryptAlterTableToken.getStopIndex(), leftJoiner + String.join(",", dropColumns) + rightJoiner, "DROP COLUMN"));
-                }
-            }
-            lastStartIndex = ((Substitutable) token).getStartIndex();
-        }
-        return result;
-    }
-    
-    private Collection<SQLToken> getAddColumnTokens(final String tableName, final Collection<AddColumnDefinitionSegment> columnDefinitionSegments) {
+    private Collection<SQLToken> getAddColumnTokens(final String tableName, final EncryptTable encryptTable, final Collection<AddColumnDefinitionSegment> columnDefinitionSegments) {
         Collection<SQLToken> result = new LinkedList<>();
         for (AddColumnDefinitionSegment each : columnDefinitionSegments) {
-            result.addAll(getAddColumnTokens(tableName, each));
+            result.addAll(getAddColumnTokens(tableName, encryptTable, each));
         }
         return result;
     }
     
     @SuppressWarnings("rawtypes")
-    private Collection<SQLToken> getAddColumnTokens(final String tableName, final AddColumnDefinitionSegment addColumnDefinitionSegment) {
+    private Collection<SQLToken> getAddColumnTokens(final String tableName, final EncryptTable encryptTable, final AddColumnDefinitionSegment addColumnDefinitionSegment) {
         Collection<SQLToken> result = new LinkedList<>();
         for (ColumnDefinitionSegment each : addColumnDefinitionSegment.getColumnDefinitions()) {
             String columnName = each.getColumnName().getIdentifier().getValue();
             Optional<StandardEncryptAlgorithm> encryptor = encryptRule.findStandardEncryptor(tableName, columnName);
             if (encryptor.isPresent()) {
-                result.addAll(getAddColumnTokens(tableName, columnName, addColumnDefinitionSegment, each));
+                result.addAll(getAddColumnTokens(encryptTable, columnName, addColumnDefinitionSegment, each));
             }
         }
-        getAddColumnPositionToken(tableName, addColumnDefinitionSegment).ifPresent(result::add);
+        getAddColumnPositionToken(tableName, encryptTable, addColumnDefinitionSegment).ifPresent(result::add);
         return result;
     }
     
-    private Collection<SQLToken> getAddColumnTokens(final String tableName, final String columnName,
+    private Collection<SQLToken> getAddColumnTokens(final EncryptTable encryptTable, final String columnName,
                                                     final AddColumnDefinitionSegment addColumnDefinitionSegment, final ColumnDefinitionSegment columnDefinitionSegment) {
         Collection<SQLToken> result = new LinkedList<>();
         result.add(new RemoveToken(columnDefinitionSegment.getStartIndex(), columnDefinitionSegment.getColumnName().getStopIndex()));
         result.add(new EncryptAlterTableToken(columnDefinitionSegment.getColumnName().getStopIndex() + 1, columnDefinitionSegment.getColumnName().getStopIndex(),
-                encryptRule.getCipherColumn(tableName, columnName), null));
-        Optional<String> assistedQueryColumn = encryptRule.findAssistedQueryColumn(tableName, columnName);
-        assistedQueryColumn.map(optional -> new EncryptAlterTableToken(
+                encryptTable.getCipherColumn(columnName), null));
+        encryptTable.findAssistedQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(
                 addColumnDefinitionSegment.getStopIndex() + 1, columnDefinitionSegment.getColumnName().getStopIndex(), optional, ", ADD COLUMN")).ifPresent(result::add);
-        Optional<String> likeQueryColumn = encryptRule.findLikeQueryColumn(tableName, columnName);
-        likeQueryColumn.map(optional -> new EncryptAlterTableToken(
+        encryptTable.findLikeQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(
                 addColumnDefinitionSegment.getStopIndex() + 1, columnDefinitionSegment.getColumnName().getStopIndex(), optional, ", ADD COLUMN")).ifPresent(result::add);
         return result;
     }
     
-    private EncryptColumn getEncryptColumn(final String tableName, final String columnName) {
-        return encryptRule.findEncryptTable(tableName).flatMap(optional -> optional.findEncryptColumn(columnName)).orElseThrow(() -> new EncryptColumnNotFoundException(tableName, columnName));
-    }
-    
     @SuppressWarnings("rawtypes")
-    private Optional<SQLToken> getAddColumnPositionToken(final String tableName, final AddColumnDefinitionSegment addColumnDefinitionSegment) {
+    private Optional<SQLToken> getAddColumnPositionToken(final String tableName, final EncryptTable encryptTable, final AddColumnDefinitionSegment addColumnDefinitionSegment) {
         Optional<StandardEncryptAlgorithm> encryptor = addColumnDefinitionSegment.getColumnPosition().filter(optional -> null != optional.getColumnName())
                 .flatMap(optional -> encryptRule.findStandardEncryptor(tableName, optional.getColumnName().getIdentifier().getValue()));
-        if (encryptor.isPresent()) {
-            return Optional.of(getPositionColumnToken(addColumnDefinitionSegment.getColumnPosition().get(), tableName));
-        }
-        return Optional.empty();
-    }
-    
-    private EncryptAlterTableToken getPositionColumnToken(final ColumnPositionSegment positionSegment, final String tableName) {
-        return new EncryptAlterTableToken(positionSegment.getColumnName().getStartIndex(), positionSegment.getStopIndex(), encryptRule
-                .getCipherColumn(tableName, positionSegment.getColumnName().getIdentifier().getValue()), null);
+        return encryptor.isPresent() ? Optional.of(getPositionColumnToken(encryptTable, addColumnDefinitionSegment.getColumnPosition().get())) : Optional.empty();
     }
     
     @SuppressWarnings("rawtypes")
-    private Collection<SQLToken> getModifyColumnTokens(final String tableName, final Collection<ModifyColumnDefinitionSegment> columnDefinitionSegments) {
+    private Collection<SQLToken> getModifyColumnTokens(final String tableName, final EncryptTable encryptTable, final Collection<ModifyColumnDefinitionSegment> columnDefinitionSegments) {
         Collection<SQLToken> result = new LinkedList<>();
         for (ModifyColumnDefinitionSegment each : columnDefinitionSegments) {
-            ColumnDefinitionSegment segment = each.getColumnDefinition();
-            String columnName = segment.getColumnName().getIdentifier().getValue();
+            String columnName = each.getColumnDefinition().getColumnName().getIdentifier().getValue();
             Optional<StandardEncryptAlgorithm> encryptor = encryptRule.findStandardEncryptor(tableName, columnName);
             if (encryptor.isPresent()) {
-                result.addAll(getModifyColumnTokens(tableName, columnName, each));
+                result.addAll(getModifyColumnTokens(encryptTable, columnName, each));
             }
-            each.getColumnPosition().flatMap(optional -> getColumnPositionToken(tableName, optional)).ifPresent(result::add);
+            each.getColumnPosition().flatMap(optional -> getColumnPositionToken(tableName, encryptTable, optional)).ifPresent(result::add);
         }
         return result;
     }
     
-    private Collection<SQLToken> getModifyColumnTokens(final String tableName, final String columnName,
-                                                       final ModifyColumnDefinitionSegment modifyColumnDefinitionSegment) {
+    private Collection<SQLToken> getModifyColumnTokens(final EncryptTable encryptTable, final String columnName, final ModifyColumnDefinitionSegment modifyColumnDefinitionSegment) {
         Collection<SQLToken> result = new LinkedList<>();
         ColumnDefinitionSegment columnDefinitionSegment = modifyColumnDefinitionSegment.getColumnDefinition();
         result.add(new RemoveToken(columnDefinitionSegment.getColumnName().getStartIndex(), columnDefinitionSegment.getColumnName().getStopIndex()));
         result.add(new EncryptAlterTableToken(columnDefinitionSegment.getColumnName().getStopIndex() + 1, columnDefinitionSegment.getColumnName().getStopIndex(),
-                encryptRule.getCipherColumn(tableName, columnName), null));
-        encryptRule.findAssistedQueryColumn(tableName, columnName).map(optional -> new EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1,
+                encryptTable.getCipherColumn(columnName), null));
+        encryptTable.findAssistedQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1,
                 columnDefinitionSegment.getColumnName().getStopIndex(), optional, ", MODIFY COLUMN")).ifPresent(result::add);
-        encryptRule.findLikeQueryColumn(tableName, columnName).map(optional -> new EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1,
+        encryptTable.findLikeQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1,
                 columnDefinitionSegment.getColumnName().getStopIndex(), optional, ", MODIFY COLUMN")).ifPresent(result::add);
         return result;
     }
     
+    private EncryptAlterTableToken getPositionColumnToken(final EncryptTable encryptTable, final ColumnPositionSegment positionSegment) {
+        return new EncryptAlterTableToken(positionSegment.getColumnName().getStartIndex(), positionSegment.getStopIndex(),
+                encryptTable.getCipherColumn(positionSegment.getColumnName().getIdentifier().getValue()), null);
+    }
+    
     @SuppressWarnings("rawtypes")
-    private Optional<SQLToken> getColumnPositionToken(final String tableName, final ColumnPositionSegment columnPositionSegment) {
+    private Optional<SQLToken> getColumnPositionToken(final String tableName, final EncryptTable encryptTable, final ColumnPositionSegment columnPositionSegment) {
         Optional<StandardEncryptAlgorithm> encryptor = Optional.of(columnPositionSegment).filter(optional -> null != optional.getColumnName())
                 .flatMap(optional -> encryptRule.findStandardEncryptor(tableName, optional.getColumnName().getIdentifier().getValue()));
-        return encryptor.isPresent() ? Optional.of(getPositionColumnToken(columnPositionSegment, tableName)) : Optional.empty();
+        return encryptor.isPresent() ? Optional.of(getPositionColumnToken(encryptTable, columnPositionSegment)) : Optional.empty();
     }
     
-    private Collection<SQLToken> getChangeColumnTokens(final String tableName, final Collection<ChangeColumnDefinitionSegment> changeColumnDefinitions) {
+    private Collection<SQLToken> getChangeColumnTokens(final String tableName, final EncryptTable encryptTable, final Collection<ChangeColumnDefinitionSegment> changeColumnDefinitions) {
         Collection<SQLToken> result = new LinkedList<>();
         for (ChangeColumnDefinitionSegment each : changeColumnDefinitions) {
-            result.addAll(getChangeColumnTokensEach(tableName, each));
-            each.getColumnPosition().flatMap(optional -> getColumnPositionToken(tableName, optional)).ifPresent(result::add);
+            result.addAll(getChangeColumnTokens(tableName, encryptTable, each));
+            each.getColumnPosition().flatMap(optional -> getColumnPositionToken(tableName, encryptTable, optional)).ifPresent(result::add);
         }
         return result;
     }
     
-    private Collection<? extends SQLToken> getChangeColumnTokensEach(final String tableName, final ChangeColumnDefinitionSegment segment) {
-        isSameEncryptColumn(tableName, segment);
+    private Collection<? extends SQLToken> getChangeColumnTokens(final String tableName, final EncryptTable encryptTable, final ChangeColumnDefinitionSegment segment) {
+        isSameEncryptColumn(tableName, encryptTable, segment);
         if (!encryptRule.findStandardEncryptor(tableName, segment.getPreviousColumn().getIdentifier().getValue()).isPresent()
                 || !encryptRule.findStandardEncryptor(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue()).isPresent()) {
             return Collections.emptyList();
         }
         Collection<SQLToken> result = new LinkedList<>();
-        result.addAll(getPreviousColumnTokens(tableName, segment));
-        result.addAll(getColumnTokens(tableName, segment));
+        result.addAll(getPreviousColumnTokens(encryptTable, segment));
+        result.addAll(getColumnTokens(encryptTable, segment));
         return result;
     }
     
     @SuppressWarnings("rawtypes")
-    private void isSameEncryptColumn(final String tableName, final ChangeColumnDefinitionSegment segment) {
+    private void isSameEncryptColumn(final String tableName, final EncryptTable encryptTable, final ChangeColumnDefinitionSegment segment) {
         Optional<StandardEncryptAlgorithm> previousAlgorithm = encryptRule.findStandardEncryptor(tableName, segment.getPreviousColumn().getIdentifier().getValue());
         Optional<StandardEncryptAlgorithm> currentAlgorithm = encryptRule.findStandardEncryptor(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue());
         if (!previousAlgorithm.isPresent() && !currentAlgorithm.isPresent()) {
             return;
         }
-        if (previousAlgorithm.isPresent() && currentAlgorithm.isPresent() && previousAlgorithm.get().equals(currentAlgorithm.get()) && checkPreviousAndAfterHasSameColumnNumber(tableName, segment)) {
+        if (previousAlgorithm.isPresent()
+                && currentAlgorithm.isPresent() && previousAlgorithm.get().equals(currentAlgorithm.get()) && checkPreviousAndAfterHasSameColumnNumber(encryptTable, segment)) {
             return;
         }
         throw new EncryptColumnAlterException(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue(), segment.getPreviousColumn().getIdentifier().getValue());
     }
     
-    private boolean checkPreviousAndAfterHasSameColumnNumber(final String tableName, final ChangeColumnDefinitionSegment segment) {
-        EncryptColumn previousColumn = getEncryptColumn(tableName, segment.getPreviousColumn().getIdentifier().getValue());
-        EncryptColumn currentColumn = getEncryptColumn(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue());
+    private boolean checkPreviousAndAfterHasSameColumnNumber(final EncryptTable encryptTable, final ChangeColumnDefinitionSegment changeColumnDefinitionSegment) {
+        EncryptColumn previousColumn = encryptTable.getEncryptColumn(changeColumnDefinitionSegment.getPreviousColumn().getIdentifier().getValue());
+        EncryptColumn currentColumn = encryptTable.getEncryptColumn(changeColumnDefinitionSegment.getColumnDefinition().getColumnName().getIdentifier().getValue());
         if (previousColumn.getAssistedQuery().isPresent() && !currentColumn.getAssistedQuery().isPresent()) {
             return false;
         }
@@ -236,62 +210,82 @@ public final class EncryptAlterTableTokenGenerator implements CollectionSQLToken
         return previousColumn.getAssistedQuery().isPresent() || !currentColumn.getAssistedQuery().isPresent();
     }
     
-    private Collection<? extends SQLToken> getColumnTokens(final String tableName, final ChangeColumnDefinitionSegment segment) {
+    private Collection<? extends SQLToken> getColumnTokens(final EncryptTable encryptTable, final ChangeColumnDefinitionSegment segment) {
         Collection<SQLToken> result = new LinkedList<>();
         result.add(new RemoveToken(segment.getColumnDefinition().getColumnName().getStartIndex(), segment.getColumnDefinition().getColumnName().getStopIndex()));
         result.add(new EncryptAlterTableToken(segment.getColumnDefinition().getColumnName().getStopIndex() + 1, segment.getColumnDefinition().getColumnName().getStopIndex(),
-                encryptRule.getCipherColumn(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue()), null));
+                encryptTable.getCipherColumn(segment.getColumnDefinition().getColumnName().getIdentifier().getValue()), null));
         String previousColumnName = segment.getPreviousColumn().getIdentifier().getValue();
-        EncryptColumn encryptColumn = getEncryptColumn(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue());
-        encryptRule.findAssistedQueryColumn(tableName, previousColumnName)
+        EncryptColumn encryptColumn = encryptTable.getEncryptColumn(segment.getColumnDefinition().getColumnName().getIdentifier().getValue());
+        encryptTable.findAssistedQueryColumn(previousColumnName)
                 .map(optional -> new EncryptAlterTableToken(segment.getStopIndex() + 1, segment.getColumnDefinition().getColumnName().getStopIndex(),
                         encryptColumn.getAssistedQuery().map(EncryptColumnItem::getName).orElse(""), ", CHANGE COLUMN " + optional))
                 .ifPresent(result::add);
-        encryptRule.findLikeQueryColumn(tableName, previousColumnName)
+        encryptTable.findLikeQueryColumn(previousColumnName)
                 .map(optional -> new EncryptAlterTableToken(segment.getStopIndex() + 1, segment.getColumnDefinition().getColumnName().getStopIndex(),
                         encryptColumn.getLikeQuery().map(EncryptColumnItem::getName).orElse(""), ", CHANGE COLUMN " + optional))
                 .ifPresent(result::add);
         return result;
     }
     
-    private Collection<? extends SQLToken> getPreviousColumnTokens(final String tableName, final ChangeColumnDefinitionSegment segment) {
+    private Collection<? extends SQLToken> getPreviousColumnTokens(final EncryptTable encryptTable, final ChangeColumnDefinitionSegment segment) {
         Collection<SQLToken> result = new LinkedList<>();
         result.add(new RemoveToken(segment.getPreviousColumn().getStartIndex(), segment.getPreviousColumn().getStopIndex()));
         result.add(new EncryptAlterTableToken(segment.getPreviousColumn().getStopIndex() + 1, segment.getPreviousColumn().getStopIndex(),
-                encryptRule.getCipherColumn(tableName, segment.getPreviousColumn().getIdentifier().getValue()), null));
+                encryptTable.getCipherColumn(segment.getPreviousColumn().getIdentifier().getValue()), null));
         return result;
     }
     
-    private List<SQLToken> getDropColumnTokens(final String tableName, final Collection<DropColumnDefinitionSegment> columnDefinitionSegments) {
+    private List<SQLToken> getDropColumnTokens(final String tableName, final EncryptTable encryptTable, final Collection<DropColumnDefinitionSegment> columnDefinitionSegments) {
         List<SQLToken> result = new ArrayList<>();
         for (DropColumnDefinitionSegment each : columnDefinitionSegments) {
-            result.addAll(getDropColumnTokens(tableName, each));
+            result.addAll(getDropColumnTokens(tableName, encryptTable, each));
         }
         return result;
     }
     
     @SuppressWarnings("rawtypes")
-    private Collection<SQLToken> getDropColumnTokens(final String tableName, final DropColumnDefinitionSegment dropColumnDefinitionSegment) {
+    private Collection<SQLToken> getDropColumnTokens(final String tableName, final EncryptTable encryptTable, final DropColumnDefinitionSegment dropColumnDefinitionSegment) {
         Collection<SQLToken> result = new LinkedList<>();
         for (ColumnSegment each : dropColumnDefinitionSegment.getColumns()) {
             String columnName = each.getQualifiedName();
             Optional<StandardEncryptAlgorithm> encryptor = encryptRule.findStandardEncryptor(tableName, columnName);
             if (encryptor.isPresent()) {
-                result.addAll(getDropColumnTokens(tableName, columnName, each, dropColumnDefinitionSegment));
+                result.addAll(getDropColumnTokens(encryptTable, columnName, each, dropColumnDefinitionSegment));
             }
         }
         return result;
     }
     
-    private Collection<SQLToken> getDropColumnTokens(final String tableName, final String columnName,
+    private Collection<SQLToken> getDropColumnTokens(final EncryptTable encryptTable, final String columnName,
                                                      final ColumnSegment columnSegment, final DropColumnDefinitionSegment dropColumnDefinitionSegment) {
         Collection<SQLToken> result = new LinkedList<>();
         result.add(new RemoveToken(columnSegment.getStartIndex(), columnSegment.getStopIndex()));
-        result.add(new EncryptAlterTableToken(columnSegment.getStopIndex() + 1, columnSegment.getStopIndex(), encryptRule.getCipherColumn(tableName, columnName), null));
-        encryptRule.findAssistedQueryColumn(tableName, columnName).map(optional -> new EncryptAlterTableToken(dropColumnDefinitionSegment.getStopIndex() + 1,
+        result.add(new EncryptAlterTableToken(columnSegment.getStopIndex() + 1, columnSegment.getStopIndex(), encryptTable.getCipherColumn(columnName), null));
+        encryptTable.findAssistedQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(dropColumnDefinitionSegment.getStopIndex() + 1,
                 dropColumnDefinitionSegment.getStopIndex(), optional, ", DROP COLUMN")).ifPresent(result::add);
-        encryptRule.findLikeQueryColumn(tableName, columnName).map(optional -> new EncryptAlterTableToken(dropColumnDefinitionSegment.getStopIndex() + 1,
+        encryptTable.findLikeQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(dropColumnDefinitionSegment.getStopIndex() + 1,
                 dropColumnDefinitionSegment.getStopIndex(), optional, ", DROP COLUMN")).ifPresent(result::add);
         return result;
     }
+    
+    private Collection<SQLToken> mergeDropColumnStatement(final List<SQLToken> dropSQLTokens, final String leftJoiner, final String rightJoiner) {
+        Collection<SQLToken> result = new LinkedList<>();
+        Collection<String> dropColumns = new LinkedList<>();
+        int lastStartIndex = -1;
+        for (int i = 0; i < dropSQLTokens.size(); i++) {
+            SQLToken token = dropSQLTokens.get(i);
+            if (token instanceof RemoveToken) {
+                result.add(0 == i ? token : new RemoveToken(lastStartIndex, ((RemoveToken) token).getStopIndex()));
+            } else {
+                EncryptAlterTableToken encryptAlterTableToken = (EncryptAlterTableToken) token;
+                dropColumns.add(encryptAlterTableToken.getColumnName());
+                if (i == dropSQLTokens.size() - 1) {
+                    result.add(new EncryptAlterTableToken(token.getStartIndex(), encryptAlterTableToken.getStopIndex(), leftJoiner + String.join(",", dropColumns) + rightJoiner, "DROP COLUMN"));
+                }
+            }
+            lastStartIndex = ((Substitutable) token).getStartIndex();
+        }
+        return result;
+    }
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
index c63a6f664e6..9f6fc0098a0 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.encrypt.rule;
 
 import org.apache.shardingsphere.encrypt.api.config.rule.EncryptColumnRuleConfiguration;
 import org.apache.shardingsphere.encrypt.api.config.rule.EncryptTableRuleConfiguration;
+import org.apache.shardingsphere.encrypt.exception.metadata.EncryptColumnNotFoundException;
 import org.apache.shardingsphere.encrypt.exception.metadata.EncryptLogicColumnNotFoundException;
 
 import java.util.Collection;
@@ -33,9 +34,12 @@ import java.util.TreeMap;
  */
 public final class EncryptTable {
     
+    private final String table;
+    
     private final Map<String, EncryptColumn> columns;
     
     public EncryptTable(final EncryptTableRuleConfiguration config) {
+        table = config.getName();
         columns = createEncryptColumns(config);
     }
     
@@ -209,4 +213,13 @@ public final class EncryptTable {
         return Optional.ofNullable(columns.get(logicColumnName));
     }
     
+    /**
+     * Get encrypt column.
+     * 
+     * @param logicColumnName logic column name
+     * @return encrypt column
+     */
+    public EncryptColumn getEncryptColumn(final String logicColumnName) {
+        return findEncryptColumn(logicColumnName).orElseThrow(() -> new EncryptColumnNotFoundException(table, logicColumnName));
+    }
 }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptAlterTableTokenGeneratorTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptAlterTableTokenGeneratorTest.java
index da7f629c485..256f09c3981 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptAlterTableTokenGeneratorTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptAlterTableTokenGeneratorTest.java
@@ -51,28 +51,32 @@ import static org.mockito.Mockito.when;
 
 class EncryptAlterTableTokenGeneratorTest {
     
-    private EncryptAlterTableTokenGenerator generator;
+    private final EncryptAlterTableTokenGenerator generator = new EncryptAlterTableTokenGenerator();
     
     @BeforeEach
     void setup() {
-        generator = new EncryptAlterTableTokenGenerator();
         generator.setEncryptRule(mockEncryptRule());
     }
     
     private EncryptRule mockEncryptRule() {
         EncryptRule result = mock(EncryptRule.class);
-        when(result.getCipherColumn("t_encrypt", "certificate_number")).thenReturn("cipher_certificate_number");
-        when(result.findAssistedQueryColumn("t_encrypt", "certificate_number")).thenReturn(Optional.of("assisted_certificate_number"));
-        when(result.findLikeQueryColumn("t_encrypt", "certificate_number")).thenReturn(Optional.of("like_certificate_number"));
-        EncryptTable encryptTable = mock(EncryptTable.class);
-        when(encryptTable.getLogicColumns()).thenReturn(Collections.singleton("t_encrypt"));
-        when(encryptTable.findEncryptColumn("certificate_number")).thenReturn(Optional.of(mockEncryptColumn()));
-        when(encryptTable.findEncryptColumn("certificate_number_new")).thenReturn(Optional.of(mockNewEncryptColumn()));
+        EncryptTable encryptTable = mockEncryptTable();
+        when(result.findEncryptTable("t_encrypt")).thenReturn(Optional.of(encryptTable));
         StandardEncryptAlgorithm<?, ?> encryptAlgorithm = mock(StandardEncryptAlgorithm.class);
         when(result.findStandardEncryptor("t_encrypt", "certificate_number")).thenReturn(Optional.of(encryptAlgorithm));
         when(result.findStandardEncryptor("t_encrypt", "certificate_number_new")).thenReturn(Optional.of(encryptAlgorithm));
-        when(result.findEncryptTable("t_encrypt")).thenReturn(Optional.of(encryptTable));
-        when(result.getCipherColumn("t_encrypt", "certificate_number_new")).thenReturn("cipher_certificate_number_new");
+        return result;
+    }
+    
+    private EncryptTable mockEncryptTable() {
+        EncryptTable result = mock(EncryptTable.class);
+        when(result.getCipherColumn("certificate_number")).thenReturn("cipher_certificate_number");
+        when(result.findAssistedQueryColumn("certificate_number")).thenReturn(Optional.of("assisted_certificate_number"));
+        when(result.findLikeQueryColumn("certificate_number")).thenReturn(Optional.of("like_certificate_number"));
+        when(result.getLogicColumns()).thenReturn(Collections.singleton("t_encrypt"));
+        when(result.getEncryptColumn("certificate_number")).thenReturn(mockEncryptColumn());
+        when(result.getCipherColumn("certificate_number_new")).thenReturn("cipher_certificate_number_new");
+        when(result.getEncryptColumn("certificate_number_new")).thenReturn(mockNewEncryptColumn());
         return result;
     }
     
@@ -92,92 +96,93 @@ class EncryptAlterTableTokenGeneratorTest {
     
     @Test
     void assertAddColumnGenerateSQLTokens() {
-        Collection<SQLToken> sqlTokens = generator.generateSQLTokens(buildAddColumnStatementContext());
-        assertThat(sqlTokens.size(), is(4));
-        Iterator<SQLToken> iterator = sqlTokens.iterator();
-        assertThat(iterator.next(), instanceOf(RemoveToken.class));
-        EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) iterator.next();
+        Collection<SQLToken> actual = generator.generateSQLTokens(mockAddColumnStatementContext());
+        assertThat(actual.size(), is(4));
+        Iterator<SQLToken> actualIterator = actual.iterator();
+        assertThat(actualIterator.next(), instanceOf(RemoveToken.class));
+        EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(cipherToken.toString(), is("cipher_certificate_number"));
         assertThat(cipherToken.getStartIndex(), is(51));
         assertThat(cipherToken.getStopIndex(), is(50));
-        EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) iterator.next();
+        EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(assistedToken.toString(), is(", ADD COLUMN assisted_certificate_number"));
         assertThat(assistedToken.getStartIndex(), is(68));
         assertThat(assistedToken.getStopIndex(), is(50));
-        EncryptAlterTableToken likeToken = (EncryptAlterTableToken) iterator.next();
+        EncryptAlterTableToken likeToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(likeToken.toString(), is(", ADD COLUMN like_certificate_number"));
         assertThat(likeToken.getStartIndex(), is(68));
         assertThat(likeToken.getStopIndex(), is(50));
     }
     
-    private AlterTableStatementContext buildAddColumnStatementContext() {
+    private AlterTableStatementContext mockAddColumnStatementContext() {
         AlterTableStatementContext result = mock(AlterTableStatementContext.class, RETURNS_DEEP_STUBS);
         when(result.getSqlStatement().getTable().getTableName().getIdentifier().getValue()).thenReturn("t_encrypt");
-        ColumnDefinitionSegment segment = new ColumnDefinitionSegment(33, 67, new ColumnSegment(33, 50, new IdentifierValue("certificate_number")), new DataTypeSegment(), false, false);
-        AddColumnDefinitionSegment addColumnDefinitionSegment = new AddColumnDefinitionSegment(22, 67, Collections.singletonList(segment));
-        when(result.getSqlStatement().getAddColumnDefinitions()).thenReturn(Collections.singletonList(addColumnDefinitionSegment));
+        ColumnDefinitionSegment columnDefinitionSegment = new ColumnDefinitionSegment(
+                33, 67, new ColumnSegment(33, 50, new IdentifierValue("certificate_number")), new DataTypeSegment(), false, false);
+        when(result.getSqlStatement().getAddColumnDefinitions()).thenReturn(Collections.singleton(new AddColumnDefinitionSegment(22, 67, Collections.singleton(columnDefinitionSegment))));
         return result;
     }
     
     @Test
     void assertModifyColumnGenerateSQLTokens() {
-        Collection<SQLToken> sqlTokens = generator.generateSQLTokens(buildModifyColumnStatementContext());
-        assertThat(sqlTokens.size(), is(4));
-        Iterator<SQLToken> iterator = sqlTokens.iterator();
-        assertThat(iterator.next(), instanceOf(RemoveToken.class));
-        EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) iterator.next();
+        Collection<SQLToken> actual = generator.generateSQLTokens(mockModifyColumnStatementContext());
+        assertThat(actual.size(), is(4));
+        Iterator<SQLToken> actualIterator = actual.iterator();
+        assertThat(actualIterator.next(), instanceOf(RemoveToken.class));
+        EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(cipherToken.toString(), is("cipher_certificate_number"));
         assertThat(cipherToken.getStartIndex(), is(54));
         assertThat(cipherToken.getStopIndex(), is(53));
-        EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) iterator.next();
+        EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(assistedToken.toString(), is(", MODIFY COLUMN assisted_certificate_number"));
         assertThat(assistedToken.getStartIndex(), is(71));
         assertThat(assistedToken.getStopIndex(), is(53));
-        EncryptAlterTableToken likeToken = (EncryptAlterTableToken) iterator.next();
+        EncryptAlterTableToken likeToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(likeToken.toString(), is(", MODIFY COLUMN like_certificate_number"));
         assertThat(likeToken.getStartIndex(), is(71));
         assertThat(likeToken.getStopIndex(), is(53));
     }
     
-    private AlterTableStatementContext buildModifyColumnStatementContext() {
+    private AlterTableStatementContext mockModifyColumnStatementContext() {
         AlterTableStatementContext result = mock(AlterTableStatementContext.class, RETURNS_DEEP_STUBS);
         when(result.getSqlStatement().getTable().getTableName().getIdentifier().getValue()).thenReturn("t_encrypt");
-        ColumnDefinitionSegment segment = new ColumnDefinitionSegment(36, 70, new ColumnSegment(36, 53, new IdentifierValue("certificate_number")), new DataTypeSegment(), false, false);
-        ModifyColumnDefinitionSegment modifyColumnDefinitionSegment = new ModifyColumnDefinitionSegment(22, 70, segment);
-        when(result.getSqlStatement().getModifyColumnDefinitions()).thenReturn(Collections.singletonList(modifyColumnDefinitionSegment));
+        ColumnDefinitionSegment columnDefinitionSegment = new ColumnDefinitionSegment(
+                36, 70, new ColumnSegment(36, 53, new IdentifierValue("certificate_number")), new DataTypeSegment(), false, false);
+        when(result.getSqlStatement().getModifyColumnDefinitions()).thenReturn(Collections.singleton(new ModifyColumnDefinitionSegment(22, 70, columnDefinitionSegment)));
         return result;
     }
     
     @Test
     void assertChangeColumnGenerateSQLTokens() {
-        Collection<SQLToken> sqlTokens = generator.generateSQLTokens(buildChangeColumnStatementContext());
-        assertThat(sqlTokens.size(), is(6));
-        Iterator<SQLToken> iterator = sqlTokens.iterator();
-        assertThat(iterator.next(), instanceOf(RemoveToken.class));
-        EncryptAlterTableToken previous = (EncryptAlterTableToken) iterator.next();
+        Collection<SQLToken> actual = generator.generateSQLTokens(mockChangeColumnStatementContext());
+        assertThat(actual.size(), is(6));
+        Iterator<SQLToken> actualIterator = actual.iterator();
+        assertThat(actualIterator.next(), instanceOf(RemoveToken.class));
+        EncryptAlterTableToken previous = (EncryptAlterTableToken) actualIterator.next();
         assertThat(previous.toString(), is("cipher_certificate_number"));
-        assertThat(iterator.next(), instanceOf(RemoveToken.class));
-        EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) iterator.next();
+        assertThat(actualIterator.next(), instanceOf(RemoveToken.class));
+        EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(cipherToken.toString(), is("cipher_certificate_number_new"));
         assertThat(cipherToken.getStartIndex(), is(77));
         assertThat(cipherToken.getStopIndex(), is(76));
-        EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) iterator.next();
+        EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(assistedToken.toString(), is(", CHANGE COLUMN assisted_certificate_number assisted_certificate_number_new"));
         assertThat(assistedToken.getStartIndex(), is(94));
         assertThat(assistedToken.getStopIndex(), is(76));
-        EncryptAlterTableToken likeToken = (EncryptAlterTableToken) iterator.next();
+        EncryptAlterTableToken likeToken = (EncryptAlterTableToken) actualIterator.next();
         assertThat(likeToken.toString(), is(", CHANGE COLUMN like_certificate_number like_certificate_number_new"));
         assertThat(likeToken.getStartIndex(), is(94));
         assertThat(likeToken.getStopIndex(), is(76));
     }
     
-    private AlterTableStatementContext buildChangeColumnStatementContext() {
+    private AlterTableStatementContext mockChangeColumnStatementContext() {
         AlterTableStatementContext result = mock(AlterTableStatementContext.class, RETURNS_DEEP_STUBS);
         when(result.getSqlStatement().getTable().getTableName().getIdentifier().getValue()).thenReturn("t_encrypt");
-        ColumnDefinitionSegment segment = new ColumnDefinitionSegment(55, 93, new ColumnSegment(55, 76, new IdentifierValue("certificate_number_new")), new DataTypeSegment(), false, false);
-        ChangeColumnDefinitionSegment changeColumnDefinitionSegment = new ChangeColumnDefinitionSegment(22, 93, segment);
+        ColumnDefinitionSegment columnDefinitionSegment = new ColumnDefinitionSegment(
+                55, 93, new ColumnSegment(55, 76, new IdentifierValue("certificate_number_new")), new DataTypeSegment(), false, false);
+        ChangeColumnDefinitionSegment changeColumnDefinitionSegment = new ChangeColumnDefinitionSegment(22, 93, columnDefinitionSegment);
         changeColumnDefinitionSegment.setPreviousColumn(new ColumnSegment(36, 53, new IdentifierValue("certificate_number")));
-        when(result.getSqlStatement().getChangeColumnDefinitions()).thenReturn(Collections.singletonList(changeColumnDefinitionSegment));
+        when(result.getSqlStatement().getChangeColumnDefinitions()).thenReturn(Collections.singleton(changeColumnDefinitionSegment));
         return result;
     }
 }