You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/10/22 05:18:18 UTC

[shardingsphere] branch master updated: support subquery sql node convert to sql statement (#13214)

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 32202c0  support subquery sql node convert to sql statement (#13214)
32202c0 is described below

commit 32202c001aa4b667cf129aa3f3a944d58c960e75
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Fri Oct 22 13:17:27 2021 +0800

    support subquery sql node convert to sql statement (#13214)
    
    * add some case for sql node convert to sql statement
    
    * support case one sql node convert to sql statement
    
    * support more case sql node convert to sql statement
    
    * revert config file
    
    * support subquery convert to sql statement
    
    * adjust unit test
    
    * rename method name
    
    * rename method name
    
    * optimize code
    
    * fix checkstyle
    
    * delete useless file
---
 .../converter/segment/SQLSegmentConverter.java     | 20 ++++++++
 .../segment/expression/ExpressionConverter.java    | 57 ++++++++++++++++++++--
 .../impl/BetweenExpressionConverter.java           | 24 +++++++--
 .../impl/BinaryOperationExpressionConverter.java   | 23 +++++----
 .../segment/expression/impl/ColumnConverter.java   | 21 ++++++--
 .../impl/ExistsSubqueryExpressionConverter.java    | 26 ++++++++--
 .../expression/impl/InExpressionConverter.java     | 23 +++++++--
 .../impl/LiteralExpressionConverter.java           |  5 ++
 .../impl/SubqueryExpressionConverter.java          | 11 ++++-
 .../converter/segment/from/TableConverter.java     | 17 ++++---
 .../segment/from/impl/JoinTableConverter.java      |  6 +--
 .../segment/from/impl/SimpleTableConverter.java    | 13 +++++
 .../segment/from/impl/SubqueryTableConverter.java  | 19 ++++++--
 .../segment/groupby/GroupByConverter.java          |  3 +-
 .../segment/orderby/OrderByConverter.java          | 12 +++--
 .../orderby/item/ColumnOrderByItemConverter.java   | 12 ++++-
 .../orderby/item/OrderByItemConverterUtil.java     | 26 ++++++++--
 .../segment/projection/ProjectionsConverter.java   | 33 +++++++++----
 .../impl/AggregationProjectionConverter.java       | 14 ++++--
 .../projection/impl/ColumnProjectionConverter.java |  8 +--
 .../impl/ExpressionProjectionConverter.java        |  5 +-
 .../impl/ShorthandProjectionConverter.java         | 19 ++++++--
 .../impl/SubqueryProjectionConverter.java          | 14 ++++++
 .../converter/segment/where/WhereConverter.java    |  9 +++-
 24 files changed, 334 insertions(+), 86 deletions(-)

diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/SQLSegmentConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/SQLSegmentConverter.java
index 6c201b7..1ca48a0 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/SQLSegmentConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/SQLSegmentConverter.java
@@ -45,4 +45,24 @@ public interface SQLSegmentConverter<S extends SQLSegment, T extends SqlNode> {
      * @return converted SQL segment
      */
     Optional<S> convertToSQLSegment(T sqlNode);
+    
+    /**
+     * Get start index.
+     * 
+     * @param sqlNode SQL node
+     * @return start index
+     */
+    default int getStartIndex(SqlNode sqlNode) {
+        return sqlNode.getParserPosition().getColumnNum() - 1;
+    }
+    
+    /**
+     * Get stop index.
+     *
+     * @param sqlNode SQL node
+     * @return stop index
+     */
+    default int getStopIndex(SqlNode sqlNode) {
+        return sqlNode.getParserPosition().getEndColumnNum() - 1;
+    }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/ExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/ExpressionConverter.java
index 6149f81..92b6fb0 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/ExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/ExpressionConverter.java
@@ -17,7 +17,16 @@
 
 package org.apache.shardingsphere.infra.optimize.converter.segment.expression;
 
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlBinaryOperator;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.fun.SqlBetweenOperator;
+import org.apache.calcite.sql.fun.SqlInOperator;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.BetweenExpressionConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.BinaryOperationExpressionConverter;
@@ -58,23 +67,61 @@ public final class ExpressionConverter implements SQLSegmentConverter<Expression
         } else if (segment instanceof ListExpression) {
             return new ListExpressionConverter().convertToSQLNode((ListExpression) segment);
         } else if (segment instanceof BinaryOperationExpression) {
-            return new BinaryOperationExpressionConverter().convertToSQLNode((BinaryOperationExpression) segment);
+            return new BinaryOperationExpressionConverter().convertToSQLNode((BinaryOperationExpression) segment).map(optional -> optional);
         } else if (segment instanceof ColumnSegment) {
-            return new ColumnConverter().convertToSQLNode((ColumnSegment) segment);
+            return new ColumnConverter().convertToSQLNode((ColumnSegment) segment).map(optional -> optional);
         } else if (segment instanceof ExistsSubqueryExpression) {
-            return new ExistsSubqueryExpressionConverter().convertToSQLNode((ExistsSubqueryExpression) segment);
+            return new ExistsSubqueryExpressionConverter().convertToSQLNode((ExistsSubqueryExpression) segment).map(optional -> optional);
         } else if (segment instanceof SubqueryExpressionSegment) {
             return new SubqueryExpressionConverter().convertToSQLNode((SubqueryExpressionSegment) segment);
         } else if (segment instanceof InExpression) {
-            return new InExpressionConverter().convertToSQLNode((InExpression) segment);
+            return new InExpressionConverter().convertToSQLNode((InExpression) segment).map(optional -> optional);
         } else if (segment instanceof BetweenExpression) {
-            return new BetweenExpressionConverter().convertToSQLNode((BetweenExpression) segment);
+            return new BetweenExpressionConverter().convertToSQLNode((BetweenExpression) segment).map(optional -> optional);
         }
         throw new UnsupportedOperationException("unsupported TableSegment type: " + segment.getClass());
     }
     
     @Override
     public Optional<ExpressionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+        if (null == sqlNode) {
+            return Optional.empty(); 
+        }
+        if (sqlNode instanceof SqlIdentifier) {
+            return new ColumnConverter().convertToSQLSegment((SqlIdentifier) sqlNode).map(optional -> optional);
+        }
+        if (sqlNode instanceof SqlBasicCall) {
+            return convertToSQLSegment((SqlBasicCall) sqlNode, false);
+        }
+        if (sqlNode instanceof SqlSelect) {
+            return new SubqueryExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+        }
+        if (sqlNode instanceof SqlLiteral) {
+            return new LiteralExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+        }
+        return Optional.empty();
+    }
+    
+    private Optional<ExpressionSegment> convertToSQLSegment(final SqlBasicCall sqlBasicCall, final boolean not) {
+        if (null == sqlBasicCall) {
+            return Optional.empty();
+        }
+        SqlOperator operator = sqlBasicCall.getOperator();
+        if (operator.getName().equals(SqlStdOperatorTable.NOT.getName()) && sqlBasicCall.getOperandList().get(0) instanceof SqlBasicCall) {
+            return convertToSQLSegment((SqlBasicCall) sqlBasicCall.getOperandList().get(0), true);
+        }
+        if (operator instanceof SqlInOperator) {
+            return new InExpressionConverter(not).convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+        }
+        if (operator instanceof SqlBetweenOperator) {
+            return new BetweenExpressionConverter(not).convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+        }
+        if (operator.getName().equals(SqlStdOperatorTable.EXISTS.getName())) {
+            return new ExistsSubqueryExpressionConverter(not).convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+        }
+        if (operator instanceof SqlBinaryOperator) {
+            return new BinaryOperationExpressionConverter().convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+        }
         return Optional.empty();
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
index 62817a36..ec2622c 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BetweenExpressionConverter.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
 
+import lombok.RequiredArgsConstructor;
 import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -24,6 +25,7 @@ import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.expression.ExpressionConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 
 import java.util.Collection;
 import java.util.LinkedList;
@@ -32,10 +34,17 @@ import java.util.Optional;
 /**
  * Between expression converter.
  */
-public final class BetweenExpressionConverter implements SQLSegmentConverter<BetweenExpression, SqlNode> {
+@RequiredArgsConstructor
+public final class BetweenExpressionConverter implements SQLSegmentConverter<BetweenExpression, SqlBasicCall> {
+    
+    private final boolean not;
+
+    public BetweenExpressionConverter() {
+        not = false;
+    }
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final BetweenExpression expression) {
+    public Optional<SqlBasicCall> convertToSQLNode(final BetweenExpression expression) {
         if (null == expression) {
             return Optional.empty();
         }
@@ -49,7 +58,14 @@ public final class BetweenExpressionConverter implements SQLSegmentConverter<Bet
     }
     
     @Override
-    public Optional<BetweenExpression> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+    public Optional<BetweenExpression> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+        if (null == sqlBasicCall) {
+            return Optional.empty();
+        }
+        ExpressionConverter expressionConverter = new ExpressionConverter();
+        ExpressionSegment between = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(1)).orElseThrow(IllegalStateException::new);
+        ExpressionSegment and = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(2)).orElseThrow(IllegalStateException::new);
+        ExpressionSegment left = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(0)).orElseThrow(IllegalStateException::new);
+        return Optional.of(new BetweenExpression(left.getStartIndex(), and.getStopIndex(), left, between, and, not));
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BinaryOperationExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BinaryOperationExpressionConverter.java
index bd42865..459c967 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BinaryOperationExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/BinaryOperationExpressionConverter.java
@@ -35,7 +35,7 @@ import java.util.TreeMap;
 /**
  * Binary operation expression converter.
  */
-public final class BinaryOperationExpressionConverter implements SQLSegmentConverter<BinaryOperationExpression, SqlNode> {
+public final class BinaryOperationExpressionConverter implements SQLSegmentConverter<BinaryOperationExpression, SqlBasicCall> {
     
     private static final Map<String, SqlBinaryOperator> REGISTRY = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
     
@@ -59,26 +59,25 @@ public final class BinaryOperationExpressionConverter implements SQLSegmentConve
     }
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final BinaryOperationExpression segment) {
+    public Optional<SqlBasicCall> convertToSQLNode(final BinaryOperationExpression segment) {
         SqlBinaryOperator operator = convertOperator(segment.getOperator());
-        SqlNode left = convertExpression(segment.getLeft());
-        SqlNode right = convertExpression(segment.getRight());
+        SqlNode left = new ExpressionConverter().convertToSQLNode(segment.getLeft()).orElseThrow(IllegalStateException::new);
+        SqlNode right = new ExpressionConverter().convertToSQLNode(segment.getRight()).orElseThrow(IllegalStateException::new);
         return Optional.of(new SqlBasicCall(operator, new SqlNode[] {left, right}, SqlParserPos.ZERO));
     }
     
     @Override
-    public Optional<BinaryOperationExpression> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+    public Optional<BinaryOperationExpression> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+        ExpressionConverter expressionConverter = new ExpressionConverter();
+        ExpressionSegment left = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(0)).orElseThrow(IllegalStateException::new);
+        ExpressionSegment right = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(1)).orElseThrow(IllegalStateException::new);
+        String operator = sqlBasicCall.getOperator().getName();
+        String text = sqlBasicCall.toString();
+        return Optional.of(new BinaryOperationExpression(getStartIndex(sqlBasicCall), getStopIndex(sqlBasicCall), left, right, operator, text));
     }
     
     private SqlBinaryOperator convertOperator(final String operator) {
         Preconditions.checkState(REGISTRY.containsKey(operator), "Unsupported SQL operator: `%s`", operator);
         return REGISTRY.get(operator);
     }
