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

panjuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new d19fb02  Add shadow delete statement route (#12398)
d19fb02 is described below

commit d19fb027e1c08cc5c430cc1fc7e6ba3ba283e517
Author: gin <[email protected]>
AuthorDate: Tue Sep 14 14:24:49 2021 +0800

    Add shadow delete statement route (#12398)
    
    * Optimize column values type.
    
    * Optimize shadow extractor.
    
    * Add shadow delete statement routing engine.
    
    * Add shadow delete statement routing engine in example.
    
    * Fix ut.
    
    * Add final.
---
 .../ShadowSpringNamespaceMybatisExample.java       |  4 +-
 .../namespace/mybatis/repository/OrderMapper.java  |  4 ++
 .../namespace/mybatis/service/OrderService.java    |  2 +
 .../namespace/mybatis/service/ShadowService.java   |  2 +
 .../mybatis/service/impl/OrderServiceImpl.java     | 59 +++++++++++++-------
 .../mybatis/service/impl/ShadowServiceImpl.java    | 58 ++++++++++++++-----
 .../META-INF/application-shadow-databases.xml      |  2 +-
 .../resources/META-INF/mappers/OrderMapper.xml     | 11 ++++
 .../future/engine/AbstractShadowRouteEngine.java   | 16 +++---
 .../future/engine/ShadowRouteEngineFactory.java    |  7 ++-
 .../engine/determiner/ShadowColumnCondition.java   | 18 ++++--
 .../determiner/ShadowDetermineCondition.java       | 34 ++++++-----
 .../algorithm/ColumnShadowAlgorithmDeterminer.java | 16 +++---
 .../dml/ShadowDeleteStatementRoutingEngine.java    | 65 ++++++++++++++++++++--
 .../dml/ShadowInsertStatementRoutingEngine.java    |  9 ++-
 .../dml/ShadowUpdateStatementRoutingEngine.java    | 43 ++++----------
 .../route/future/engine/util/ShadowExtractor.java  | 57 +++----------------
 .../ColumnShadowAlgorithmDeterminerTest.java       |  9 +--
 18 files changed, 242 insertions(+), 174 deletions(-)

diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/ShadowSpringNamespaceMybatisExample.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/ShadowSpringNamespace
 [...]
index 19c8462..c4181f7 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/ShadowSpringNamespaceMybatisExample.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/ShadowSpringNamespaceMybatisExample.java
@@ -37,11 +37,11 @@ public final class ShadowSpringNamespaceMybatisExample {
     
     private static void executeOrderService(final 
ConfigurableApplicationContext applicationContext) {
         OrderService orderService = applicationContext.getBean("orderService", 
OrderService.class);
-        orderService.executeUpdateCase();
+        orderService.executeDeleteCase();
     }
     
     private static void executeShadowService(final 
ConfigurableApplicationContext applicationContext) {
         ShadowService shadowService = 
applicationContext.getBean("shadowService", ShadowService.class);
-        shadowService.executeUpdateCase();
+        shadowService.executeDeleteCase();
     }
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/repository/OrderMapper.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/repository/OrderMapper.java
index 2f5a412..1b9cf43 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/repository/OrderMapper.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/repository/OrderMapper.java
@@ -33,4 +33,8 @@ public interface OrderMapper {
     void updateOne(OrderInfo orderInfo);
     
     void updateByUserIds(Map<String, Object> updateMap);
+    
+    void remove(OrderInfo orderInfo);
+    
+    void removeInUserIds(List<Integer> userIds);
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/OrderService.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/OrderService.java
index 1156525..85976c5 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/OrderService.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/OrderService.java
@@ -22,4 +22,6 @@ public interface OrderService {
     void executeInsertCase();
     
     void executeUpdateCase();
+    
+    void executeDeleteCase();
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/ShadowService.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/ShadowService.java
index 9d00d76..c0d40c5 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/ShadowService.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/ShadowService.java
@@ -22,4 +22,6 @@ public interface ShadowService {
     void executeInsertCase();
     
     void executeUpdateCase();
+    
+    void executeDeleteCase();
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/OrderServiceImpl.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/OrderServiceImpl.java
index 2f152cd..7c27d04 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/OrderServiceImpl.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/OrderServiceImpl.java
@@ -41,6 +41,30 @@ public final class OrderServiceImpl implements OrderService {
         executeBatchInsertCase();
     }
     
+    private void executeBatchInsertCase() {
+        List<OrderInfo> orders = new ArrayList<>();
+        OrderInfo orderInfo1 = new OrderInfo();
+        orderInfo1.setUserId(1);
+        orderInfo1.setContent("insert_case_2");
+        orders.add(orderInfo1);
+        OrderInfo orderInfo2 = new OrderInfo();
+        orderInfo2.setUserId(2);
+        orderInfo2.setContent("insert_case_2");
+        orders.add(orderInfo2);
+        OrderInfo orderInfo3 = new OrderInfo();
+        orderInfo3.setUserId(1);
+        orderInfo3.setContent("insert_case_2");
+        orders.add(orderInfo3);
+        orderMapper.saveBatch(orders);
+    }
+    
+    private void executeOneInsertCase() {
+        OrderInfo orderInfo = new OrderInfo();
+        orderInfo.setUserId(1);
+        orderInfo.setContent("insert_case_1");
+        orderMapper.saveOne(orderInfo);
+    }
+    
     @Override
     public void executeUpdateCase() {
         executeOneUpdateCase();
@@ -65,28 +89,23 @@ public final class OrderServiceImpl implements OrderService 
{
         orderMapper.updateOne(orderInfo);
     }
     
+    @Override
+    public void executeDeleteCase() {
+        executeRemoveOneCase();
+        executeRemoveInCase();
+    }
+    
+    private void executeRemoveInCase() {
+        List<Integer> userIds = new LinkedList<>();
+        userIds.add(1);
+        userIds.add(1);
+        userIds.add(1);
+        orderMapper.removeInUserIds(userIds);
+    }
     
-    private void executeOneInsertCase() {
+    private void executeRemoveOneCase() {
         OrderInfo orderInfo = new OrderInfo();
         orderInfo.setUserId(1);
-        orderInfo.setContent("insert_case_1");
-        orderMapper.saveOne(orderInfo);
-    }
-    
-    private void executeBatchInsertCase() {
-        List<OrderInfo> orders = new ArrayList<>();
-        OrderInfo orderInfo1 = new OrderInfo();
-        orderInfo1.setUserId(1);
-        orderInfo1.setContent("insert_case_2");
-        orders.add(orderInfo1);
-        OrderInfo orderInfo2 = new OrderInfo();
-        orderInfo2.setUserId(2);
-        orderInfo2.setContent("insert_case_2");
-        orders.add(orderInfo2);
-        OrderInfo orderInfo3 = new OrderInfo();
-        orderInfo3.setUserId(1);
-        orderInfo3.setContent("insert_case_2");
-        orders.add(orderInfo3);
-        orderMapper.saveBatch(orders);
+        orderMapper.remove(orderInfo);
     }
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/ShadowServiceImpl.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/ShadowService
 [...]
index 58b05c6..3e4c9b8 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/ShadowServiceImpl.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/ShadowServiceImpl.java
@@ -37,10 +37,7 @@ public final class ShadowServiceImpl implements 
ShadowService {
     
     @Override
     public void executeInsertCase() {
-        Collection<String> insertSQLs = initInsertCase();
-        for (String each : insertSQLs) {
-            execute(each);
-        }
+        initInsertCase().forEach(this::execute);
     }
     
     private Collection<String> initInsertCase() {
@@ -58,28 +55,61 @@ public final class ShadowServiceImpl implements 
ShadowService {
     
     @Override
     public void executeUpdateCase() {
-        Collection<String> updateSQLs = initUpdateCase();
-        for (String each : updateSQLs) {
-            execute(each);
-        }
+        initUpdateCase().forEach(this::execute);
     }
     
     private Collection<String> initUpdateCase() {
         Collection<String> result = new LinkedList<>();
         String update_case_1 = "UPDATE t_order SET user_id = 2, content = 
'update_case_1' WHERE user_id = 1 and content = 'update_case_1'";
         result.add(update_case_1);
-        String update_case_2 = "UPDATE t_order SET user_id = 2, content = 
'update_case_1' WHERE user_id = 2 and content = 'update_case_1'";
+        String update_case_2 = "UPDATE t_order SET user_id = 2, content = 
'update_case_2' WHERE user_id = 2 and content = 'update_case_1'";
         result.add(update_case_2);
-        String update_case_3 = "UPDATE t_order SET user_id = 2, content = 
'update_case_1' WHERE user_id = 1 or content = 'aa'";
+        String update_case_3 = "UPDATE t_order SET user_id = 2, content = 
'update_case_3' WHERE user_id in (1, 1) or content = 'aa'";
         result.add(update_case_3);
-        String update_case_4 = "UPDATE t_order SET user_id = 2, content = 
'update_case_1' WHERE user_id = 2 or content = 'aa'";
+        String update_case_4 = "UPDATE t_order SET user_id = 2, content = 
'update_case_4' WHERE user_id in (1, 2, 3) or content BETWEEN 'aaa' AND 'bbb'";
         result.add(update_case_4);
-        String update_case_5 = "UPDATE t_order SET user_id = 2, content = 
'update_case_1' WHERE user_id in (1, 2, 3) or content BETWEEN 'aaa' AND 'bbb'";
+        String update_case_5 = "UPDATE t_order SET user_id = 2, content = 
'update_case_5' WHERE user_id like '1'";
         result.add(update_case_5);
-        String update_case_6 = "UPDATE t_order SET user_id = 2, content = 
'update_case_1' WHERE user_id = 2 or content = 'aa'";
+        String update_case_6 = "UPDATE t_order SET user_id = 2, content = 
'update_case_6' WHERE user_id not like '1'";
         result.add(update_case_6);
-        String update_case_7 = "UPDATE t_order SET user_id = 2, content = 
'update_case_1' WHERE user_id BETWEEN 0 AND 2 or content = 'aa'";
+        String update_case_7 = "UPDATE t_order SET user_id = 2, content = 
'update_case_7' WHERE user_id = 1 or user_id in (2, 3) ";
         result.add(update_case_7);
+        String update_case_8 = "UPDATE t_order SET user_id = 2, content = 
'update_case_8' WHERE user_id = 2 or user_id in (1, 1) ";
+        result.add(update_case_8);
+        String update_case_9 = "UPDATE t_order SET user_id = 2, content = 
'update_case_9' WHERE user_id in (select user_id from t_order_data where 
user_id = 1)";
+        result.add(update_case_9);
+        String update_case_10 = "UPDATE t_order SET user_id = 2, content = 
'update_case_10' WHERE user_id BETWEEN 0 AND 2 or content = 'aa'";
+        result.add(update_case_10);
+        return result;
+    }
+    
+    @Override
+    public void executeDeleteCase() {
+        initDeleteCase().forEach(this::execute);
+    }
+    
+    private Collection<String> initDeleteCase() {
+        Collection<String> result = new LinkedList<>();
+        String delete_case_1 = "DELETE FROM t_order WHERE user_id = 1 and 
content = 'delete_case_1'";
+        result.add(delete_case_1);
+        String delete_case_2 = "DELETE FROM t_order WHERE user_id = 2 and 
content = 'delete_case_2'";
+        result.add(delete_case_2);
+        String delete_case_3 = "DELETE FROM t_order WHERE user_id in (1, 1) or 
content = 'aa'";
+        result.add(delete_case_3);
+        String delete_case_4 = "DELETE FROM t_order WHERE user_id in (1, 2, 3) 
or content BETWEEN 'aaa' AND 'bbb'";
+        result.add(delete_case_4);
+        String delete_case_5 = "DELETE FROM t_order WHERE user_id like '1'";
+        result.add(delete_case_5);
+        String delete_case_6 = "DELETE FROM t_order WHERE user_id not like 
'1'";
+        result.add(delete_case_6);
+        String delete_case_7 = "DELETE FROM t_order WHERE user_id = 1 or 
user_id in (2, 3) ";
+        result.add(delete_case_7);
+        String delete_case_8 = "DELETE FROM t_order WHERE user_id = 2 or 
user_id in (1, 1) ";
+        result.add(delete_case_8);
+        String delete_case_9 = "DELETE FROM t_order WHERE user_id in (select 
user_id from t_order_data where user_id = 1)";
+        result.add(delete_case_9);
+        String delete_case_10 = "DELETE FROM t_order WHERE user_id BETWEEN 0 
AND 2 or content = 'aa'";
+        result.add(delete_case_10);
         return result;
     }
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/application-shadow-databases.xml
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/application-shadow-databases.xml
index 82d149f..aa366c7 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/application-shadow-databases.xml
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/application-shadow-databases.xml
@@ -49,7 +49,7 @@
 
     <shadow:shadow-algorithm id="user-id-match-algorithm" 
type="COLUMN_REGEX_MATCH">
         <props>
-            <prop key="operation">update</prop>
+            <prop key="operation">delete</prop>
             <prop key="column">user_id</prop>
             <prop key="regex">[1]</prop>
         </props>
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/mappers/OrderMapper.xml
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/mappers/OrderMapper.xml
index 37db9af..2183cc1 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/mappers/OrderMapper.xml
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/mappers/OrderMapper.xml
@@ -53,4 +53,15 @@
             #{userId}
         </foreach>
     </update>
+    
+    <delete id="remove" 
parameterType="org.apache.shardingsphere.example.shadow.spring.namespace.mybatis.domain.OrderInfo">
+        DELETE FROM t_order WHERE user_id = #{userId}
+    </delete>
+
+    <delete id="removeInUserIds" parameterType="java.util.List">
+        DELETE FROM t_order WHERE user_id in
+        <foreach collection="list" item="userId" separator="," open="(" 
close=")">
+            #{userId}
+        </foreach>
+    </delete>
 </mapper>
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/AbstractShadowRouteEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/AbstractShadowRouteEngine.java
index 1a335e1..2d43c32 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/AbstractShadowRouteEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/AbstractShadowRouteEngine.java
@@ -22,6 +22,7 @@ import 
org.apache.shardingsphere.infra.route.context.RouteMapper;
 import org.apache.shardingsphere.infra.route.context.RouteUnit;
 import 
org.apache.shardingsphere.shadow.api.shadow.column.ColumnShadowAlgorithm;
 import org.apache.shardingsphere.shadow.api.shadow.note.NoteShadowAlgorithm;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDeterminerFactory;
 import org.apache.shardingsphere.shadow.rule.ShadowRule;
@@ -30,7 +31,6 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.Sim
 
 import java.util.Collection;
 import java.util.LinkedList;
-import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -82,12 +82,12 @@ public abstract class AbstractShadowRouteEngine implements 
ShadowRouteEngine {
     }
     
     private boolean isShadowColumnAlgorithm(final ShadowDetermineCondition 
shadowDetermineCondition, final ShadowAlgorithm shadowAlgorithm, final 
ShadowRule shadowRule, final String tableName) {
-        if (!shadowDetermineCondition.isColumnValuesMappingsInitialized()) {
-            Optional<Map<String, Collection<Comparable<?>>>> 
columnValuesMappings = parseColumnValuesMappings();
-            if (!columnValuesMappings.isPresent()) {
+        if (!shadowDetermineCondition.isShadowColumnConditionsInitialized()) {
+            final Optional<Collection<ShadowColumnCondition>> 
shadowColumnConditions = parseShadowColumnConditions();
+            if (!shadowColumnConditions.isPresent()) {
                 return false;
             }
-            
shadowDetermineCondition.initColumnValuesMappings(columnValuesMappings.get());
+            
shadowDetermineCondition.initShadowColumnCondition(shadowColumnConditions.get());
         }
         return 
ShadowDeterminerFactory.newInstance(shadowAlgorithm).isShadow(shadowDetermineCondition,
 shadowRule, tableName);
     }
@@ -104,11 +104,11 @@ public abstract class AbstractShadowRouteEngine 
implements ShadowRouteEngine {
     }
     
     /**
-     * Parse column values mappings.
+     * Parse shadow column conditions.
      *
-     * @return column values mappings
+     * @return shadow column condition
      */
-    protected abstract Optional<Map<String, Collection<Comparable<?>>>> 
parseColumnValuesMappings();
+    protected abstract Optional<Collection<ShadowColumnCondition>> 
parseShadowColumnConditions();
     
     /**
      * Parse sql notes.
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/ShadowRouteEngineFactory.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/ShadowRouteEngineFactory.java
index 11d5ecb..e3b3d2a 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/ShadowRouteEngineFactory.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/ShadowRouteEngineFactory.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.shadow.route.future.engine;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.infra.binder.LogicSQL;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.DeleteStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.UpdateStatementContext;
 import 
org.apache.shardingsphere.shadow.route.future.engine.dml.ShadowDeleteStatementRoutingEngine;
@@ -50,7 +51,7 @@ public final class ShadowRouteEngineFactory {
         if (sqlStatement instanceof InsertStatement) {
             return createShadowInsertStatementRoutingEngine(logicSQL);
         } else if (sqlStatement instanceof DeleteStatement) {
-            return createShadowDeleteStatementRoutingEngine();
+            return createShadowDeleteStatementRoutingEngine(logicSQL);
         } else if (sqlStatement instanceof UpdateStatement) {
             return createShadowUpdateStatementRoutingEngine(logicSQL);
         } else if (sqlStatement instanceof SelectStatement) {
@@ -72,8 +73,8 @@ public final class ShadowRouteEngineFactory {
         return new ShadowUpdateStatementRoutingEngine((UpdateStatementContext) 
logicSQL.getSqlStatementContext(), logicSQL.getParameters());
     }
     
-    private static ShadowRouteEngine 
createShadowDeleteStatementRoutingEngine() {
-        return new ShadowDeleteStatementRoutingEngine();
+    private static ShadowRouteEngine 
createShadowDeleteStatementRoutingEngine(final LogicSQL logicSQL) {
+        return new ShadowDeleteStatementRoutingEngine((DeleteStatementContext) 
logicSQL.getSqlStatementContext(), logicSQL.getParameters());
     }
     
     private static ShadowRouteEngine 
createShadowInsertStatementRoutingEngine(final LogicSQL logicSQL) {
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/OrderService.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/ShadowColumnCondition.java
similarity index 69%
copy from 
examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/OrderService.java
copy to 
shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/ShadowColumnCondition.java
index 1156525..14cd817 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/OrderService.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/ShadowColumnCondition.java
@@ -15,11 +15,21 @@
  * limitations under the License.
  */
 
-package 
org.apache.shardingsphere.example.shadow.spring.namespace.mybatis.service;
+package org.apache.shardingsphere.shadow.route.future.engine.determiner;
 
-public interface OrderService {
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Collection;
+
+/**
+ * Shadow column condition.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class ShadowColumnCondition {
     
-    void executeInsertCase();
+    private final String column;
     
-    void executeUpdateCase();
+    private final Collection<Comparable<?>> values;
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/ShadowDetermineCondition.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/ShadowDetermineCondition.java
index 8eeee24..d6f59a5 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/ShadowDetermineCondition.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/ShadowDetermineCondition.java
@@ -20,9 +20,7 @@ package 
org.apache.shardingsphere.shadow.route.future.engine.determiner;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 
 import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
-import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -32,18 +30,18 @@ public final class ShadowDetermineCondition {
     
     private boolean sqlNotesInitialized;
     
-    private boolean columnValuesMappingsInitialized;
+    private boolean shadowColumnConditionsInitialized;
     
     private final ShadowOperationType shadowOperationType;
     
-    private final Map<String, Collection<Comparable<?>>> columnValuesMappings 
= new LinkedHashMap<>();
+    private final Collection<ShadowColumnCondition> shadowColumnConditions = 
new LinkedList<>();
     
     private final Collection<String> sqlNotes = new LinkedList<>();
     
     public ShadowDetermineCondition(final ShadowOperationType 
shadowOperationType) {
         this.shadowOperationType = shadowOperationType;
         sqlNotesInitialized = false;
-        columnValuesMappingsInitialized = false;
+        shadowColumnConditionsInitialized = false;
     }
     
     /**
@@ -78,34 +76,34 @@ public final class ShadowDetermineCondition {
     }
     
     /**
-     * Initialize column values mappings.
+     * Initialize shadow column condition.
      *
-     * @param columnValuesMappings column values mappings
+     * @param shadowColumnConditions shadow column conditions
      */
-    public void initColumnValuesMappings(final Map<String, 
Collection<Comparable<?>>> columnValuesMappings) {
-        if (columnValuesMappingsInitialized) {
+    public void initShadowColumnCondition(final 
Collection<ShadowColumnCondition> shadowColumnConditions) {
+        if (shadowColumnConditionsInitialized) {
             return;
         }
-        this.columnValuesMappings.putAll(columnValuesMappings);
-        columnValuesMappingsInitialized = true;
+        this.shadowColumnConditions.addAll(shadowColumnConditions);
+        shadowColumnConditionsInitialized = true;
     }
     
     /**
-     * Is column values mappings initialized.
+     * Is shadow column conditions initialized.
      *
      * @return is initialized or not
      */
-    public boolean isColumnValuesMappingsInitialized() {
-        return columnValuesMappingsInitialized;
+    public boolean isShadowColumnConditionsInitialized() {
+        return shadowColumnConditionsInitialized;
     }
     
     /**
-     * Get column values mappings.
+     * Get shadow column conditions.
      *
-     * @return column values mappings
+     * @return shadow column conditions
      */
-    public Optional<Map<String, Collection<Comparable<?>>>> 
getColumnValuesMappings() {
-        return columnValuesMappings.isEmpty() ? Optional.empty() : 
Optional.of(columnValuesMappings);
+    public Optional<Collection<ShadowColumnCondition>> 
getShadowColumnConditions() {
+        return shadowColumnConditions.isEmpty() ? Optional.empty() : 
Optional.of(shadowColumnConditions);
     }
     
     /**
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/ColumnShadowAlgorithmDeterminer.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/ColumnShadowAlgorithmDeterminer.java
index ed5a2aa..095a4db 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/ColumnShadowAlgorithmDeterminer.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/ColumnShadowAlgorithmDeterminer.java
@@ -22,12 +22,12 @@ import 
org.apache.shardingsphere.shadow.api.shadow.column.ColumnShadowAlgorithm;
 import 
org.apache.shardingsphere.shadow.api.shadow.column.PreciseColumnShadowValue;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowAlgorithmDeterminer;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import org.apache.shardingsphere.shadow.rule.ShadowRule;
 
 import java.util.Collection;
 import java.util.LinkedList;
-import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -40,10 +40,10 @@ public final class ColumnShadowAlgorithmDeterminer 
implements ShadowAlgorithmDet
     
     @Override
     public boolean isShadow(final ShadowDetermineCondition 
shadowDetermineCondition, final ShadowRule shadowRule, final String tableName) {
-        Optional<Map<String, Collection<Comparable<?>>>> columnValuesMappings 
= shadowDetermineCondition.getColumnValuesMappings();
-        if (columnValuesMappings.isPresent()) {
-            for (Map.Entry<String, Collection<Comparable<?>>> entry : 
columnValuesMappings.get().entrySet()) {
-                if (isShadowColumn(createColumnShadowValues(entry.getKey(), 
entry.getValue(), tableName, 
shadowDetermineCondition.getShadowOperationType()), 
shadowRule.getAllShadowTableNames())) {
+        Optional<Collection<ShadowColumnCondition>> shadowColumnConditions = 
shadowDetermineCondition.getShadowColumnConditions();
+        if (shadowColumnConditions.isPresent()) {
+            for (ShadowColumnCondition each : shadowColumnConditions.get()) {
+                if (isShadowColumn(each, shadowRule, tableName, 
shadowDetermineCondition.getShadowOperationType())) {
                     return true;
                 }
             }
@@ -51,9 +51,9 @@ public final class ColumnShadowAlgorithmDeterminer implements 
ShadowAlgorithmDet
         return false;
     }
     
-    private boolean isShadowColumn(final 
Collection<PreciseColumnShadowValue<Comparable<?>>> preciseColumnShadowValues, 
final Collection<String> relatedShadowTables) {
-        for (PreciseColumnShadowValue<Comparable<?>> each : 
preciseColumnShadowValues) {
-            if (!columnShadowAlgorithm.isShadow(relatedShadowTables, each)) {
+    private boolean isShadowColumn(final ShadowColumnCondition 
shadowColumnCondition, final ShadowRule shadowRule, final String tableName, 
final ShadowOperationType operationType) {
+        for (PreciseColumnShadowValue<Comparable<?>> each : 
createColumnShadowValues(shadowColumnCondition.getColumn(), 
shadowColumnCondition.getValues(), tableName, operationType)) {
+            if 
(!columnShadowAlgorithm.isShadow(shadowRule.getAllShadowTableNames(), each)) {
                 return false;
             }
         }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowDeleteStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowDeleteStatementRoutingEngine.java
index 496ffec..8ac638c 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowDeleteStatementRoutingEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowDeleteStatementRoutingEngine.java
@@ -17,17 +17,70 @@
 
 package org.apache.shardingsphere.shadow.route.future.engine.dml;
 
-import org.apache.shardingsphere.infra.route.context.RouteContext;
-import org.apache.shardingsphere.shadow.route.future.engine.ShadowRouteEngine;
-import org.apache.shardingsphere.shadow.rule.ShadowRule;
+import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.DeleteStatementContext;
+import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
+import 
org.apache.shardingsphere.shadow.route.future.engine.AbstractShadowRouteEngine;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
+import 
org.apache.shardingsphere.shadow.route.future.engine.util.ShadowExtractor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.util.ColumnExtractor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.util.ExpressionExtractUtil;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
 
 /**
  * Shadow delete statement routing engine.
  */
-public final class ShadowDeleteStatementRoutingEngine implements 
ShadowRouteEngine {
+@RequiredArgsConstructor
+public final class ShadowDeleteStatementRoutingEngine extends 
AbstractShadowRouteEngine {
+    
+    private final DeleteStatementContext deleteStatementContext;
+    
+    private final List<Object> parameters;
+    
+    @Override
+    protected Optional<Collection<ShadowColumnCondition>> 
parseShadowColumnConditions() {
+        Collection<ShadowColumnCondition> result = new LinkedList<>();
+        deleteStatementContext.getWhere().ifPresent(whereSegment -> 
parseWhereSegment(whereSegment, result));
+        return result.isEmpty() ? Optional.empty() : Optional.of(result);
+    }
+    
+    private void parseWhereSegment(final WhereSegment whereSegment, final 
Collection<ShadowColumnCondition> shadowColumnConditions) {
+        
ExpressionExtractUtil.getAndPredicates(whereSegment.getExpr()).forEach(each -> 
parseAndPredicate(each.getPredicates(), shadowColumnConditions));
+    }
+    
+    private void parseAndPredicate(final Collection<ExpressionSegment> 
predicates, final Collection<ShadowColumnCondition> shadowColumnConditions) {
+        predicates.forEach(each -> parseExpressionSegment(each, 
shadowColumnConditions));
+    }
+    
+    private void parseExpressionSegment(final ExpressionSegment 
expressionSegment, final Collection<ShadowColumnCondition> 
shadowColumnConditions) {
+        ColumnExtractor.extract(expressionSegment).ifPresent(segment -> 
ShadowExtractor.extractValues(expressionSegment, parameters)
+                .ifPresent(values -> shadowColumnConditions.add(new 
ShadowColumnCondition(segment.getIdentifier().getValue(), values))));
+    }
+    
+    @Override
+    protected ShadowDetermineCondition createShadowDetermineCondition() {
+        return new ShadowDetermineCondition(ShadowOperationType.DELETE);
+    }
+    
+    @Override
+    protected Collection<SimpleTableSegment> getAllTables() {
+        return deleteStatementContext.getAllTables();
+    }
     
+    // FIXME refactor the method when sql parses the note and puts it in the 
statement context
     @Override
-    public void route(final RouteContext routeContext, final ShadowRule 
shadowRule) {
-        // TODO decorate route in delete statement case
+    protected Optional<Collection<String>> parseSqlNotes() {
+        Collection<String> result = new LinkedList<>();
+        result.add("/*foo=bar,shadow=true*/");
+        result.add("/*aaa=bbb*/");
+        return Optional.of(result);
     }
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngine.java
index 072a93c..ee08bc6 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngine.java
@@ -22,15 +22,14 @@ import 
org.apache.shardingsphere.infra.binder.segment.insert.values.InsertValueC
 import 
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 import 
org.apache.shardingsphere.shadow.route.future.engine.AbstractShadowRouteEngine;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 
 import java.util.Collection;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -42,8 +41,8 @@ public final class ShadowInsertStatementRoutingEngine extends 
AbstractShadowRout
     private final InsertStatementContext insertStatementContext;
     
     @Override
-    protected Optional<Map<String, Collection<Comparable<?>>>> 
parseColumnValuesMappings() {
-        Map<String, Collection<Comparable<?>>> result = new LinkedHashMap<>();
+    protected Optional<Collection<ShadowColumnCondition>> 
parseShadowColumnConditions() {
+        Collection<ShadowColumnCondition> result = new LinkedList<>();
         Collection<String> columnNames = parseColumnNames();
         Iterator<String> columnNamesIt = columnNames.iterator();
         List<InsertValueContext> insertValueContexts = 
insertStatementContext.getInsertValueContexts();
@@ -51,7 +50,7 @@ public final class ShadowInsertStatementRoutingEngine extends 
AbstractShadowRout
         while (columnNamesIt.hasNext()) {
             String columnName = columnNamesIt.next();
             Optional<Collection<Comparable<?>>> columnValues = 
getColumnValues(insertValueContexts, index);
-            columnValues.ifPresent(values -> result.put(columnName, values));
+            columnValues.ifPresent(values -> result.add(new 
ShadowColumnCondition(columnName, values)));
             index++;
         }
         return result.isEmpty() ? Optional.empty() : Optional.of(result);
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowUpdateStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowUpdateStatementRoutingEngine.java
index be3b6d7..bb559e5 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowUpdateStatementRoutingEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowUpdateStatementRoutingEngine.java
@@ -21,20 +21,18 @@ import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.UpdateStatementContext;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 import 
org.apache.shardingsphere.shadow.route.future.engine.AbstractShadowRouteEngine;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.util.ShadowExtractor;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.util.ColumnExtractor;
 import 
org.apache.shardingsphere.sql.parser.sql.common.util.ExpressionExtractUtil;
 
 import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -48,40 +46,23 @@ public final class ShadowUpdateStatementRoutingEngine 
extends AbstractShadowRout
     private final List<Object> parameters;
     
     @Override
-    protected Optional<Map<String, Collection<Comparable<?>>>> 
parseColumnValuesMappings() {
-        Map<String, Collection<Comparable<?>>> result = new LinkedHashMap<>();
-        Optional<WhereSegment> where = updateStatementContext.getWhere();
-        where.ifPresent(whereSegment -> parseWhereSegment(whereSegment, 
result));
+    protected Optional<Collection<ShadowColumnCondition>> 
parseShadowColumnConditions() {
+        Collection<ShadowColumnCondition> result = new LinkedList<>();
+        updateStatementContext.getWhere().ifPresent(whereSegment -> 
parseWhereSegment(whereSegment, result));
         return result.isEmpty() ? Optional.empty() : Optional.of(result);
     }
     
-    private void parseWhereSegment(final WhereSegment whereSegment, final 
Map<String, Collection<Comparable<?>>> columnValuesMappings) {
-        
ExpressionExtractUtil.getAndPredicates(whereSegment.getExpr()).forEach(each -> 
parseAndPredicate(each.getPredicates(), columnValuesMappings));
+    private void parseWhereSegment(final WhereSegment whereSegment, final 
Collection<ShadowColumnCondition> shadowColumnConditions) {
+        
ExpressionExtractUtil.getAndPredicates(whereSegment.getExpr()).forEach(each -> 
parseAndPredicate(each.getPredicates(), shadowColumnConditions));
     }
     
-    private void parseAndPredicate(final Collection<ExpressionSegment> 
predicates, final Map<String, Collection<Comparable<?>>> columnValuesMappings) {
-        for (ExpressionSegment each : predicates) {
-            parseExpressionSegment(each, columnValuesMappings);
-        }
+    private void parseAndPredicate(final Collection<ExpressionSegment> 
predicates, final Collection<ShadowColumnCondition> shadowColumnConditions) {
+        predicates.forEach(each -> parseExpressionSegment(each, 
shadowColumnConditions));
     }
     
-    private void parseExpressionSegment(final ExpressionSegment 
expressionSegment, final Map<String, Collection<Comparable<?>>> 
columnValuesMappings) {
-        if (expressionSegment instanceof BinaryOperationExpression) {
-            parseBinaryOperationExpression((BinaryOperationExpression) 
expressionSegment, columnValuesMappings);
-        }
-        if (expressionSegment instanceof InExpression) {
-            parseInExpression((InExpression) expressionSegment, 
columnValuesMappings);
-        }
-    }
-    
-    private void parseInExpression(final InExpression expression, final 
Map<String, Collection<Comparable<?>>> columnValuesMappings) {
-        Optional<String> columnName = 
ShadowExtractor.extractColumnName(expression);
-        columnName.ifPresent(s -> 
ShadowExtractor.extractValues(expression.getRight(), 
parameters).ifPresent(values -> columnValuesMappings.put(s, values)));
-    }
-    
-    private void parseBinaryOperationExpression(final 
BinaryOperationExpression expression, final Map<String, 
Collection<Comparable<?>>> columnValuesMappings) {
-        Optional<String> columnName = 
ShadowExtractor.extractColumnName(expression);
-        columnName.ifPresent(s -> 
ShadowExtractor.extractValues(expression.getRight(), 
parameters).ifPresent(values -> columnValuesMappings.put(s, values)));
+    private void parseExpressionSegment(final ExpressionSegment 
expressionSegment, final Collection<ShadowColumnCondition> 
shadowColumnConditions) {
+        ColumnExtractor.extract(expressionSegment).ifPresent(segment -> 
ShadowExtractor.extractValues(expressionSegment, parameters)
+                .ifPresent(values -> shadowColumnConditions.add(new 
ShadowColumnCondition(segment.getIdentifier().getValue(), values))));
     }
     
     @Override
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/util/ShadowExtractor.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/util/ShadowExtractor.java
index 612e90d..33fae08 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/util/ShadowExtractor.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/util/ShadowExtractor.java
@@ -19,7 +19,6 @@ package 
org.apache.shardingsphere.shadow.route.future.engine.util;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
@@ -40,44 +39,6 @@ import java.util.Optional;
 public final class ShadowExtractor {
     
     /**
-     * Get left value binary operation Expression if left value expression is 
column segment.
-     *
-     * @param expression binary operation expression
-     * @return column name
-     */
-    public static Optional<String> extractColumnName(final 
BinaryOperationExpression expression) {
-        ExpressionSegment left = expression.getLeft();
-        if (left instanceof ColumnSegment) {
-            return Optional.of(extractColumnName((ColumnSegment) left));
-        }
-        return Optional.empty();
-    }
-    
-    /**
-     * Get left value in Expression if left value expression is column segment.
-     *
-     * @param expression in expression
-     * @return column name
-     */
-    public static Optional<String> extractColumnName(final InExpression 
expression) {
-        ExpressionSegment left = expression.getLeft();
-        if (left instanceof ColumnSegment) {
-            return Optional.of(extractColumnName((ColumnSegment) left));
-        }
-        return Optional.empty();
-    }
-    
-    /**
-     * Get value in column segment.
-     *
-     * @param columnSegment column segment
-     * @return column name
-     */
-    private static String extractColumnName(final ColumnSegment columnSegment) 
{
-        return columnSegment.getIdentifier().getValue();
-    }
-    
-    /**
      * Get values in expression segment.
      *
      * @param expression expression segment
@@ -86,22 +47,18 @@ public final class ShadowExtractor {
      */
     public static Optional<Collection<Comparable<?>>> extractValues(final 
ExpressionSegment expression, final List<Object> parameters) {
         Collection<Comparable<?>> result = new LinkedList<>();
-        if (expression instanceof SimpleExpressionSegment) {
-            Optional<Comparable<?>> value = 
extractValueInSimpleExpressionSegment(expression, parameters);
-            value.ifPresent(result::add);
+        if (expression instanceof BinaryOperationExpression) {
+            extractValues(((BinaryOperationExpression) expression).getRight(), 
parameters).ifPresent(result::addAll);
         }
-        if (expression instanceof ListExpression) {
-            Optional<Collection<Comparable<?>>> values = 
extractValuesInListExpression(expression, parameters);
-            values.ifPresent(result::addAll);
+        if (expression instanceof InExpression) {
+            extractValues(((InExpression) expression).getRight(), 
parameters).ifPresent(result::addAll);
         }
-        return result.isEmpty() ? Optional.empty() : Optional.of(result);
-    }
-    
-    private static Optional<Collection<Comparable<?>>> 
extractValuesInListExpression(final ExpressionSegment expression, final 
List<Object> parameters) {
-        Collection<Comparable<?>> result = new LinkedList<>();
         if (expression instanceof ListExpression) {
             ((ListExpression) expression).getItems().forEach(each -> 
extractValueInSimpleExpressionSegment(each, parameters).ifPresent(result::add));
         }
+        if (expression instanceof SimpleExpressionSegment) {
+            extractValueInSimpleExpressionSegment(expression, 
parameters).ifPresent(result::add);
+        }
         return result.isEmpty() ? Optional.empty() : Optional.of(result);
     }
     
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/ColumnShadowAlgorithmDeterminerTest.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/ColumnShadowAlgorithmDeterminerTest.java
index f554783..ccba7fd 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/ColumnShadowAlgorithmDeterminerTest.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/ColumnShadowAlgorithmDeterminerTest.java
@@ -24,6 +24,7 @@ import 
org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguratio
 import 
org.apache.shardingsphere.shadow.api.shadow.column.ColumnShadowAlgorithm;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowAlgorithmDeterminer;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import org.apache.shardingsphere.shadow.rule.ShadowRule;
 import org.apache.shardingsphere.shadow.spi.ShadowAlgorithm;
@@ -120,15 +121,15 @@ public final class ColumnShadowAlgorithmDeterminerTest {
     
     private ShadowDetermineCondition createShadowDetermineCondition() {
         ShadowDetermineCondition shadowDetermineCondition = new 
ShadowDetermineCondition(ShadowOperationType.INSERT);
-        
shadowDetermineCondition.initColumnValuesMappings(createColumnValuesMappings());
+        
shadowDetermineCondition.initShadowColumnCondition(createColumnValuesMappings());
         return shadowDetermineCondition;
     }
     
-    private Map<String, Collection<Comparable<?>>> 
createColumnValuesMappings() {
-        Map<String, Collection<Comparable<?>>> result = new LinkedHashMap<>();
+    private Collection<ShadowColumnCondition> createColumnValuesMappings() {
+        Collection<ShadowColumnCondition> result = new LinkedList<>();
         Collection<Comparable<?>> values = new LinkedList<>();
         values.add(1);
-        result.put("user_id", values);
+        result.add(new ShadowColumnCondition("user_id", values));
         return result;
     }
 }

Reply via email to