You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/10/21 04:43:41 UTC

[shardingsphere] branch master updated: add the fuzzyQueryColumn and fuzzyQueryEncryptorName (#21652)

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

duanzhengqiang 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 50ea61223a9 add the fuzzyQueryColumn and fuzzyQueryEncryptorName (#21652)
50ea61223a9 is described below

commit 50ea61223a9e30a692d2ae0be0f0746d439e8b18
Author: gxxiong <xi...@foxmail.com>
AuthorDate: Fri Oct 21 12:43:34 2022 +0800

    add the fuzzyQueryColumn and fuzzyQueryEncryptorName (#21652)
    
    Co-authored-by: gxxiong <xi...@yofc.com>
---
 .../rule/EncryptColumnRuleConfiguration.java       |  6 ++-
 .../shardingsphere/encrypt/rule/EncryptColumn.java | 20 +++++--
 .../shardingsphere/encrypt/rule/EncryptRule.java   | 62 ++++++++++++++++++++++
 .../shardingsphere/encrypt/rule/EncryptTable.java  | 39 +++++++++++++-
 .../rule/YamlEncryptColumnRuleConfiguration.java   |  4 ++
 .../YamlEncryptColumnRuleConfigurationSwapper.java |  8 +--
 ...rovidedEncryptRuleConfigurationCheckerTest.java | 21 +++++++-
 .../EncryptRuleConfigurationCheckerTest.java       | 21 +++++++-
 ...atedEncryptShowCreateTableMergedResultTest.java | 34 ++++++++++--
 ...rgedEncryptShowCreateTableMergedResultTest.java | 20 +++++--
 .../impl/EncryptAlterTableTokenGeneratorTest.java  |  4 +-
 .../impl/EncryptCreateTableTokenGeneratorTest.java |  3 +-
 .../impl/EncryptProjectionTokenGeneratorTest.java  |  2 +-
 .../token/generator/EncryptGeneratorBaseTest.java  |  3 +-
 .../encrypt/rule/EncryptColumnTest.java            |  9 +++-
 .../encrypt/rule/EncryptRuleTest.java              |  5 +-
 ...lEncryptColumnRuleConfigurationSwapperTest.java |  2 +
 ...mlEncryptTableRuleConfigurationSwapperTest.java |  2 +
 .../converter/EncryptRuleStatementConverter.java   |  2 +-
 .../parser/EncryptRuleBeanDefinitionParser.java    |  2 +
 .../tag/EncryptRuleBeanDefinitionTag.java          | 10 ++++
 .../main/resources/META-INF/namespace/encrypt.xsd  |  1 +
 22 files changed, 253 insertions(+), 27 deletions(-)

diff --git a/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/api/config/rule/EncryptColumnRuleConfiguration.java b/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/api/config/rule/EncryptColumnRuleConfiguration.java
index 740c102764e..3741f67c015 100644
--- a/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/api/config/rule/EncryptColumnRuleConfiguration.java
+++ b/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/api/config/rule/EncryptColumnRuleConfiguration.java
@@ -33,16 +33,20 @@ public final class EncryptColumnRuleConfiguration {
     
     private final String assistedQueryColumn;
     
+    private final String fuzzyQueryColumn;
+    
     private final String plainColumn;
     
     private final String encryptorName;
     
     private final String assistedQueryEncryptorName;
     
+    private final String fuzzyQueryEncryptorName;
+    
     private final Boolean queryWithCipherColumn;
     
     public EncryptColumnRuleConfiguration(final String logicColumn, final String cipherColumn, final String assistedQueryColumn, final String plainColumn,
                                           final String encryptorName, final Boolean queryWithCipherColumn) {
-        this(logicColumn, cipherColumn, assistedQueryColumn, plainColumn, encryptorName, null, queryWithCipherColumn);
+        this(logicColumn, cipherColumn, assistedQueryColumn, null, plainColumn, encryptorName, null, null, queryWithCipherColumn);
     }
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptColumn.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptColumn.java
index ce382462a11..5447be9c279 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptColumn.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptColumn.java
@@ -36,25 +36,39 @@ public final class EncryptColumn {
     
     private final String plainColumn;
     
+    private final String fuzzyQueryColumn;
+    
     private final String encryptorName;
     
     private final String assistedQueryEncryptorName;
     
+    private final String fuzzyQueryEncryptorName;
+    
     private final Boolean queryWithCipherColumn;
     
-    public EncryptColumn(final String cipherColumn, final String assistedQueryColumn, final String plainColumn, final String encryptorName, final Boolean queryWithCipherColumn) {
-        this(cipherColumn, assistedQueryColumn, plainColumn, encryptorName, null, queryWithCipherColumn);
+    public EncryptColumn(final String cipherColumn, final String assistedQueryColumn, final String fuzzyQueryColumn, final String plainColumn,
+                         final String encryptorName, final Boolean queryWithCipherColumn) {
+        this(cipherColumn, assistedQueryColumn, plainColumn, fuzzyQueryColumn, encryptorName, null, null, queryWithCipherColumn);
     }
     
     /**
      * Get assisted query column.
-     * 
+     *
      * @return assisted query column
      */
     public Optional<String> getAssistedQueryColumn() {
         return Strings.isNullOrEmpty(assistedQueryColumn) ? Optional.empty() : Optional.of(assistedQueryColumn);
     }
     
+    /**
+     * Get fuzzy query column.
+     *
+     * @return fuzzy query column
+     */
+    public Optional<String> getFuzzyQueryColumn() {
+        return Strings.isNullOrEmpty(fuzzyQueryColumn) ? Optional.empty() : Optional.of(fuzzyQueryColumn);
+    }
+    
     /**
      * Get plain column.
      *
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
index 69091b1777b..15738e5aa7b 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
@@ -116,6 +116,19 @@ public final class EncryptRule implements DatabaseRule, TableContainedRule {
         return tables.containsKey(lowerCaseLogicTable) ? tables.get(lowerCaseLogicTable).findAssistedQueryEncryptorName(logicColumn).map(encryptors::get) : Optional.empty();
     }
     
+    /**
+     * Find fuzzy encryptor.
+     *
+     * @param logicTable logic table name
+     * @param logicColumn logic column name
+     * @return encryptor
+     */
+    @SuppressWarnings("rawtypes")
+    public Optional<EncryptAlgorithm> findFuzzyQueryEncryptor(final String logicTable, final String logicColumn) {
+        String lowerCaseLogicTable = logicTable.toLowerCase();
+        return tables.containsKey(lowerCaseLogicTable) ? tables.get(lowerCaseLogicTable).findFuzzyQueryEncryptorName(logicColumn).map(encryptors::get) : Optional.empty();
+    }
+    
     /**
      * get encrypt values.
      *
@@ -178,6 +191,18 @@ public final class EncryptRule implements DatabaseRule, TableContainedRule {
         return tables.containsKey(lowerCaseLogicTable) ? tables.get(lowerCaseLogicTable).findAssistedQueryColumn(logicColumn) : Optional.empty();
     }
     
+    /**
+     * Find fuzzy query column.
+     *
+     * @param logicTable logic table name
+     * @param logicColumn column name
+     * @return fuzzy query column
+     */
+    public Optional<String> findFuzzyQueryColumn(final String logicTable, final String logicColumn) {
+        String lowerCaseLogicTable = logicTable.toLowerCase();
+        return tables.containsKey(lowerCaseLogicTable) ? tables.get(lowerCaseLogicTable).findFuzzyQueryColumn(logicColumn) : Optional.empty();
+    }
+    
     /**
      * Get assisted query columns.
      * 
@@ -188,6 +213,16 @@ public final class EncryptRule implements DatabaseRule, TableContainedRule {
         return tables.containsKey(logicTable.toLowerCase()) ? tables.get(logicTable.toLowerCase()).getAssistedQueryColumns() : Collections.emptyList();
     }
     
+    /**
+     * Get fuzzy query columns.
+     *
+     * @param logicTable logic table
+     * @return fuzzy query columns
+     */
+    public Collection<String> getFuzzyQueryColumns(final String logicTable) {
+        return tables.containsKey(logicTable.toLowerCase()) ? tables.get(logicTable.toLowerCase()).getFuzzyQueryColumns() : Collections.emptyList();
+    }
+    
     /**
      * Get encrypt assisted query values.
      *
@@ -215,6 +250,33 @@ public final class EncryptRule implements DatabaseRule, TableContainedRule {
         return result;
     }
     
+    /**
+     * Get encrypt fuzzy query values.
+     *
+     * @param databaseName database name
+     * @param schemaName schema name
+     * @param logicTable logic table
+     * @param logicColumn logic column
+     * @param originalValues original values
+     * @return fuzzy query values
+     */
+    @SuppressWarnings("rawtypes")
+    public List<Object> getEncryptFuzzyQueryValues(final String databaseName, final String schemaName, final String logicTable, final String logicColumn, final List<Object> originalValues) {
+        Optional<EncryptAlgorithm> encryptor = findFuzzyQueryEncryptor(logicTable, logicColumn);
+        EncryptContext encryptContext = EncryptContextBuilder.build(databaseName, schemaName, logicTable, logicColumn);
+        Preconditions.checkArgument(encryptor.isPresent(), "Can not find fuzzy encryptor by %s.%s.", logicTable, logicColumn);
+        return getEncryptFuzzyQueryValues(encryptor.get(), originalValues, encryptContext);
+    }
+    
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private List<Object> getEncryptFuzzyQueryValues(final EncryptAlgorithm encryptor, final List<Object> originalValues, final EncryptContext encryptContext) {
+        List<Object> result = new LinkedList<>();
+        for (Object each : originalValues) {
+            result.add(null == each ? null : encryptor.encrypt(each, encryptContext));
+        }
+        return result;
+    }
+    
     /**
      * Find plain column.
      *
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 acb46fcb476..21efea67956 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
@@ -41,8 +41,8 @@ public final class EncryptTable {
     public EncryptTable(final EncryptTableRuleConfiguration config) {
         columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
         for (EncryptColumnRuleConfiguration each : config.getColumns()) {
-            columns.put(each.getLogicColumn(), new EncryptColumn(each.getCipherColumn(), each.getAssistedQueryColumn(), each.getPlainColumn(), each.getEncryptorName(),
-                    each.getAssistedQueryEncryptorName(), each.getQueryWithCipherColumn()));
+            columns.put(each.getLogicColumn(), new EncryptColumn(each.getCipherColumn(), each.getAssistedQueryColumn(), each.getPlainColumn(), each.getFuzzyQueryColumn(),
+                    each.getEncryptorName(), each.getAssistedQueryEncryptorName(), each.getFuzzyQueryEncryptorName(), each.getQueryWithCipherColumn()));
         }
         queryWithCipherColumn = config.getQueryWithCipherColumn();
     }
@@ -67,6 +67,16 @@ public final class EncryptTable {
         return columns.containsKey(logicColumn) ? Optional.ofNullable(columns.get(logicColumn).getAssistedQueryEncryptorName()) : Optional.empty();
     }
     
+    /**
+     * Find fuzzy query encrypt algorithm name.
+     *
+     * @param logicColumn column name
+     * @return fuzzy encrypt  algorithm name
+     */
+    public Optional<String> findFuzzyQueryEncryptorName(final String logicColumn) {
+        return columns.containsKey(logicColumn) ? Optional.ofNullable(columns.get(logicColumn).getFuzzyQueryEncryptorName()) : Optional.empty();
+    }
+    
     /**
      * Get logic columns.
      *
@@ -141,6 +151,21 @@ public final class EncryptTable {
         return result;
     }
     
+    /**
+     * Get fuzzy query columns.
+     *
+     * @return fuzzy query columns
+     */
+    public Collection<String> getFuzzyQueryColumns() {
+        Collection<String> result = new LinkedList<>();
+        for (EncryptColumn each : columns.values()) {
+            if (each.getFuzzyQueryColumn().isPresent()) {
+                result.add(each.getFuzzyQueryColumn().get());
+            }
+        }
+        return result;
+    }
+    
     /**
      * Find assisted query column.
      *
@@ -151,6 +176,16 @@ public final class EncryptTable {
         return columns.containsKey(logicColumn) ? columns.get(logicColumn).getAssistedQueryColumn() : Optional.empty();
     }
     
+    /**
+     * Find fuzzy query column.
+     *
+     * @param logicColumn column name
+     * @return fuzzy query column
+     */
+    public Optional<String> findFuzzyQueryColumn(final String logicColumn) {
+        return columns.containsKey(logicColumn) ? columns.get(logicColumn).getFuzzyQueryColumn() : Optional.empty();
+    }
+    
     /**
      * Get plain columns.
      *
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/config/rule/YamlEncryptColumnRuleConfiguration.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/config/rule/YamlEncryptColumnRuleConfiguration.java
index f52bf5ace13..0b3a50f5d9c 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/config/rule/YamlEncryptColumnRuleConfiguration.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/config/rule/YamlEncryptColumnRuleConfiguration.java
@@ -34,11 +34,15 @@ public final class YamlEncryptColumnRuleConfiguration implements YamlConfigurati
     
     private String assistedQueryColumn;
     
+    private String fuzzyQueryColumn;
+    
     private String plainColumn;
     
     private String encryptorName;
     
     private String assistedQueryEncryptorName;
     
+    private String fuzzyQueryEncryptorName;
+    
     private Boolean queryWithCipherColumn;
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptColumnRuleConfigurationSwapper.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptColumnRuleConfigurationSwapper.java
index 339455068a7..b58dab43c0c 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptColumnRuleConfigurationSwapper.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptColumnRuleConfigurationSwapper.java
@@ -31,18 +31,20 @@ public final class YamlEncryptColumnRuleConfigurationSwapper implements YamlConf
         YamlEncryptColumnRuleConfiguration result = new YamlEncryptColumnRuleConfiguration();
         result.setLogicColumn(data.getLogicColumn());
         result.setPlainColumn(data.getPlainColumn());
+        result.setFuzzyQueryColumn(data.getFuzzyQueryColumn());
         result.setCipherColumn(data.getCipherColumn());
         result.setAssistedQueryColumn(data.getAssistedQueryColumn());
         result.setEncryptorName(data.getEncryptorName());
-        result.setQueryWithCipherColumn(data.getQueryWithCipherColumn());
         result.setAssistedQueryEncryptorName(data.getAssistedQueryEncryptorName());
+        result.setFuzzyQueryEncryptorName(data.getFuzzyQueryEncryptorName());
+        result.setQueryWithCipherColumn(data.getQueryWithCipherColumn());
         return result;
     }
     
     @Override
     public EncryptColumnRuleConfiguration swapToObject(final YamlEncryptColumnRuleConfiguration yamlConfig) {
         return new EncryptColumnRuleConfiguration(
-                yamlConfig.getLogicColumn(), yamlConfig.getCipherColumn(), yamlConfig.getAssistedQueryColumn(), yamlConfig.getPlainColumn(), yamlConfig.getEncryptorName(),
-                yamlConfig.getAssistedQueryEncryptorName(), yamlConfig.getQueryWithCipherColumn());
+                yamlConfig.getLogicColumn(), yamlConfig.getCipherColumn(), yamlConfig.getAssistedQueryColumn(), yamlConfig.getFuzzyQueryColumn(), yamlConfig.getPlainColumn(),
+                yamlConfig.getEncryptorName(), yamlConfig.getAssistedQueryEncryptorName(), yamlConfig.getFuzzyQueryEncryptorName(), yamlConfig.getQueryWithCipherColumn());
     }
 }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/AlgorithmProvidedEncryptRuleConfigurationCheckerTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/AlgorithmProvidedEncryptRuleConfigurationCheckerTest.java
index 18ae2e5fe1a..cc6d8fa7151 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/AlgorithmProvidedEncryptRuleConfigurationCheckerTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/AlgorithmProvidedEncryptRuleConfigurationCheckerTest.java
@@ -88,7 +88,26 @@ public final class AlgorithmProvidedEncryptRuleConfigurationCheckerTest {
         AlgorithmProvidedEncryptRuleConfiguration result = mock(AlgorithmProvidedEncryptRuleConfiguration.class);
         when(result.getEncryptors()).thenReturn(Collections.emptyMap());
         Collection<EncryptColumnRuleConfiguration> columns =
-                Collections.singletonList(new EncryptColumnRuleConfiguration("user_id", "user_cipher", "user_assisted", "user_plain", "aes_encryptor", "aes_assisted_encryptor", false));
+                Collections.singletonList(new EncryptColumnRuleConfiguration("user_id", "user_cipher", "user_assisted", "", "user_plain", "aes_encryptor", "aes_assisted_encryptor", null, false));
+        when(result.getTables()).thenReturn(Collections.singletonList(new EncryptTableRuleConfiguration("t_encrypt", columns, false)));
+        return result;
+    }
+    
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Test(expected = IllegalStateException.class)
+    public void assertCheckWhenConfigInvalidFuzzyColumn() {
+        AlgorithmProvidedEncryptRuleConfiguration config = createInvalidFuzzyColumnConfig();
+        Optional<RuleConfigurationChecker> checker = RuleConfigurationCheckerFactory.findInstance(config);
+        assertTrue(checker.isPresent());
+        assertThat(checker.get(), instanceOf(AlgorithmProvidedEncryptRuleConfigurationChecker.class));
+        checker.get().check("test", config, Collections.emptyMap(), Collections.emptyList());
+    }
+    
+    private AlgorithmProvidedEncryptRuleConfiguration createInvalidFuzzyColumnConfig() {
+        AlgorithmProvidedEncryptRuleConfiguration result = mock(AlgorithmProvidedEncryptRuleConfiguration.class);
+        when(result.getEncryptors()).thenReturn(Collections.emptyMap());
+        Collection<EncryptColumnRuleConfiguration> columns =
+                Collections.singletonList(new EncryptColumnRuleConfiguration("user_id", "user_cipher", "", "user_fuzzy", "user_plain", "aes_encryptor", null, "fuzzy_cn_encryptor", false));
         when(result.getTables()).thenReturn(Collections.singletonList(new EncryptTableRuleConfiguration("t_encrypt", columns, false)));
         return result;
     }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/EncryptRuleConfigurationCheckerTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/EncryptRuleConfigurationCheckerTest.java
index 93610c12960..6af9927ead6 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/EncryptRuleConfigurationCheckerTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/EncryptRuleConfigurationCheckerTest.java
@@ -87,7 +87,26 @@ public final class EncryptRuleConfigurationCheckerTest {
         EncryptRuleConfiguration result = mock(EncryptRuleConfiguration.class);
         when(result.getEncryptors()).thenReturn(Collections.emptyMap());
         Collection<EncryptColumnRuleConfiguration> columns =
-                Collections.singletonList(new EncryptColumnRuleConfiguration("user_id", "user_cipher", "user_assisted", "user_plain", "aes_encryptor", "aes_assisted_encryptor", false));
+                Collections.singletonList(new EncryptColumnRuleConfiguration("user_id", "user_cipher", "user_assisted", "", "user_plain", "aes_encryptor", "aes_assisted_encryptor", null, false));
+        when(result.getTables()).thenReturn(Collections.singletonList(new EncryptTableRuleConfiguration("t_encrypt", columns, false)));
+        return result;
+    }
+    
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Test(expected = IllegalStateException.class)
+    public void assertCheckWhenConfigInvalidFuzzyColumn() {
+        EncryptRuleConfiguration config = createInvalidFuzzyColumnConfig();
+        Optional<RuleConfigurationChecker> checker = RuleConfigurationCheckerFactory.findInstance(config);
+        assertTrue(checker.isPresent());
+        assertThat(checker.get(), instanceOf(EncryptRuleConfigurationChecker.class));
+        checker.get().check("test", config, Collections.emptyMap(), Collections.emptyList());
+    }
+    
+    private EncryptRuleConfiguration createInvalidFuzzyColumnConfig() {
+        EncryptRuleConfiguration result = mock(EncryptRuleConfiguration.class);
+        when(result.getEncryptors()).thenReturn(Collections.emptyMap());
+        Collection<EncryptColumnRuleConfiguration> columns =
+                Collections.singletonList(new EncryptColumnRuleConfiguration("user_id", "user_cipher", "", "user_fuzzy", "user_plain", "aes_encryptor", null, "fuzzy_cn_encryptor", false));
         when(result.getTables()).thenReturn(Collections.singletonList(new EncryptTableRuleConfiguration("t_encrypt", columns, false)));
         return result;
     }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResultTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResultTest.java
index c1bfa4cdd8d..454b6fefb8f 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResultTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/DecoratedEncryptShowCreateTableMergedResultTest.java
@@ -65,7 +65,7 @@ public final class DecoratedEncryptShowCreateTableMergedResultTest {
                 "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, "
                         + "`user_id` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
         DecoratedEncryptShowCreateTableMergedResult actual =
-                createDecoratedEncryptShowCreateTableMergedResult(mergedResult, mockEncryptRule(new EncryptColumn("user_id_cipher", null, "user_id", null, false)));
+                createDecoratedEncryptShowCreateTableMergedResult(mergedResult, mockEncryptRule(new EncryptColumn("user_id_cipher", null, null, "user_id", null, false)));
         assertTrue(actual.next());
         assertThat(actual.getValue(2, String.class),
                 is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
@@ -78,12 +78,26 @@ public final class DecoratedEncryptShowCreateTableMergedResultTest {
                 "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, "
                         + "`user_id_assisted` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
         DecoratedEncryptShowCreateTableMergedResult actual =
-                createDecoratedEncryptShowCreateTableMergedResult(mergedResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "user_id_assisted", null, null, false)));
+                createDecoratedEncryptShowCreateTableMergedResult(mergedResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "user_id_assisted", "", null, null, false)));
         assertTrue(actual.next());
         assertThat(actual.getValue(2, String.class),
                 is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
     }
     
+    @Test
+    public void assertGetValueWhenConfigFuzzyQueryColumn() throws SQLException {
+        when(mergedResult.next()).thenReturn(true).thenReturn(false);
+        when(mergedResult.getValue(2, String.class)).thenReturn(
+                "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, "
+                        + "`user_id_fuzzy` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
+        DecoratedEncryptShowCreateTableMergedResult actual =
+                createDecoratedEncryptShowCreateTableMergedResult(mergedResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "", "user_id_fuzzy", null, null, false)));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(2, String.class),
+                is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `user_id_fuzzy` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL,"
+                        + " PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
+    }
+    
     @Test
     public void assertGetValueWhenConfigPlainColumnAndAssistedQueryColumn() throws SQLException {
         when(mergedResult.next()).thenReturn(true).thenReturn(false);
@@ -91,12 +105,26 @@ public final class DecoratedEncryptShowCreateTableMergedResultTest {
                 "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, `user_id` VARCHAR(100) NOT NULL, "
                         + "`user_id_assisted` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
         DecoratedEncryptShowCreateTableMergedResult actual =
-                createDecoratedEncryptShowCreateTableMergedResult(mergedResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "user_id_assisted", "user_id", null, false)));
+                createDecoratedEncryptShowCreateTableMergedResult(mergedResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "user_id_assisted", "", "user_id", null, false)));
         assertTrue(actual.next());
         assertThat(actual.getValue(2, String.class),
                 is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
     }
     
+    @Test
+    public void assertGetValueWhenConfigPlainColumnAndFuzzyQueryColumn() throws SQLException {
+        when(mergedResult.next()).thenReturn(true).thenReturn(false);
+        when(mergedResult.getValue(2, String.class)).thenReturn(
+                "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, `user_id` VARCHAR(100) NOT NULL, "
+                        + "`user_id_fuzzy` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
+        DecoratedEncryptShowCreateTableMergedResult actual =
+                createDecoratedEncryptShowCreateTableMergedResult(mergedResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "", "user_id_fuzzy", "user_id", null, false)));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(2, String.class),
+                is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `user_id_fuzzy` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL,"
+                        + " PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
+    }
+    
     private EncryptRule mockEncryptRule(final EncryptColumn encryptColumn) {
         EncryptRule result = mock(EncryptRule.class);
         EncryptTable encryptTable = mock(EncryptTable.class);
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResultTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResultTest.java
index a27bb824a24..785c93e3ccd 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResultTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dal/show/MergedEncryptShowCreateTableMergedResultTest.java
@@ -65,7 +65,7 @@ public final class MergedEncryptShowCreateTableMergedResultTest {
                 "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, "
                         + "`user_id` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
         MergedEncryptShowCreateTableMergedResult actual =
-                createMergedEncryptShowCreateTableMergedResult(queryResult, mockEncryptRule(new EncryptColumn("user_id_cipher", null, "user_id", null, false)));
+                createMergedEncryptShowCreateTableMergedResult(queryResult, mockEncryptRule(new EncryptColumn("user_id_cipher", null, null, "user_id", null, false)));
         assertTrue(actual.next());
         assertThat(actual.getValue(2, String.class),
                 is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
@@ -78,12 +78,26 @@ public final class MergedEncryptShowCreateTableMergedResultTest {
                 "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, "
                         + "`user_id_assisted` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
         MergedEncryptShowCreateTableMergedResult actual =
-                createMergedEncryptShowCreateTableMergedResult(queryResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "user_id_assisted", null, null, false)));
+                createMergedEncryptShowCreateTableMergedResult(queryResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "user_id_assisted", null, null, null, false)));
         assertTrue(actual.next());
         assertThat(actual.getValue(2, String.class),
                 is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
     }
     
+    @Test
+    public void assertGetValueWhenConfigFuzzyQueryColumn() throws SQLException {
+        when(queryResult.next()).thenReturn(true).thenReturn(false);
+        when(queryResult.getValue(2, String.class)).thenReturn(
+                "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, "
+                        + "`user_id_fuzzy` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
+        MergedEncryptShowCreateTableMergedResult actual =
+                createMergedEncryptShowCreateTableMergedResult(queryResult, mockEncryptRule(new EncryptColumn("user_id_cipher", null, "user_id_fuzzy", null, null, false)));
+        assertTrue(actual.next());
+        assertThat(actual.getValue(2, String.class),
+                is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `user_id_fuzzy` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL,"
+                        + " PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
+    }
+    
     @Test
     public void assertGetValueWhenConfigPlainColumnAndAssistedQueryColumn() throws SQLException {
         when(queryResult.next()).thenReturn(true).thenReturn(false);
@@ -91,7 +105,7 @@ public final class MergedEncryptShowCreateTableMergedResultTest {
                 "CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id_cipher` VARCHAR(100) NOT NULL, `user_id` VARCHAR(100) NOT NULL, "
                         + "`user_id_assisted` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
         MergedEncryptShowCreateTableMergedResult actual =
-                createMergedEncryptShowCreateTableMergedResult(queryResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "user_id_assisted", "user_id", null, false)));
+                createMergedEncryptShowCreateTableMergedResult(queryResult, mockEncryptRule(new EncryptColumn("user_id_cipher", "user_id_assisted", null, "user_id", null, false)));
         assertTrue(actual.next());
         assertThat(actual.getValue(2, String.class),
                 is("CREATE TABLE `t_encrypt` (`id` INT NOT NULL, `user_id` VARCHAR(100) NOT NULL, `order_id` VARCHAR(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"));
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 a41b1f2e534..846f099a9a3 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
@@ -76,11 +76,11 @@ public final class EncryptAlterTableTokenGeneratorTest {
     }
     
     private EncryptColumn mockEncryptColumn() {
-        return new EncryptColumn("cipher_certificate_number", "assisted_certificate_number", "certificate_number_plain", "test", null);
+        return new EncryptColumn("cipher_certificate_number", "assisted_certificate_number", "fuzzy_certificate_number", "certificate_number_plain", "test", null);
     }
     
     private EncryptColumn mockNewEncryptColumn() {
-        return new EncryptColumn("cipher_certificate_number_new", "assisted_certificate_number_new", "certificate_number_new_plain", "test", null);
+        return new EncryptColumn("cipher_certificate_number_new", "assisted_certificate_number_new", "fuzzy_certificate_number_new", "certificate_number_new_plain", "test", null);
     }
     
     @Test
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptCreateTableTokenGeneratorTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptCreateTableTokenGeneratorTest.java
index 80a3e6b34cb..20fb639e58c 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptCreateTableTokenGeneratorTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptCreateTableTokenGeneratorTest.java
@@ -96,11 +96,12 @@ public final class EncryptCreateTableTokenGeneratorTest {
         when(result.getCipherColumn("t_encrypt", "certificate_number")).thenReturn(column.getCipherColumn());
         when(result.findPlainColumn("t_encrypt", "certificate_number")).thenReturn(column.getPlainColumn());
         when(result.findAssistedQueryColumn("t_encrypt", "certificate_number")).thenReturn(column.getAssistedQueryColumn());
+        when(result.findFuzzyQueryColumn("t_encrypt", "certificate_number")).thenReturn(column.getFuzzyQueryColumn());
         when(encryptTable.findEncryptColumn("certificate_number")).thenReturn(Optional.of(column));
         return result;
     }
     
     private EncryptColumn mockEncryptColumn() {
-        return new EncryptColumn("cipher_certificate_number", "assisted_certificate_number", "certificate_number_plain", "test", null);
+        return new EncryptColumn("cipher_certificate_number", "assisted_certificate_number", "fuzzy_certificate_number", "certificate_number_plain", "test", null);
     }
 }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptProjectionTokenGeneratorTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptProjectionTokenGeneratorTest.java
index af16f33a15a..48958b19882 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptProjectionTokenGeneratorTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptProjectionTokenGeneratorTest.java
@@ -71,7 +71,7 @@ public final class EncryptProjectionTokenGeneratorTest {
         when(result.findPlainColumn("doctor1", "mobile")).thenReturn(Optional.of("Mobile"));
         when(result.findEncryptTable("doctor")).thenReturn(Optional.of(encryptTable1));
         when(result.findEncryptTable("doctor1")).thenReturn(Optional.of(encryptTable2));
-        EncryptColumn column = new EncryptColumn("mobile", null, "mobile", null, null);
+        EncryptColumn column = new EncryptColumn("mobile", null, null, "mobile", null, null);
         when(result.findEncryptColumn("doctor", "mobile")).thenReturn(Optional.of(column));
         return result;
     }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptGeneratorBaseTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptGeneratorBaseTest.java
index f503541f400..29d45bdf91b 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptGeneratorBaseTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptGeneratorBaseTest.java
@@ -61,7 +61,8 @@ public abstract class EncryptGeneratorBaseTest {
     private static final String TABLE_NAME = "t_user";
     
     protected static EncryptRule createEncryptRule() {
-        EncryptColumnRuleConfiguration pwdColumnConfig = new EncryptColumnRuleConfiguration("pwd", "pwd_cipher", "pwd_assist", "pwd_plain", "test_encryptor", "test_encryptor", false);
+        EncryptColumnRuleConfiguration pwdColumnConfig =
+                new EncryptColumnRuleConfiguration("pwd", "pwd_cipher", "pwd_assist", "pwd_fuzzy", "pwd_plain", "test_encryptor", "test_encryptor", "test_encryptor", false);
         return new EncryptRule(new EncryptRuleConfiguration(Collections.singleton(new EncryptTableRuleConfiguration(TABLE_NAME, Collections.singletonList(pwdColumnConfig), null)),
                 Collections.singletonMap("test_encryptor", new AlgorithmConfiguration("CORE.QUERY_ASSISTED.FIXTURE", new Properties()))));
     }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rule/EncryptColumnTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rule/EncryptColumnTest.java
index 94d34ae7194..abd3a2c02e3 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rule/EncryptColumnTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rule/EncryptColumnTest.java
@@ -25,11 +25,16 @@ public final class EncryptColumnTest {
     
     @Test
     public void assertGetAssistedQueryColumn() {
-        assertTrue(new EncryptColumn("cipherColumn", "assistedQueryColumn", "plainColumn", "encryptorName", null).getAssistedQueryColumn().isPresent());
+        assertTrue(new EncryptColumn("cipherColumn", "assistedQueryColumn", "fuzzyQueryColumn", "plainColumn", "encryptorName", null).getAssistedQueryColumn().isPresent());
+    }
+    
+    @Test
+    public void assertGetFuzzyQueryColumn() {
+        assertTrue(new EncryptColumn("cipherColumn", "assistedQueryColumn", "fuzzyQueryColumn", "plainColumn", "encryptorName", null).getFuzzyQueryColumn().isPresent());
     }
     
     @Test
     public void assertGetPlainColumn() {
-        assertTrue(new EncryptColumn("cipherColumn", "assistedQueryColumn", "plainColumn", "encryptorName", null).getPlainColumn().isPresent());
+        assertTrue(new EncryptColumn("cipherColumn", "assistedQueryColumn", "fuzzyQueryColumn", "plainColumn", "encryptorName", null).getPlainColumn().isPresent());
     }
 }
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rule/EncryptRuleTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rule/EncryptRuleTest.java
index d3d08b8654a..490f2a6b42c 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rule/EncryptRuleTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rule/EncryptRuleTest.java
@@ -185,7 +185,7 @@ public final class EncryptRuleTest {
     private EncryptRuleConfiguration createEncryptRuleConfiguration() {
         AlgorithmConfiguration queryAssistedEncryptConfig = new AlgorithmConfiguration("CORE.QUERY_ASSISTED.FIXTURE", new Properties());
         AlgorithmConfiguration metaDataAwareEncryptConfig = new AlgorithmConfiguration("CORE.METADATA_AWARE.FIXTURE", new Properties());
-        EncryptColumnRuleConfiguration pwdColumnConfig = new EncryptColumnRuleConfiguration("pwd", "pwd_cipher", "pwd_assist", "pwd_plain", "test_encryptor", "test_encryptor", null);
+        EncryptColumnRuleConfiguration pwdColumnConfig = new EncryptColumnRuleConfiguration("pwd", "pwd_cipher", "pwd_assist", "", "pwd_plain", "test_encryptor", "test_encryptor", null, null);
         EncryptColumnRuleConfiguration creditCardColumnConfig = new EncryptColumnRuleConfiguration("credit_card", "credit_card_cipher", "", "credit_card_plain", "test_encryptor", null);
         EncryptColumnRuleConfiguration nameColumnConfig = new EncryptColumnRuleConfiguration("name", "name_cipher", "", "name_plain", "customized_encryptor", null);
         EncryptTableRuleConfiguration tableConfig = new EncryptTableRuleConfiguration("t_encrypt", Arrays.asList(pwdColumnConfig, creditCardColumnConfig, nameColumnConfig), null);
@@ -194,7 +194,8 @@ public final class EncryptRuleTest {
     
     @Test
     public void assertAssistedQueryEncryptorNameSpecified() {
-        EncryptColumnRuleConfiguration pwdColumnConfig = new EncryptColumnRuleConfiguration("pwd", "pwd_cipher", "pwd_assist", "pwd_plain", "test_encryptor", "assisted_query_test_encryptor", null);
+        EncryptColumnRuleConfiguration pwdColumnConfig =
+                new EncryptColumnRuleConfiguration("pwd", "pwd_cipher", "pwd_assist", "", "pwd_plain", "test_encryptor", "assisted_query_test_encryptor", null, null);
         assertThat(pwdColumnConfig.getAssistedQueryEncryptorName(), is("assisted_query_test_encryptor"));
     }
     
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptColumnRuleConfigurationSwapperTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptColumnRuleConfigurationSwapperTest.java
index 4356ca9bcf9..78fde6ff3a4 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptColumnRuleConfigurationSwapperTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptColumnRuleConfigurationSwapperTest.java
@@ -46,6 +46,7 @@ public final class YamlEncryptColumnRuleConfigurationSwapperTest {
         yamlEncryptColumnRuleConfig.setLogicColumn("logicColumn");
         yamlEncryptColumnRuleConfig.setCipherColumn("cipherColumn");
         yamlEncryptColumnRuleConfig.setAssistedQueryColumn("assistedQueryColumn");
+        yamlEncryptColumnRuleConfig.setFuzzyQueryColumn("fuzzyQueryColumn");
         yamlEncryptColumnRuleConfig.setPlainColumn("plainColumn");
         yamlEncryptColumnRuleConfig.setEncryptorName("encryptorName");
         yamlEncryptColumnRuleConfig.setQueryWithCipherColumn(true);
@@ -53,6 +54,7 @@ public final class YamlEncryptColumnRuleConfigurationSwapperTest {
         assertThat(actual.getLogicColumn(), is("logicColumn"));
         assertThat(actual.getCipherColumn(), is("cipherColumn"));
         assertThat(actual.getAssistedQueryColumn(), is("assistedQueryColumn"));
+        assertThat(actual.getFuzzyQueryColumn(), is("fuzzyQueryColumn"));
         assertThat(actual.getPlainColumn(), is("plainColumn"));
         assertThat(actual.getEncryptorName(), is("encryptorName"));
         assertThat(actual.getQueryWithCipherColumn(), is(true));
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptTableRuleConfigurationSwapperTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptTableRuleConfigurationSwapperTest.java
index 1013d92599c..0f1bf7eeae8 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptTableRuleConfigurationSwapperTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/yaml/swapper/rule/YamlEncryptTableRuleConfigurationSwapperTest.java
@@ -70,6 +70,7 @@ public final class YamlEncryptTableRuleConfigurationSwapperTest {
         encryptColumnRuleConfig.setLogicColumn("encrypt_column");
         encryptColumnRuleConfig.setCipherColumn("encrypt_cipher");
         encryptColumnRuleConfig.setAssistedQueryColumn("encrypt_assisted");
+        encryptColumnRuleConfig.setFuzzyQueryColumn("encrypt_fuzzy");
         encryptColumnRuleConfig.setPlainColumn("encrypt_plain");
         encryptColumnRuleConfig.setEncryptorName("test_encryptor");
         encryptColumnRuleConfig.setQueryWithCipherColumn(true);
@@ -88,6 +89,7 @@ public final class YamlEncryptTableRuleConfigurationSwapperTest {
         assertThat(actualEncryptColumnRuleConfig.getLogicColumn(), is("test_column"));
         assertThat(actualEncryptColumnRuleConfig.getCipherColumn(), is("encrypt_cipher"));
         assertThat(actualEncryptColumnRuleConfig.getAssistedQueryColumn(), is("encrypt_assisted"));
+        assertThat(actualEncryptColumnRuleConfig.getFuzzyQueryColumn(), is("encrypt_fuzzy"));
         assertThat(actualEncryptColumnRuleConfig.getPlainColumn(), is("encrypt_plain"));
         assertThat(actualEncryptColumnRuleConfig.getEncryptorName(), is("test_encryptor"));
         assertTrue(actualEncryptColumnRuleConfig.getQueryWithCipherColumn());
diff --git a/features/encrypt/distsql/handler/src/main/java/org/apache/shardingsphere/encrypt/distsql/handler/converter/EncryptRuleStatementConverter.java b/features/encrypt/distsql/handler/src/main/java/org/apache/shardingsphere/encrypt/distsql/handler/converter/EncryptRuleStatementConverter.java
index 3333b7bde0f..7bfe6054c5d 100644
--- a/features/encrypt/distsql/handler/src/main/java/org/apache/shardingsphere/encrypt/distsql/handler/converter/EncryptRuleStatementConverter.java
+++ b/features/encrypt/distsql/handler/src/main/java/org/apache/shardingsphere/encrypt/distsql/handler/converter/EncryptRuleStatementConverter.java
@@ -61,7 +61,7 @@ public final class EncryptRuleStatementConverter {
     private static EncryptColumnRuleConfiguration createEncryptColumnRuleConfiguration(final String tableName, final EncryptColumnSegment columnSegment) {
         String assistedQueryEncryptorName = null == columnSegment.getAssistedQueryEncryptor() ? null : getAssistedQueryEncryptorName(tableName, columnSegment.getName());
         return new EncryptColumnRuleConfiguration(columnSegment.getName(), columnSegment.getCipherColumn(), columnSegment.getAssistedQueryColumn(),
-                columnSegment.getPlainColumn(), getEncryptorName(tableName, columnSegment.getName()), assistedQueryEncryptorName, null);
+                null, columnSegment.getPlainColumn(), getEncryptorName(tableName, columnSegment.getName()), assistedQueryEncryptorName, null, null);
     }
     
     private static Map<String, AlgorithmConfiguration> createEncryptorConfigurations(final EncryptRuleSegment ruleSegment) {
diff --git a/features/encrypt/spring/spring-namespace/src/main/java/org/apache/shardingsphere/encrypt/spring/namespace/parser/EncryptRuleBeanDefinitionParser.java b/features/encrypt/spring/spring-namespace/src/main/java/org/apache/shardingsphere/encrypt/spring/namespace/parser/EncryptRuleBeanDefinitionParser.java
index 4f35d76541c..0d021ed110c 100644
--- a/features/encrypt/spring/spring-namespace/src/main/java/org/apache/shardingsphere/encrypt/spring/namespace/parser/EncryptRuleBeanDefinitionParser.java
+++ b/features/encrypt/spring/spring-namespace/src/main/java/org/apache/shardingsphere/encrypt/spring/namespace/parser/EncryptRuleBeanDefinitionParser.java
@@ -81,9 +81,11 @@ public final class EncryptRuleBeanDefinitionParser extends AbstractBeanDefinitio
         factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.LOGIC_COLUMN_ATTRIBUTE));
         factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.CIPHER_COLUMN_ATTRIBUTE));
         factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.ASSISTED_QUERY_COLUMN_ATTRIBUTE));
+        factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.FUZZY_QUERY_COLUMN_ATTRIBUTE));
         factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.PLAIN_COLUMN_ATTRIBUTE));
         factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.ENCRYPT_ALGORITHM_REF_ATTRIBUTE));
         factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.ASSISTED_QUERY_ENCRYPT_ALGORITHM_REF_ATTRIBUTE));
+        factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.FUZZY_QUERY_ENCRYPT_ALGORITHM_REF_ATTRIBUTE));
         factory.addConstructorArgValue(element.getAttribute(EncryptRuleBeanDefinitionTag.QUERY_WITH_CIPHER_COLUMN));
         return factory.getBeanDefinition();
     }
diff --git a/features/encrypt/spring/spring-namespace/src/main/java/org/apache/shardingsphere/encrypt/spring/namespace/tag/EncryptRuleBeanDefinitionTag.java b/features/encrypt/spring/spring-namespace/src/main/java/org/apache/shardingsphere/encrypt/spring/namespace/tag/EncryptRuleBeanDefinitionTag.java
index 2e26f5c8a89..c674c13be13 100644
--- a/features/encrypt/spring/spring-namespace/src/main/java/org/apache/shardingsphere/encrypt/spring/namespace/tag/EncryptRuleBeanDefinitionTag.java
+++ b/features/encrypt/spring/spring-namespace/src/main/java/org/apache/shardingsphere/encrypt/spring/namespace/tag/EncryptRuleBeanDefinitionTag.java
@@ -56,6 +56,11 @@ public final class EncryptRuleBeanDefinitionTag {
      */
     public static final String ASSISTED_QUERY_COLUMN_ATTRIBUTE = "assisted-query-column";
     
+    /**
+     * Fuzzy query column attribute.
+     */
+    public static final String FUZZY_QUERY_COLUMN_ATTRIBUTE = "fuzzy-query-column";
+    
     /**
      * Plain column attribute.
      */
@@ -71,6 +76,11 @@ public final class EncryptRuleBeanDefinitionTag {
      */
     public static final String ASSISTED_QUERY_ENCRYPT_ALGORITHM_REF_ATTRIBUTE = "assisted-query-encrypt-algorithm-ref";
     
+    /**
+     * Fuzzy query encrypt algorithm ref attribute.
+     */
+    public static final String FUZZY_QUERY_ENCRYPT_ALGORITHM_REF_ATTRIBUTE = "fuzzy-query-encrypt-algorithm-ref";
+    
     /**
      * Query with cipher column attribute.
      */
diff --git a/features/encrypt/spring/spring-namespace/src/main/resources/META-INF/namespace/encrypt.xsd b/features/encrypt/spring/spring-namespace/src/main/resources/META-INF/namespace/encrypt.xsd
index fe6edf80099..cd06f9d38c0 100644
--- a/features/encrypt/spring/spring-namespace/src/main/resources/META-INF/namespace/encrypt.xsd
+++ b/features/encrypt/spring/spring-namespace/src/main/resources/META-INF/namespace/encrypt.xsd
@@ -47,6 +47,7 @@
             <xsd:attribute name="logic-column" type="xsd:string" use="required" />
             <xsd:attribute name="cipher-column" type="xsd:string" use="required" />
             <xsd:attribute name="assisted-query-column" type="xsd:string" />
+            <xsd:attribute name="fuzzy-query-column" type="xsd:string" />
             <xsd:attribute name="plain-column" type="xsd:string" />
             <xsd:attribute name="encrypt-algorithm-ref" type="xsd:string" use="required" />
             <xsd:attribute name="assisted-query-encrypt-algorithm-ref" type="xsd:string" />