-    
-    private SqlNode convertExpression(final ExpressionSegment segment) {
-        Optional<SqlNode> result = new ExpressionConverter().convertToSQLNode(segment);
-        Preconditions.checkState(result.isPresent());
-        return result.get();
-    }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java
index fc43323..14e8934 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ColumnConverter.java
@@ -17,12 +17,13 @@
 
 package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.calcite.sql.SqlIdentifier;
-import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Arrays;
 import java.util.Optional;
@@ -30,10 +31,10 @@ import java.util.Optional;
 /**
  * Column converter.
  */
-public final class ColumnConverter implements SQLSegmentConverter<ColumnSegment, SqlNode> {
+public final class ColumnConverter implements SQLSegmentConverter<ColumnSegment, SqlIdentifier> {
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final ColumnSegment segment) {
+    public Optional<SqlIdentifier> convertToSQLNode(final ColumnSegment segment) {
         Optional<OwnerSegment> owner = segment.getOwner();
         String columnName = segment.getIdentifier().getValue();
         SqlIdentifier sqlIdentifier = owner.map(optional 
@@ -42,7 +43,17 @@ public final class ColumnConverter implements SQLSegmentConverter<ColumnSegment,
     }
     
     @Override
-    public Optional<ColumnSegment> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+    public Optional<ColumnSegment> convertToSQLSegment(final SqlIdentifier sqlIdentifier) {
+        if (null == sqlIdentifier) {
+            return Optional.empty();
+        }
+        ImmutableList<String> names = sqlIdentifier.names;
+        if (1 == names.size()) {
+            return Optional.of(new ColumnSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier), new IdentifierValue(names.get(0))));    
+        }
+        ColumnSegment result = new ColumnSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier), new IdentifierValue(names.get(1)));
+        SqlIdentifier owner = sqlIdentifier.getComponent(0);
+        result.setOwner(new OwnerSegment(getStartIndex(owner), getStopIndex(owner), new IdentifierValue(names.get(0))));
+        return Optional.of(result);
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
index 49bdab5..db108d9 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/ExistsSubqueryExpressionConverter.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
 
+import lombok.RequiredArgsConstructor;
 import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -24,16 +25,25 @@ import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExistsSubqueryExpression;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 
 import java.util.Optional;
 
 /**
  * Exists subquery expression converter.
  */
-public final class ExistsSubqueryExpressionConverter implements SQLSegmentConverter<ExistsSubqueryExpression, SqlNode> {
+@RequiredArgsConstructor
+public final class ExistsSubqueryExpressionConverter implements SQLSegmentConverter<ExistsSubqueryExpression, SqlBasicCall> {
+    
+    private final boolean not;
+    
+    public ExistsSubqueryExpressionConverter() {
+        not = false;
+    }
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final ExistsSubqueryExpression expression) {
+    public Optional<SqlBasicCall> convertToSQLNode(final ExistsSubqueryExpression expression) {
         if (null == expression) {
             return Optional.empty();
         }
@@ -42,7 +52,15 @@ public final class ExistsSubqueryExpressionConverter implements SQLSegmentConver
     }
     
     @Override
-    public Optional<ExistsSubqueryExpression> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+    public Optional<ExistsSubqueryExpression> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+        if (null == sqlBasicCall) {
+            return Optional.empty();
+        }
+        SqlNode subquerySqlNode = sqlBasicCall.getOperandList().get(0);
+        SelectStatement selectStatement = new SelectStatementConverter().convertToSQLStatement(subquerySqlNode);
+        SubquerySegment subquery = new SubquerySegment(getStartIndex(subquerySqlNode) - 1, getStopIndex(subquerySqlNode) + 1, selectStatement);
+        ExistsSubqueryExpression result = new ExistsSubqueryExpression(getStartIndex(sqlBasicCall), subquery.getStopIndex(), subquery);
+        result.setNot(not);
+        return Optional.of(result);
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
index 4285531..b5e0a2a 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/InExpressionConverter.java
@@ -17,12 +17,14 @@
 
 package org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl;
 
+import lombok.RequiredArgsConstructor;
 import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.expression.ExpressionConverter;
+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 java.util.Collection;
@@ -32,10 +34,17 @@ import java.util.Optional;
 /**
  * In expression converter.
  */
-public final class InExpressionConverter implements SQLSegmentConverter<InExpression, SqlNode> {
+@RequiredArgsConstructor
+public final class InExpressionConverter implements SQLSegmentConverter<InExpression, SqlBasicCall> {
+    
+    private final boolean not;
+    
+    public InExpressionConverter() {
+        not = false;
+    }
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final InExpression expression) {
+    public Optional<SqlBasicCall> convertToSQLNode(final InExpression expression) {
         if (null == expression) {
             return Optional.empty();
         }
@@ -48,7 +57,13 @@ public final class InExpressionConverter implements SQLSegmentConverter<InExpres
     }
     
     @Override
-    public Optional<InExpression> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+    public Optional<InExpression> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+        if (null == sqlBasicCall) {
+            return Optional.empty();
+        }
+        ExpressionConverter expressionConverter = new ExpressionConverter();
+        ExpressionSegment left = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(0)).orElseThrow(IllegalStateException::new);
+        ExpressionSegment right = expressionConverter.convertToSQLSegment(sqlBasicCall.getOperandList().get(1)).orElseThrow(IllegalStateException::new);
+        return Optional.of(new InExpression(getStartIndex(sqlBasicCall), getStopIndex(sqlBasicCall) + 1, left, right, not));
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/LiteralExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/LiteralExpressionConverter.java
index c418181..9612494 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/LiteralExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/LiteralExpressionConverter.java
@@ -22,6 +22,7 @@ import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtil;
 
 import java.util.Optional;
 
@@ -43,6 +44,10 @@ public final class LiteralExpressionConverter implements SQLSegmentConverter<Lit
     
     @Override
     public Optional<LiteralExpressionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+        if (sqlNode instanceof SqlLiteral) {
+            SqlLiteral sqlLiteral = (SqlLiteral) sqlNode;
+            return Optional.of(new LiteralExpressionSegment(getStartIndex(sqlLiteral), getStopIndex(sqlLiteral), SQLUtil.getExactlyValue(sqlLiteral.toValue())));
+        }
         return Optional.empty();
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
index dc6ad1b..2fbafd8 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/expression/impl/SubqueryExpressionConverter.java
@@ -21,6 +21,8 @@ import org.apache.calcite.sql.SqlNode;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 
 import java.util.Optional;
 
@@ -39,6 +41,13 @@ public final class SubqueryExpressionConverter implements SQLSegmentConverter<Su
     
     @Override
     public Optional<SubqueryExpressionSegment> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+        if (null == sqlNode) {
+            return Optional.empty();
+        }
+        SelectStatement selectStatement = new SelectStatementConverter().convertToSQLStatement(sqlNode);
+        // FIXME subquery projection position returned by the CalCite parser does not contain two brackets
+        int startIndex = getStartIndex(sqlNode) - 1;
+        int stopIndex = getStopIndex(sqlNode) + 1;
+        return Optional.of(new SubqueryExpressionSegment(new SubquerySegment(startIndex, stopIndex, selectStatement)));
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/TableConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/TableConverter.java
index 954e6d8..8ef0033 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/TableConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/TableConverter.java
@@ -42,21 +42,22 @@ public final class TableConverter implements SQLSegmentConverter<TableSegment, S
         if (segment instanceof SimpleTableSegment) {
             return new SimpleTableConverter().convertToSQLNode((SimpleTableSegment) segment);
         } else if (segment instanceof JoinTableSegment) {
-            return new JoinTableConverter().convertToSQLNode((JoinTableSegment) segment);
+            return new JoinTableConverter().convertToSQLNode((JoinTableSegment) segment).map(optional -> optional);
         } else if (segment instanceof SubqueryTableSegment) {
-            return new SubqueryTableConverter().convertToSQLNode((SubqueryTableSegment) segment);
+            return new SubqueryTableConverter().convertToSQLNode((SubqueryTableSegment) segment).map(optional -> optional);
         }
-        throw new UnsupportedOperationException("Unsupported segment segment type: " + segment.getClass());
+        throw new UnsupportedOperationException("Unsupported segment type: " + segment.getClass());
     }
     
     @Override
     public Optional<TableSegment> convertToSQLSegment(final SqlNode sqlNode) {
-        if (sqlNode instanceof SqlBasicCall || sqlNode instanceof SqlIdentifier) {
+        if (sqlNode instanceof SqlIdentifier) {
             return new SimpleTableConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+        } else if (sqlNode instanceof SqlJoin) {
+            return new JoinTableConverter().convertToSQLSegment((SqlJoin) sqlNode).map(optional -> optional);
+        } else if (sqlNode instanceof SqlBasicCall) {
+            return new SubqueryTableConverter().convertToSQLSegment((SqlBasicCall) sqlNode).map(optional -> optional);
         }
-        if (sqlNode instanceof SqlJoin) {
-            return new JoinTableConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
-        }
-        return Optional.empty();
+        throw new UnsupportedOperationException("Unsupported sql node type: " + sqlNode.getClass());
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/JoinTableConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/JoinTableConverter.java
index 4160080..ac6b7b7 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/JoinTableConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/JoinTableConverter.java
@@ -33,7 +33,7 @@ import java.util.Optional;
 /**
  * Join converter.
  */
-public final class JoinTableConverter implements SQLSegmentConverter<JoinTableSegment, SqlNode> {
+public final class JoinTableConverter implements SQLSegmentConverter<JoinTableSegment, SqlJoin> {
     
     private static final String JOIN_TYPE_INNER = "INNER";
     
@@ -44,7 +44,7 @@ public final class JoinTableConverter implements SQLSegmentConverter<JoinTableSe
     private static final String JOIN_TYPE_FULL = "FULL";
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final JoinTableSegment segment) {
+    public Optional<SqlJoin> convertToSQLNode(final JoinTableSegment segment) {
         SqlNode left = new TableConverter().convertToSQLNode(segment.getLeft()).orElseThrow(IllegalStateException::new);
         SqlNode right = new TableConverter().convertToSQLNode(segment.getRight()).orElseThrow(IllegalStateException::new);
         Optional<SqlNode> condition = new ExpressionConverter().convertToSQLNode(segment.getCondition());
@@ -54,7 +54,7 @@ public final class JoinTableConverter implements SQLSegmentConverter<JoinTableSe
     }
     
     @Override
-    public Optional<JoinTableSegment> convertToSQLSegment(final SqlNode sqlNode) {
+    public Optional<JoinTableSegment> convertToSQLSegment(final SqlJoin sqlJoin) {
         return Optional.empty();
     }
     
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SimpleTableConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SimpleTableConverter.java
index 83f17c9..300baed 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SimpleTableConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SimpleTableConverter.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.infra.optimize.converter.segment.from.impl;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlNode;
@@ -25,6 +26,7 @@ import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
 
@@ -46,6 +48,17 @@ public final class SimpleTableConverter implements SQLSegmentConverter<SimpleTab
     
     @Override
     public Optional<SimpleTableSegment> convertToSQLSegment(final SqlNode sqlNode) {
+        if (sqlNode instanceof SqlBasicCall) {
+            SqlBasicCall sqlBasicCall = (SqlBasicCall) sqlNode;
+            if (sqlBasicCall.getOperator().equals(SqlStdOperatorTable.AS)) {
+                ImmutableList<String> names = ((SqlIdentifier) sqlBasicCall.getOperandList().get(0)).names;
+                SimpleTableSegment tableSegment = new SimpleTableSegment(new TableNameSegment(getStartIndex(sqlNode), getStopIndex(sqlNode), new IdentifierValue(names.get(0))));
+                return Optional.of(tableSegment);
+            }
+        }
+        if (sqlNode instanceof SqlIdentifier) {
+            return Optional.of(new SimpleTableSegment(new TableNameSegment(getStartIndex(sqlNode), getStopIndex(sqlNode), new IdentifierValue(((SqlIdentifier) sqlNode).names.get(0)))));
+        }
         return Optional.empty();
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SubqueryTableConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SubqueryTableConverter.java
index ab2611f..fad90b0 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SubqueryTableConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/from/impl/SubqueryTableConverter.java
@@ -24,7 +24,11 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.LinkedList;
@@ -33,10 +37,10 @@ import java.util.Optional;
 /**
  * Subquery table converter.
  */
-public final class SubqueryTableConverter implements SQLSegmentConverter<SubqueryTableSegment, SqlNode> {
+public final class SubqueryTableConverter implements SQLSegmentConverter<SubqueryTableSegment, SqlBasicCall> {
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final SubqueryTableSegment segment) {
+    public Optional<SqlBasicCall> convertToSQLNode(final SubqueryTableSegment segment) {
         if (null == segment) {
             return Optional.empty();
         }
@@ -47,7 +51,14 @@ public final class SubqueryTableConverter implements SQLSegmentConverter<Subquer
     }
     
     @Override
-    public Optional<SubqueryTableSegment> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+    public Optional<SubqueryTableSegment> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+        SqlNode select = sqlBasicCall.getOperandList().get(0);
+        SelectStatement selectStatement = new SelectStatementConverter().convertToSQLStatement(select);
+        SubqueryTableSegment result = new SubqueryTableSegment(new SubquerySegment(getStartIndex(sqlBasicCall), getStopIndex(sqlBasicCall), selectStatement));
+        if (sqlBasicCall.getOperator().equals(SqlStdOperatorTable.AS)) {
+            SqlNode alias = sqlBasicCall.getOperandList().get(1);
+            result.setAlias(new AliasSegment(getStartIndex(alias), getStopIndex(alias), new IdentifierValue(alias.toString())));   
+        }
+        return Optional.of(result);
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/groupby/GroupByConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/groupby/GroupByConverter.java
index 6e94a3e..8603830 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/groupby/GroupByConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/groupby/GroupByConverter.java
@@ -32,7 +32,8 @@ public final class GroupByConverter implements SQLSegmentConverter<GroupBySegmen
     
     @Override
     public Optional<SqlNodeList> convertToSQLNode(final GroupBySegment segment) {
-        return null == segment || segment.getGroupByItems().isEmpty() ? Optional.empty() : Optional.of(new SqlNodeList(OrderByItemConverterUtil.convert(segment.getGroupByItems()), SqlParserPos.ZERO));
+        return null == segment || segment.getGroupByItems().isEmpty() 
+                ? Optional.empty() : Optional.of(new SqlNodeList(OrderByItemConverterUtil.convertToSQLNode(segment.getGroupByItems()), SqlParserPos.ZERO));
     }
     
     @Override
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/OrderByConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/OrderByConverter.java
index 9b3326b..56196c6 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/OrderByConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/OrderByConverter.java
@@ -22,7 +22,9 @@ import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.orderby.item.OrderByItemConverterUtil;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.OrderByItemSegment;
 
+import java.util.Collection;
 import java.util.Optional;
 
 /**
@@ -32,11 +34,15 @@ public final class OrderByConverter implements SQLSegmentConverter<OrderBySegmen
     
     @Override
     public Optional<SqlNodeList> convertToSQLNode(final OrderBySegment segment) {
-        return null == segment ? Optional.empty() : Optional.of(new SqlNodeList(OrderByItemConverterUtil.convert(segment.getOrderByItems()), SqlParserPos.ZERO));
+        return null == segment ? Optional.empty() : Optional.of(new SqlNodeList(OrderByItemConverterUtil.convertToSQLNode(segment.getOrderByItems()), SqlParserPos.ZERO));
     }
     
     @Override
-    public Optional<OrderBySegment> convertToSQLSegment(final SqlNodeList sqlNode) {
-        return Optional.empty();
+    public Optional<OrderBySegment> convertToSQLSegment(final SqlNodeList sqlNodeList) {
+        if (null == sqlNodeList) {
+            return Optional.empty(); 
+        }
+        Collection<OrderByItemSegment> orderByItems = OrderByItemConverterUtil.convertToSQLSegment(sqlNodeList);
+        return Optional.of(new OrderBySegment(getStartIndex(sqlNodeList), getStopIndex(sqlNodeList), orderByItems));
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/ColumnOrderByItemConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/ColumnOrderByItemConverter.java
index 2bde223..dd9c97b 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/ColumnOrderByItemConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/ColumnOrderByItemConverter.java
@@ -18,13 +18,16 @@
 package org.apache.shardingsphere.infra.optimize.converter.segment.orderby.item;
 
 import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.ColumnConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.constant.OrderDirection;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Objects;
 import java.util.Optional;
@@ -36,7 +39,7 @@ public final class ColumnOrderByItemConverter implements SQLSegmentConverter<Col
     
     @Override
     public Optional<SqlNode> convertToSQLNode(final ColumnOrderByItemSegment segment) {
-        Optional<SqlNode> result = new ColumnConverter().convertToSQLNode(segment.getColumn());
+        Optional<SqlNode> result = new ColumnConverter().convertToSQLNode(segment.getColumn()).map(optional -> optional);
         if (result.isPresent() && Objects.equals(OrderDirection.DESC, segment.getOrderDirection())) {
             result = Optional.of(new SqlBasicCall(SqlStdOperatorTable.DESC, new SqlNode[] {result.get()}, SqlParserPos.ZERO));
         }
@@ -45,6 +48,11 @@ public final class ColumnOrderByItemConverter implements SQLSegmentConverter<Col
     
     @Override
     public Optional<ColumnOrderByItemSegment> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+        if (!(sqlNode instanceof SqlIdentifier)) {
+            return Optional.empty(); 
+        }
+        SqlIdentifier sqlIdentifier = (SqlIdentifier) sqlNode;
+        ColumnSegment column = new ColumnSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier), new IdentifierValue(sqlIdentifier.names.get(0)));
+        return Optional.of(new ColumnOrderByItemSegment(column, OrderDirection.ASC));
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/OrderByItemConverterUtil.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/OrderByItemConverterUtil.java
index 11083d1..16f986e 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/OrderByItemConverterUtil.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/orderby/item/OrderByItemConverterUtil.java
@@ -19,15 +19,17 @@ package org.apache.shardingsphere.infra.optimize.converter.segment.orderby.item;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
+import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ExpressionOrderByItemSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.IndexOrderByItemSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.OrderByItemSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.TextOrderByItemSegment;
 
-import java.util.ArrayList;
 import java.util.Collection;
+import java.util.LinkedList;
 
 /**
  * Order by item converter utility.
@@ -36,13 +38,13 @@ import java.util.Collection;
 public final class OrderByItemConverterUtil {
     
     /**
-     * Convert order by items.
+     * Convert order by items to sql node.
      * 
      * @param orderByItems order by item list
      * @return SQL nodes converted by order by item
      */
-    public static Collection<SqlNode> convert(final Collection<OrderByItemSegment> orderByItems) {
-        Collection<SqlNode> result = new ArrayList<>(orderByItems.size());
+    public static Collection<SqlNode> convertToSQLNode(final Collection<OrderByItemSegment> orderByItems) {
+        Collection<SqlNode> result = new LinkedList<>();
         for (OrderByItemSegment each : orderByItems) {
             if (each instanceof ColumnOrderByItemSegment) {
                 new ColumnOrderByItemConverter().convertToSQLNode((ColumnOrderByItemSegment) each).ifPresent(result::add);
@@ -56,4 +58,20 @@ public final class OrderByItemConverterUtil {
         }
         return result;
     }
+    
+    /**
+     * Convert sql node list to order by items.
+     *
+     * @param sqlNodeList sql node list
+     * @return order by items converted by sql node list
+     */
+    public static Collection<OrderByItemSegment> convertToSQLSegment(final SqlNodeList sqlNodeList) {
+        Collection<OrderByItemSegment> result = new LinkedList<>();
+        for (SqlNode each : sqlNodeList) {
+            if (each instanceof SqlIdentifier) {
+                new ColumnOrderByItemConverter().convertToSQLSegment(each).ifPresent(result::add);
+            }
+        }
+        return result;
+    }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/ProjectionsConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/ProjectionsConverter.java
index 7c28332..c35f705 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/ProjectionsConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/ProjectionsConverter.java
@@ -21,6 +21,8 @@ import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlOrderBy;
+import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.AggregationProjectionConverter;
@@ -28,6 +30,7 @@ import org.apache.shardingsphere.infra.optimize.converter.segment.projection.imp
 import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.ExpressionProjectionConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.ShorthandProjectionConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl.SubqueryProjectionConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.constant.AggregationType;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
@@ -38,7 +41,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.Subquery
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedList;
+import java.util.List;
 import java.util.Optional;
 
 /**
@@ -57,28 +60,28 @@ public final class ProjectionsConverter implements SQLSegmentConverter<Projectio
     
     private Optional<SqlNode> getProjectionSQLNode(final ProjectionSegment segment) {
         if (segment instanceof ColumnProjectionSegment) {
-            return new ColumnProjectionConverter().convertToSQLNode((ColumnProjectionSegment) segment);
+            return new ColumnProjectionConverter().convertToSQLNode((ColumnProjectionSegment) segment).map(optional -> optional);
         } else if (segment instanceof ExpressionProjectionSegment) {
             return new ExpressionProjectionConverter().convertToSQLNode((ExpressionProjectionSegment) segment);
         } else if (segment instanceof ShorthandProjectionSegment) {
-            return new ShorthandProjectionConverter().convertToSQLNode((ShorthandProjectionSegment) segment);
+            return new ShorthandProjectionConverter().convertToSQLNode((ShorthandProjectionSegment) segment).map(optional -> optional);
         } else if (segment instanceof SubqueryProjectionSegment) {
             return new SubqueryProjectionConverter().convertToSQLNode((SubqueryProjectionSegment) segment);
         } else if (segment instanceof AggregationProjectionSegment) {
-            return new AggregationProjectionConverter().convertToSQLNode((AggregationProjectionSegment) segment);
+            return new AggregationProjectionConverter().convertToSQLNode((AggregationProjectionSegment) segment).map(optional -> optional);
         }
         // TODO process other projection
         return Optional.empty();
     }
     
     @Override
-    public Optional<ProjectionsSegment> convertToSQLSegment(final SqlNodeList sqlNode) {
-        Collection<ProjectionSegment> projections = new LinkedList<>();
-        for (SqlNode each : sqlNode) {
+    public Optional<ProjectionsSegment> convertToSQLSegment(final SqlNodeList sqlNodeList) {
+        List<ProjectionSegment> projections = new ArrayList<>();
+        for (SqlNode each : sqlNodeList) {
             getProjectionSegment(each).ifPresent(projections::add);
         }
-        int startIndex = sqlNode.get(0).getParserPosition().getColumnNum() - 1;
-        int stopIndex = sqlNode.get(sqlNode.size() - 1).getParserPosition().getEndColumnNum() - 1;
+        int startIndex = projections.get(0).getStartIndex();
+        int stopIndex = projections.get(projections.size() - 1).getStopIndex();
         ProjectionsSegment result = new ProjectionsSegment(startIndex, stopIndex);
         result.getProjections().addAll(projections);
         return Optional.of(result);
@@ -86,9 +89,19 @@ public final class ProjectionsConverter implements SQLSegmentConverter<Projectio
     
     private Optional<ProjectionSegment> getProjectionSegment(final SqlNode sqlNode) {
         if (sqlNode instanceof SqlIdentifier) {
-            return new ColumnProjectionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+            SqlIdentifier sqlIdentifier = (SqlIdentifier) sqlNode;
+            if (SqlIdentifier.STAR.names.equals(sqlIdentifier.names)) {
+                return new ShorthandProjectionConverter().convertToSQLSegment(sqlIdentifier).map(optional -> optional);    
+            }
+            return new ColumnProjectionConverter().convertToSQLSegment(sqlIdentifier).map(optional -> optional);
         } else if (sqlNode instanceof SqlBasicCall) {
+            SqlBasicCall sqlBasicCall = (SqlBasicCall) sqlNode;
+            if (AggregationType.isAggregationType(sqlBasicCall.getOperator().getName())) {
+                return new AggregationProjectionConverter().convertToSQLSegment(sqlBasicCall).map(optional -> optional);
+            }
             return new ExpressionProjectionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
+        } else if (sqlNode instanceof SqlSelect || sqlNode instanceof SqlOrderBy) {
+            return new SubqueryProjectionConverter().convertToSQLSegment(sqlNode).map(optional -> optional);
         }
         // TODO process other projection
         return Optional.empty();
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/AggregationProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/AggregationProjectionConverter.java
index be7bc8f..368d5cb 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/AggregationProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/AggregationProjectionConverter.java
@@ -25,6 +25,7 @@ import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.constant.AggregationType;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
 
 import java.util.Map;
@@ -34,7 +35,7 @@ import java.util.TreeMap;
 /**
  * Aggregation projection converter. 
  */
-public final class AggregationProjectionConverter implements SQLSegmentConverter<AggregationProjectionSegment, SqlNode> {
+public final class AggregationProjectionConverter implements SQLSegmentConverter<AggregationProjectionSegment, SqlBasicCall> {
     
     private static final Map<String, SqlAggFunction> REGISTRY = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
     
@@ -51,7 +52,7 @@ public final class AggregationProjectionConverter implements SQLSegmentConverter
     }
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final AggregationProjectionSegment segment) {
+    public Optional<SqlBasicCall> convertToSQLNode(final AggregationProjectionSegment segment) {
         if (null == segment) {
             return Optional.empty();
         }
@@ -59,8 +60,13 @@ public final class AggregationProjectionConverter implements SQLSegmentConverter
     }
     
     @Override
-    public Optional<AggregationProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+    public Optional<AggregationProjectionSegment> convertToSQLSegment(final SqlBasicCall sqlBasicCall) {
+        if (null == sqlBasicCall) {
+            return Optional.empty();    
+        }
+        AggregationType aggregationType = AggregationType.valueOf(sqlBasicCall.getOperator().getName());
+        String innerExpression = sqlBasicCall.toString().replace(sqlBasicCall.getOperator().getName(), "");
+        return Optional.of(new AggregationProjectionSegment(getStartIndex(sqlBasicCall), getStopIndex(sqlBasicCall), aggregationType, innerExpression));
     }
     
     private SqlAggFunction convertOperator(final String operator) {
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java
index 1a0de30..9f48990 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ColumnProjectionConverter.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
 
-import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.expression.impl.ColumnConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
@@ -27,15 +27,15 @@ import java.util.Optional;
 /**
  * Column projection converter. 
  */
-public final class ColumnProjectionConverter implements SQLSegmentConverter<ColumnProjectionSegment, SqlNode> {
+public final class ColumnProjectionConverter implements SQLSegmentConverter<ColumnProjectionSegment, SqlIdentifier> {
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final ColumnProjectionSegment segment) {
+    public Optional<SqlIdentifier> convertToSQLNode(final ColumnProjectionSegment segment) {
         return new ColumnConverter().convertToSQLNode(segment.getColumn());
     }
     
     @Override
-    public Optional<ColumnProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+    public Optional<ColumnProjectionSegment> convertToSQLSegment(final SqlIdentifier sqlNode) {
         return new ColumnConverter().convertToSQLSegment(sqlNode).map(ColumnProjectionSegment::new);
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ExpressionProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ExpressionProjectionConverter.java
index 542c10b..23a8bec 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ExpressionProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ExpressionProjectionConverter.java
@@ -21,6 +21,7 @@ import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.segment.expression.ExpressionConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
 
 import java.util.Optional;
@@ -38,8 +39,8 @@ public final class ExpressionProjectionConverter implements SQLSegmentConverter<
     @Override
     public Optional<ExpressionProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
         if (sqlNode instanceof SqlBasicCall) {
-            return Optional.of(new ExpressionProjectionSegment(sqlNode.getParserPosition().getColumnNum() - 1,
-                    sqlNode.getParserPosition().getEndColumnNum() - 1, sqlNode.toString(), new ExpressionConverter().convertToSQLSegment(sqlNode).orElse(null)));
+            ExpressionSegment expressionSegment = new ExpressionConverter().convertToSQLSegment(sqlNode).orElse(null);
+            return Optional.of(new ExpressionProjectionSegment(getStartIndex(sqlNode), getStopIndex(sqlNode), sqlNode.toString(), expressionSegment));
         }
         return Optional.empty();
     }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ShorthandProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ShorthandProjectionConverter.java
index 532b7f5..84bc2e9 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ShorthandProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/ShorthandProjectionConverter.java
@@ -18,25 +18,34 @@
 package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
 
 import org.apache.calcite.sql.SqlIdentifier;
-import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ShorthandProjectionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
 
 /**
  * Shorthand projection converter. 
  */
-public final class ShorthandProjectionConverter implements SQLSegmentConverter<ShorthandProjectionSegment, SqlNode> {
+public final class ShorthandProjectionConverter implements SQLSegmentConverter<ShorthandProjectionSegment, SqlIdentifier> {
     
     @Override
-    public Optional<SqlNode> convertToSQLNode(final ShorthandProjectionSegment segment) {
+    public Optional<SqlIdentifier> convertToSQLNode(final ShorthandProjectionSegment segment) {
         return null == segment ? Optional.empty() : Optional.of(SqlIdentifier.star(SqlParserPos.ZERO));
     }
     
     @Override
-    public Optional<ShorthandProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+    public Optional<ShorthandProjectionSegment> convertToSQLSegment(final SqlIdentifier sqlIdentifier) {
+        if (null == sqlIdentifier) {
+            return Optional.empty();
+        }
+        ShorthandProjectionSegment result = new ShorthandProjectionSegment(getStartIndex(sqlIdentifier), getStopIndex(sqlIdentifier));
+        if (sqlIdentifier.names.size() > 1) {
+            SqlIdentifier owner = sqlIdentifier.getComponent(0);
+            result.setOwner(new OwnerSegment(getStartIndex(owner), getStopIndex(owner), new IdentifierValue(sqlIdentifier.names.get(0))));
+        }
+        return Optional.of(result);
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
index f35b14b..6a90a0e 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/projection/impl/SubqueryProjectionConverter.java
@@ -17,14 +17,19 @@
 
 package org.apache.shardingsphere.infra.optimize.converter.segment.projection.impl;
 
+import org.apache.calcite.avatica.util.Quoting;
 import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlOrderBy;
+import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.infra.optimize.converter.segment.SQLSegmentConverter;
 import org.apache.shardingsphere.infra.optimize.converter.statement.SelectStatementConverter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 
 import java.util.Collection;
 import java.util.LinkedList;
@@ -53,6 +58,15 @@ public final class SubqueryProjectionConverter implements SQLSegmentConverter<Su
     
     @Override
     public Optional<SubqueryProjectionSegment> convertToSQLSegment(final SqlNode sqlNode) {
+        if (sqlNode instanceof SqlSelect || sqlNode instanceof SqlOrderBy) {
+            SelectStatement selectStatement = new SelectStatementConverter().convertToSQLStatement(sqlNode);
+            // FIXME subquery projection position returned by the CalCite parser does not contain two brackets
+            int startIndex = getStartIndex(sqlNode) - 1;
+            int stopIndex = getStopIndex(sqlNode) + 1;
+            String text = "(" + sqlNode + ")";
+            String originalText = text.replace("\n", " ").replace(Quoting.BACK_TICK.string, "");
+            return Optional.of(new SubqueryProjectionSegment(new SubquerySegment(startIndex, stopIndex, selectStatement), originalText));
+        }
         return Optional.empty();
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/where/WhereConverter.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/where/WhereConverter.java
index bb25c29..09c28f1 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/where/WhereConverter.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/converter/segment/where/WhereConverter.java
@@ -29,6 +29,8 @@ import java.util.Optional;
  */
 public final class WhereConverter implements SQLSegmentConverter<WhereSegment, SqlNode> {
     
+    private static final int WHERE_SEGMENT_LENGTH = 6;
+    
     @Override
     public Optional<SqlNode> convertToSQLNode(final WhereSegment segment) {
         return null == segment ? Optional.empty() : new ExpressionConverter().convertToSQLNode(segment.getExpr());
@@ -36,6 +38,11 @@ public final class WhereConverter implements SQLSegmentConverter<WhereSegment, S
     
     @Override
     public Optional<WhereSegment> convertToSQLSegment(final SqlNode sqlNode) {
-        return Optional.empty();
+        if (null == sqlNode) {
+            return Optional.empty();
+        }
+        // FIXME Now sqlNode position returned by the CalCite parser does not contain WHERE and requires manual calculation
+        int startIndex = getStartIndex(sqlNode) - WHERE_SEGMENT_LENGTH;
+        return new ExpressionConverter().convertToSQLSegment(sqlNode).map(optional -> new WhereSegment(startIndex, optional.getStopIndex(), optional));
     }
 }