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

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


The following commit(s) were added to refs/heads/master by this push:
     new 421d2e561b3 Refactor and enhance Translatable Executor and Optimizer 
(#23040)
421d2e561b3 is described below

commit 421d2e561b3480804fc66e86079b77d0191941d1
Author: boyjoy1127 <[email protected]>
AuthorDate: Fri Jan 13 08:45:18 2023 +0800

    Refactor and enhance Translatable Executor and Optimizer (#23040)
    
    * refactor: Replace FilterableTableScanExecutor with 
TranslatableTableScanExecutor.
    
    * refactor: refactor TranslatableTableScanExecutor and enhance translatable 
executor and optimizer.
    
    * fix: fix optimizer unit tests.
    
    * fix: fix optimizer unit tests.
    
    * fix: fix optimizer unit tests.
    
    * refactor: Empty Row Enumerator, Memory Enumerator, Federation Row 
Enumerator.
    
    * fix: modify code style.
    
    * fix: modify code style and unit test.
    
    Co-authored-by: boyjoy1127 <[email protected]>
---
 kernel/sql-federation/executor/core/pom.xml        |   4 +
 .../sqlfederation/SQLFederationDataContext.java    |   2 +
 .../executor/FilterableTableScanExecutor.java      |  15 +++
 .../executor/TranslatableTableScanExecutor.java    | 123 ++++++++++++++++-
 .../sqlfederation/row/EmptyRowEnumerator.java      |  14 +-
 ...umerator.java => EmptyRowScalarEnumerator.java} |   6 +-
 .../sqlfederation/row/MemoryEnumerator.java        |  15 ++-
 ...Enumerator.java => MemoryScalarEnumerator.java} |  11 +-
 .../row/SQLFederationRowEnumerator.java            |  12 +-
 ...tor.java => SQLFederationScalarEnumerator.java} |  12 +-
 .../executor/FilterableTableScanExecutorTest.java  |   4 +-
 kernel/sql-federation/optimizer/pom.xml            |   4 +
 .../optimizer/parser/rexnode/Keyword.g4            |   2 +
 .../optimizer/parser/rexnode/Literals.g4           |   4 +
 .../optimizer/parser/rexnode/ParseRexNode.g4       |   4 +-
 .../optimizer/parser/rexnode/Symbol.g4             |   2 +
 .../optimizer/executor/TableScanExecutor.java      |   9 ++
 .../translatable/FederationTranslatableTable.java  |  45 ++++++-
 .../translatable/ParseRexNodeVisitorImpl.java      |  61 ++++++++-
 .../metadata/translatable/StringToRexNodeUtil.java |   8 +-
 .../translatable/TranslatableFilterRule.java       |  19 +++
 .../TranslatableProjectFilterRule.java             |  18 +++
 .../translatable/TranslatableTableScan.java        |  52 ++++++-
 .../optimizer/it/SQLOptimizeEngineIT.java          |   4 +-
 .../resources/cases/federation-query-sql-cases.xml | 150 ++++++++++-----------
 25 files changed, 472 insertions(+), 128 deletions(-)

diff --git a/kernel/sql-federation/executor/core/pom.xml 
b/kernel/sql-federation/executor/core/pom.xml
index 7d8e99b0df5..5f05f6d73c6 100644
--- a/kernel/sql-federation/executor/core/pom.xml
+++ b/kernel/sql-federation/executor/core/pom.xml
@@ -48,5 +48,9 @@
             <artifactId>shardingsphere-infra-merge</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
     </dependencies>
 </project>
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/SQLFederationDataContext.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/SQLFederationDataContext.java
index bab0db5223b..67d5219b4ec 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/SQLFederationDataContext.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/SQLFederationDataContext.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.sqlfederation;
 
+import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.calcite.DataContext;
 import org.apache.calcite.adapter.java.JavaTypeFactory;
@@ -37,6 +38,7 @@ public final class SQLFederationDataContext implements 
DataContext {
     
     private final SqlToRelConverter converter;
     
+    @Getter
     private final Map<String, Object> parameters;
     
     @Override
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutor.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutor.java
index e77ced46423..4d6cf7d7cd8 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutor.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutor.java
@@ -117,6 +117,21 @@ public final class FilterableTableScanExecutor implements 
TableScanExecutor {
     
     private final EventBusContext eventBusContext;
     
+    @Override
+    public Enumerable<Object> executeScalar(final ShardingSphereTable table, 
final ScanNodeExecutorContext scanContext) {
+        return createEmptyScalarEnumerable();
+    }
+    
+    private AbstractEnumerable<Object> createEmptyScalarEnumerable() {
+        return new AbstractEnumerable<Object>() {
+            
+            @Override
+            public Enumerator<Object> enumerator() {
+                return new EmptyRowEnumerator();
+            }
+        };
+    }
+    
     @Override
     public Enumerable<Object[]> execute(final ShardingSphereTable table, final 
ScanNodeExecutorContext scanContext) {
         String databaseName = executorContext.getDatabaseName().toLowerCase();
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/TranslatableTableScanExecutor.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/TranslatableTableScanExecutor.java
index 41ede214d7b..7e3fb59701e 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/TranslatableTableScanExecutor.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/TranslatableTableScanExecutor.java
@@ -18,6 +18,8 @@
 package org.apache.shardingsphere.sqlfederation.executor;
 
 import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
 import lombok.RequiredArgsConstructor;
 import lombok.SneakyThrows;
 import org.apache.calcite.adapter.java.JavaTypeFactory;
@@ -72,6 +74,7 @@ import 
org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
 import 
org.apache.shardingsphere.infra.util.exception.external.sql.type.wrapper.SQLWrapperException;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sqlfederation.SQLDialectFactory;
+import org.apache.shardingsphere.sqlfederation.SQLFederationDataContext;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.context.OptimizerContext;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.ScanNodeExecutorContext;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TableScanExecutor;
@@ -84,6 +87,7 @@ import 
org.apache.shardingsphere.sqlfederation.row.MemoryEnumerator;
 import org.apache.shardingsphere.sqlfederation.row.SQLFederationRowEnumerator;
 import 
org.apache.shardingsphere.sqlfederation.spi.SQLFederationExecutorContext;
 
+import java.lang.reflect.Type;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
@@ -91,9 +95,13 @@ import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
@@ -104,6 +112,8 @@ public final class TranslatableTableScanExecutor implements 
TableScanExecutor {
     
     private static final JavaTypeFactory JAVA_TYPE_FACTORY = new 
JavaTypeFactoryImpl();
     
+    private static final String COLUMN_INFORMATION_PATTERN = "\\{.*}";
+    
     private final DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine;
     
     private final JDBCExecutor jdbcExecutor;
@@ -120,6 +130,93 @@ public final class TranslatableTableScanExecutor 
implements TableScanExecutor {
     
     private final EventBusContext eventBusContext;
     
+    @Override
+    public Enumerable<Object> executeScalar(final ShardingSphereTable table, 
final ScanNodeExecutorContext scanContext) {
+        String databaseName = executorContext.getDatabaseName().toLowerCase();
+        String schemaName = executorContext.getSchemaName().toLowerCase();
+        DatabaseType databaseType = 
DatabaseTypeEngine.getTrunkDatabaseType(optimizerContext.getParserContext(databaseName).getDatabaseType().getType());
+        SqlString sqlString = createSQLString(table, 
(TranslatableScanNodeExecutorContext) scanContext, 
SQLDialectFactory.getSQLDialect(databaseType));
+        // TODO replace sql parse with sql convert
+        SQLFederationExecutorContext federationContext = 
executorContext.getFederationContext();
+        QueryContext queryContext = 
createQueryContext(federationContext.getMetaData(), sqlString, databaseType);
+        ShardingSphereDatabase database = 
federationContext.getMetaData().getDatabase(databaseName);
+        ExecutionContext context = new 
KernelProcessor().generateExecutionContext(queryContext, database, 
globalRuleMetaData, executorContext.getProps(), new ConnectionContext());
+        if (federationContext.isPreview() || 
databaseType.getSystemSchemas().contains(schemaName)) {
+            
federationContext.getExecutionUnits().addAll(context.getExecutionUnits());
+            return createEmptyScalarEnumerable();
+        }
+        if (databaseType.getSystemSchemas().contains(schemaName)) {
+            return executeByScalarShardingSphereData(databaseName, schemaName, 
table);
+        }
+        return executeScalarEnumerable(databaseType, queryContext, database, 
context);
+    }
+    
+    private AbstractEnumerable<Object> createEmptyScalarEnumerable() {
+        return new AbstractEnumerable<Object>() {
+            
+            @Override
+            public Enumerator<Object> enumerator() {
+                return new EmptyRowEnumerator();
+            }
+        };
+    }
+    
+    private Enumerable<Object> executeByScalarShardingSphereData(final String 
databaseName, final String schemaName, final ShardingSphereTable table) {
+        Optional<ShardingSphereTableData> tableData = 
Optional.ofNullable(data.getDatabaseData().get(databaseName)).map(optional -> 
optional.getSchemaData().get(schemaName))
+                
.map(ShardingSphereSchemaData::getTableData).map(shardingSphereData -> 
shardingSphereData.get(table.getName()));
+        return 
tableData.map(this::createMemoryScalarEnumerator).orElseGet(this::createEmptyScalarEnumerable);
+    }
+    
+    private Enumerable<Object> createMemoryScalarEnumerator(final 
ShardingSphereTableData tableData) {
+        return new AbstractEnumerable<Object>() {
+            
+            @Override
+            public Enumerator<Object> enumerator() {
+                return new MemoryEnumerator(tableData.getRows());
+            }
+        };
+    }
+    
+    private AbstractEnumerable<Object> executeScalarEnumerable(final 
DatabaseType databaseType, final QueryContext queryContext,
+                                                               final 
ShardingSphereDatabase database, final ExecutionContext context) {
+        try {
+            ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext = 
prepareEngine.prepare(context.getRouteContext(), context.getExecutionUnits());
+            setParameters(executionGroupContext.getInputGroups());
+            
ExecuteProcessEngine.initializeExecution(context.getQueryContext(), 
executionGroupContext, eventBusContext);
+            List<QueryResult> queryResults = execute(executionGroupContext, 
databaseType);
+            
ExecuteProcessEngine.finishExecution(executionGroupContext.getExecutionID(), 
eventBusContext);
+            MergeEngine mergeEngine = new MergeEngine(database, 
executorContext.getProps(), new ConnectionContext());
+            MergedResult mergedResult = mergeEngine.merge(queryResults, 
queryContext.getSqlStatementContext());
+            Collection<Statement> statements = 
getStatements(executionGroupContext.getInputGroups());
+            return createScalarEnumerable(mergedResult, 
queryResults.get(0).getMetaData(), statements);
+        } catch (final SQLException ex) {
+            throw new SQLWrapperException(ex);
+        } finally {
+            ExecuteProcessEngine.cleanExecution();
+        }
+    }
+    
+    private AbstractEnumerable<Object> createScalarEnumerable(final 
MergedResult mergedResult, final QueryResultMetaData metaData, final 
Collection<Statement> statements) throws SQLException {
+        // TODO remove getRows when mergedResult support JDBC first method
+        Collection<Object> rows = getScalarRows(mergedResult, metaData);
+        return new AbstractEnumerable<Object>() {
+            
+            @Override
+            public Enumerator<Object> enumerator() {
+                return new SQLFederationRowEnumerator(rows, statements);
+            }
+        };
+    }
+    
+    private Collection<Object> getScalarRows(final MergedResult mergedResult, 
final QueryResultMetaData metaData) throws SQLException {
+        Collection<Object> result = new LinkedList<>();
+        while (mergedResult.next()) {
+            Object currentRow = mergedResult.getValue(1, Object.class);
+            result.add(currentRow);
+        }
+        return result;
+    }
+    
     @Override
     public Enumerable<Object[]> execute(final ShardingSphereTable table, final 
ScanNodeExecutorContext scanContext) {
         String databaseName = executorContext.getDatabaseName().toLowerCase();
@@ -229,7 +326,7 @@ public final class TranslatableTableScanExecutor implements 
TableScanExecutor {
         RelOptCluster relOptCluster = 
RelOptCluster.create(SQLFederationPlannerUtil.createVolcanoPlanner(), new 
RexBuilder(JAVA_TYPE_FACTORY));
         RelBuilder builder = 
RelFactories.LOGICAL_BUILDER.create(relOptCluster, 
catalogReader).scan(table.getName());
         if (null != scanContext.getFilterValues()) {
-            builder.filter(createFilters(scanContext.getFilterValues()));
+            builder.filter(createFilters(scanContext.getFilterValues(), 
(SQLFederationDataContext) scanContext.getRoot()));
         }
         if (null != scanContext.getProjects()) {
             builder.project(createProjections(scanContext.getProjects(), 
builder, table.getColumnNames()));
@@ -237,18 +334,38 @@ public final class TranslatableTableScanExecutor 
implements TableScanExecutor {
         return builder.build();
     }
     
-    private Collection<RexNode> createFilters(final String[] filterValues) {
+    private Collection<RexNode> createFilters(final String[] filterValues, 
final SQLFederationDataContext context) {
         Collection<RexNode> result = new LinkedList<>();
         JavaTypeFactory typeFactory = new 
JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
         RexBuilder rexBuilder = new RexBuilder(typeFactory);
         for (String each : filterValues) {
             if (!Strings.isNullOrEmpty(each)) {
-                result.add(StringToRexNodeUtil.buildRexNode(each, rexBuilder));
+                Map<Integer, Integer> columnMap = extractColumnMap(each);
+                String filterValue = extractFilterValue(each);
+                result.add(StringToRexNodeUtil.buildRexNode(filterValue, 
rexBuilder, context.getParameters(), columnMap));
             }
         }
         return result;
     }
     
+    private Map<Integer, Integer> extractColumnMap(final String 
filterExpression) {
+        Matcher matcher = 
Pattern.compile(COLUMN_INFORMATION_PATTERN).matcher(filterExpression);
+        Map<Integer, Integer> result = new HashMap<>();
+        if (!matcher.find()) {
+            return result;
+        }
+        String columnInformation = matcher.group();
+        Gson gson = new Gson();
+        Type type = new TypeToken<Map<Integer, Integer>>() {
+        }.getType();
+        result = gson.fromJson(columnInformation, type);
+        return result;
+    }
+    
+    private String extractFilterValue(final String filterExpression) {
+        return filterExpression.replaceAll("\\{.*}", "");
+    }
+    
     private Collection<RexNode> createProjections(final int[] projects, final 
RelBuilder relBuilder, final List<String> columnNames) {
         Collection<RexNode> result = new LinkedList<>();
         for (int each : projects) {
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowEnumerator.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowEnumerator.java
index c4087549fe4..46e411dd575 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowEnumerator.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowEnumerator.java
@@ -19,14 +19,22 @@ package org.apache.shardingsphere.sqlfederation.row;
 
 import org.apache.calcite.linq4j.Enumerator;
 
+import java.lang.reflect.ParameterizedType;
+
 /**
  * Empty row enumerator.
  */
-public final class EmptyRowEnumerator implements Enumerator<Object[]> {
+public final class EmptyRowEnumerator<T> implements Enumerator<T> {
     
     @Override
-    public Object[] current() {
-        return new Object[0];
+    public T current() {
+        ParameterizedType type = (ParameterizedType) 
getClass().getGenericSuperclass();
+        System.out.println(type.getActualTypeArguments()[0].getTypeName());
+        if ("Object".equals(type.getActualTypeArguments()[0].getTypeName())) {
+            return (T) new Object();
+        } else {
+            return (T) new Object[0];
+        }
     }
     
     @Override
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowEnumerator.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowScalarEnumerator.java
similarity index 89%
copy from 
kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowEnumerator.java
copy to 
kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowScalarEnumerator.java
index c4087549fe4..4c9d60ff50c 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowEnumerator.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/EmptyRowScalarEnumerator.java
@@ -22,11 +22,11 @@ import org.apache.calcite.linq4j.Enumerator;
 /**
  * Empty row enumerator.
  */
-public final class EmptyRowEnumerator implements Enumerator<Object[]> {
+public final class EmptyRowScalarEnumerator implements Enumerator<Object> {
     
     @Override
-    public Object[] current() {
-        return new Object[0];
+    public Object current() {
+        return new Object();
     }
     
     @Override
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryEnumerator.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryEnumerator.java
index 25c87a465ef..92ebac4530a 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryEnumerator.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryEnumerator.java
@@ -27,13 +27,13 @@ import java.util.List;
 /**
  * Memory enumerator.
  */
-public final class MemoryEnumerator implements Enumerator<Object[]> {
+public final class MemoryEnumerator<T> implements Enumerator<T> {
     
     private final Collection<ShardingSphereRowData> rows;
     
     private Iterator<ShardingSphereRowData> rowDataIterator;
     
-    private List<Object> current;
+    private T current;
     
     public MemoryEnumerator(final Collection<ShardingSphereRowData> rows) {
         this.rows = rows;
@@ -41,14 +41,19 @@ public final class MemoryEnumerator implements 
Enumerator<Object[]> {
     }
     
     @Override
-    public Object[] current() {
-        return current.toArray();
+    public T current() {
+        return current;
     }
     
     @Override
     public boolean moveNext() {
         if (rowDataIterator.hasNext()) {
-            current = rowDataIterator.next().getRows();
+            List rows = rowDataIterator.next().getRows();
+            if (rows.size() == 1) {
+                current = (T) rows.get(0);
+            } else {
+                current = (T) rows.toArray();
+            }
             return true;
         }
         current = null;
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryEnumerator.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryScalarEnumerator.java
similarity index 86%
copy from 
kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryEnumerator.java
copy to 
kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryScalarEnumerator.java
index 25c87a465ef..66b9a8e4a9f 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryEnumerator.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/MemoryScalarEnumerator.java
@@ -22,27 +22,26 @@ import 
org.apache.shardingsphere.infra.metadata.data.ShardingSphereRowData;
 
 import java.util.Collection;
 import java.util.Iterator;
-import java.util.List;
 
 /**
  * Memory enumerator.
  */
-public final class MemoryEnumerator implements Enumerator<Object[]> {
+public final class MemoryScalarEnumerator implements Enumerator<Object> {
     
     private final Collection<ShardingSphereRowData> rows;
     
     private Iterator<ShardingSphereRowData> rowDataIterator;
     
-    private List<Object> current;
+    private Object current;
     
-    public MemoryEnumerator(final Collection<ShardingSphereRowData> rows) {
+    public MemoryScalarEnumerator(final Collection<ShardingSphereRowData> 
rows) {
         this.rows = rows;
         rowDataIterator = rows.iterator();
     }
     
     @Override
-    public Object[] current() {
-        return current.toArray();
+    public Object current() {
+        return current;
     }
     
     @Override
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationRowEnumerator.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationRowEnumerator.java
index c192b16f52d..ba538c19225 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationRowEnumerator.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationRowEnumerator.java
@@ -28,24 +28,24 @@ import java.util.Iterator;
 /**
  * SQL federation row enumerator.
  */
-public final class SQLFederationRowEnumerator implements Enumerator<Object[]> {
+public final class SQLFederationRowEnumerator<T> implements Enumerator<T> {
     
-    private final Collection<Object[]> rows;
+    private final Collection<T> rows;
     
     private final Collection<Statement> statements;
     
-    private Iterator<Object[]> iterator;
+    private Iterator<T> iterator;
     
-    private Object[] currentRow;
+    private T currentRow;
     
-    public SQLFederationRowEnumerator(final Collection<Object[]> rows, final 
Collection<Statement> statements) {
+    public SQLFederationRowEnumerator(final Collection<T> rows, final 
Collection<Statement> statements) {
         this.rows = rows;
         this.statements = statements;
         iterator = rows.iterator();
     }
     
     @Override
-    public Object[] current() {
+    public T current() {
         return currentRow;
     }
     
diff --git 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationRowEnumerator.java
 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationScalarEnumerator.java
similarity index 85%
copy from 
kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationRowEnumerator.java
copy to 
kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationScalarEnumerator.java
index c192b16f52d..d550035fc40 100644
--- 
a/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationRowEnumerator.java
+++ 
b/kernel/sql-federation/executor/core/src/main/java/org/apache/shardingsphere/sqlfederation/row/SQLFederationScalarEnumerator.java
@@ -28,24 +28,24 @@ import java.util.Iterator;
 /**
  * SQL federation row enumerator.
  */
-public final class SQLFederationRowEnumerator implements Enumerator<Object[]> {
+public final class SQLFederationScalarEnumerator implements Enumerator<Object> 
{
     
-    private final Collection<Object[]> rows;
+    private final Collection<Object> rows;
     
     private final Collection<Statement> statements;
     
-    private Iterator<Object[]> iterator;
+    private Iterator<Object> iterator;
     
-    private Object[] currentRow;
+    private Object currentRow;
     
-    public SQLFederationRowEnumerator(final Collection<Object[]> rows, final 
Collection<Statement> statements) {
+    public SQLFederationScalarEnumerator(final Collection<Object> rows, final 
Collection<Statement> statements) {
         this.rows = rows;
         this.statements = statements;
         iterator = rows.iterator();
     }
     
     @Override
-    public Object[] current() {
+    public Object current() {
         return currentRow;
     }
     
diff --git 
a/kernel/sql-federation/executor/core/src/test/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutorTest.java
 
b/kernel/sql-federation/executor/core/src/test/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutorTest.java
index 79c1ef6b69d..2046489a2b8 100644
--- 
a/kernel/sql-federation/executor/core/src/test/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutorTest.java
+++ 
b/kernel/sql-federation/executor/core/src/test/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutorTest.java
@@ -61,7 +61,7 @@ public final class FilterableTableScanExecutorTest {
                 .execute(shardingSphereTable, 
mock(ScanNodeExecutorContext.class));
         Enumerator<Object[]> actual = enumerable.enumerator();
         actual.moveNext();
-        Object[] row = actual.current();
-        assertThat(row[0], is(1));
+        Object row = actual.current();
+        assertThat(row, is(1));
     }
 }
diff --git a/kernel/sql-federation/optimizer/pom.xml 
b/kernel/sql-federation/optimizer/pom.xml
index 3568607aef0..b8d06d9bef3 100644
--- a/kernel/sql-federation/optimizer/pom.xml
+++ b/kernel/sql-federation/optimizer/pom.xml
@@ -106,6 +106,10 @@
             <artifactId>javax.activation-api</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
     </dependencies>
     
     <build>
diff --git 
a/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Keyword.g4
 
b/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Keyword.g4
index d416df1cd79..c346a9c07ac 100644
--- 
a/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Keyword.g4
+++ 
b/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Keyword.g4
@@ -25,6 +25,8 @@ LIKE: L I K E;
 
 INTEGER: I N T E G E R;
 
+BIGINT: B I G I N T;
+
 VARCHAR: V A R C H A R;
 
 CAST: C A S T;
diff --git 
a/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Literals.g4
 
b/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Literals.g4
index 84614199592..ff0fdb20a2c 100644
--- 
a/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Literals.g4
+++ 
b/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Literals.g4
@@ -19,6 +19,10 @@ lexer grammar Literals;
 
 import Alphabet, Symbol;
 
+PLACEHOLDER_
+    :  QUESTION_ INTEGER_
+    ;
+
 STRING_ 
     : (DQ_ ( '\\'. | '""' | ~('"'| '\\') )* DQ_)
     | (SQ_ ('\\'. | '\'\'' | ~('\'' | '\\'))* SQ_)
diff --git 
a/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/ParseRexNode.g4
 
b/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/ParseRexNode.g4
index adb06dc8a64..036141556ff 100644
--- 
a/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/ParseRexNode.g4
+++ 
b/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/ParseRexNode.g4
@@ -40,7 +40,7 @@ searchArgs
     ;
 
 constant
-    : INTEGER_ | STRING_
+    : INTEGER_ | STRING_ | PLACEHOLDER_
     ;
 
 cast
@@ -68,7 +68,7 @@ argRangeList
     ;
 
 type
-    : INTEGER|VARCHAR
+    : BIGINT | INTEGER | VARCHAR
     ;
 
 WS
diff --git 
a/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Symbol.g4
 
b/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Symbol.g4
index a6b5acd85c1..eec5fedf35d 100644
--- 
a/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Symbol.g4
+++ 
b/kernel/sql-federation/optimizer/src/main/antlr4/org/apache/shardingsphere/sqlfederation/optimizer/parser/rexnode/Symbol.g4
@@ -37,3 +37,5 @@ COLON_:              ':';
 RANGE_:              '..';
 NEGETIVE_INFINITY_:  '-∞';
 POSITIVE_INFINITY_:  '+∞';
+QUESTION_:           '?';
+
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/executor/TableScanExecutor.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/executor/TableScanExecutor.java
index d36ffddbb9b..edc721197cc 100644
--- 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/executor/TableScanExecutor.java
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/executor/TableScanExecutor.java
@@ -33,4 +33,13 @@ public interface TableScanExecutor {
      * @return query results
      */
     Enumerable<Object[]> execute(ShardingSphereTable table, 
ScanNodeExecutorContext scanContext);
+    
+    /**
+     * Execute.
+     *
+     * @param table table meta data
+     * @param scanContext filterable table scan context
+     * @return query results
+     */
+    Enumerable<Object> executeScalar(ShardingSphereTable table, 
ScanNodeExecutorContext scanContext);
 }
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/FederationTranslatableTable.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/FederationTranslatableTable.java
index 4d8bbaf1510..7b513cefc5f 100644
--- 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/FederationTranslatableTable.java
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/FederationTranslatableTable.java
@@ -35,6 +35,7 @@ import org.apache.calcite.schema.Statistic;
 import org.apache.calcite.schema.TranslatableTable;
 import org.apache.calcite.schema.impl.AbstractTable;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
+import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereColumn;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
 import 
org.apache.shardingsphere.infra.util.exception.external.sql.type.generic.UnsupportedSQLOperationException;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TableScanExecutor;
@@ -43,6 +44,8 @@ import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.statistic.Fede
 import 
org.apache.shardingsphere.sqlfederation.optimizer.util.SQLFederationDataTypeUtil;
 
 import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Federation translatable table.
@@ -58,9 +61,27 @@ public final class FederationTranslatableTable extends 
AbstractTable implements
     
     private final DatabaseType protocolType;
     
-    @Override
-    public RelDataType getRowType(final RelDataTypeFactory typeFactory) {
-        return SQLFederationDataTypeUtil.createRelDataType(table, 
protocolType, typeFactory);
+    /**
+     * Execute filter and project when query the federation translatable table.
+     *
+     * @param root data context
+     * @param filterValues right value in filter condition
+     * @param projects fields to be projected
+     * @return enumerable result
+     */
+    public Enumerable<Object> projectAndFilterScalar(final DataContext root, 
final String[] filterValues, final int[] projects) {
+        return executor.executeScalar(table, new 
TranslatableScanNodeExecutorContext(root, filterValues, projects));
+    }
+    
+    /**
+     * Execute filter and project when query the federation translatable table.
+     *
+     * @param root data context
+     * @param projects fields to be projected
+     * @return enumerable result
+     */
+    public Enumerable<Object> projectScalar(final DataContext root, final 
int[] projects) {
+        return executor.executeScalar(table, new 
TranslatableScanNodeExecutorContext(root, null, projects));
     }
     
     /**
@@ -86,6 +107,24 @@ public final class FederationTranslatableTable extends 
AbstractTable implements
         return executor.execute(table, new 
TranslatableScanNodeExecutorContext(root, null, projects));
     }
     
+    /**
+     * Get column type from table by column identity.
+     *
+     * @param index column identity
+     * @return column data type
+     */
+    public int getColumnType(final int index) {
+        List columnNames = table.getVisibleColumns();
+        Map<String, ShardingSphereColumn> columnMap = table.getColumns();
+        ShardingSphereColumn column = columnMap.get(columnNames.get(index));
+        return column.getDataType();
+    }
+    
+    @Override
+    public RelDataType getRowType(final RelDataTypeFactory typeFactory) {
+        return SQLFederationDataTypeUtil.createRelDataType(table, 
protocolType, typeFactory);
+    }
+    
     @Override
     public Expression getExpression(final SchemaPlus schema, final String 
tableName, final Class clazz) {
         return Schemas.tableExpression(schema, getElementType(), tableName, 
clazz);
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/ParseRexNodeVisitorImpl.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/ParseRexNodeVisitorImpl.java
index 81a5e7ff467..706d577c9ba 100644
--- 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/ParseRexNodeVisitorImpl.java
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/ParseRexNodeVisitorImpl.java
@@ -50,8 +50,10 @@ import 
org.apache.shardingsphere.sqlfederation.optimizer.parser.rexnode.ParseRex
 import 
org.apache.shardingsphere.sqlfederation.optimizer.parser.rexnode.ParseRexNodeParser.TypeContext;
 
 import java.math.BigDecimal;
+import java.sql.Date;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 @AllArgsConstructor
 public final class ParseRexNodeVisitorImpl extends 
ParseRexNodeBaseVisitor<RexNode> {
@@ -60,6 +62,10 @@ public final class ParseRexNodeVisitorImpl extends 
ParseRexNodeBaseVisitor<RexNo
     
     private JavaTypeFactory typeFactory;
     
+    private Map<String, Object> parameters;
+    
+    private Map<Integer, Integer> columnMap;
+    
     @Override
     public RexNode visitExpression(final ExpressionContext ctx) {
         SqlOperator operator = getOp(ctx.op());
@@ -139,8 +145,45 @@ public final class ParseRexNodeVisitorImpl extends 
ParseRexNodeBaseVisitor<RexNo
     @Override
     public RexNode visitInputRef(final InputRefContext ctx) {
         Integer index = Integer.valueOf(ctx.INTEGER_().getText());
-        RelDataType nonNullableInt = 
typeFactory.createSqlType(SqlTypeName.INTEGER);
-        return rexBuilder.makeInputRef(nonNullableInt, index);
+        if ((ctx.getParent() instanceof CastContext) && 
"VARCHAR".equals(ctx.getParent().getStop().getText())) {
+            return 
rexBuilder.makeInputRef(typeFactory.createJavaType(String.class), index);
+        } else if ((ctx.getParent() instanceof CastContext) && 
"INTEGER".equals(ctx.getParent().getStop().getText())) {
+            return 
rexBuilder.makeInputRef(typeFactory.createJavaType(Integer.class), index);
+        } else if ((ctx.getParent() instanceof CastContext) && 
"BIGINT".equals(ctx.getParent().getStop().getText())) {
+            return 
rexBuilder.makeInputRef(typeFactory.createJavaType(Long.class), index);
+        }
+        if (null != columnMap.get(index)) {
+            Class dataType = getClass(columnMap.get(index));
+            return 
rexBuilder.makeInputRef(typeFactory.createJavaType(dataType), index);
+        }
+        return 
rexBuilder.makeInputRef(typeFactory.createJavaType(Integer.class), index);
+    }
+    
+    /**
+     * Switch sql type to java type, reference to java.sql.Types.
+     *
+     * @param dataType sql type
+     * @return java type
+     */
+    private Class getClass(final int dataType) {
+        switch (dataType) {
+            case -5:
+                return Long.class;
+            case 4:
+                return Integer.class;
+            case 6:
+                return Float.class;
+            case 8:
+                return Double.class;
+            case 1:
+                return String.class;
+            case 12:
+                return String.class;
+            case 91:
+                return Date.class;
+            default:
+                return String.class;
+        }
     }
     
     @Override
@@ -166,10 +209,20 @@ public final class ParseRexNodeVisitorImpl extends 
ParseRexNodeBaseVisitor<RexNo
             RelDataType nonNullableInt = 
typeFactory.createSqlType(SqlTypeName.INTEGER);
             return rexBuilder.makeLiteral(number, nonNullableInt, false);
         }
+        if (null != ctx.PLACEHOLDER_()) {
+            if 
(parameters.get(ctx.PLACEHOLDER_().getText()).getClass().equals(Integer.class)) 
{
+                return 
rexBuilder.makeLiteral(parameters.get(ctx.PLACEHOLDER_().getText()), 
typeFactory.createSqlType(SqlTypeName.INTEGER), false);
+            } else if 
(parameters.get(ctx.PLACEHOLDER_().getText()).getClass().equals(Long.class)) {
+                return 
rexBuilder.makeLiteral(parameters.get(ctx.PLACEHOLDER_().getText()), 
typeFactory.createSqlType(SqlTypeName.BIGINT), false);
+            } else if 
(parameters.get(ctx.PLACEHOLDER_().getText()).getClass().equals(Float.class)) {
+                return 
rexBuilder.makeLiteral(parameters.get(ctx.PLACEHOLDER_().getText()), 
typeFactory.createSqlType(SqlTypeName.FLOAT), false);
+            }
+        }
         if (null != ctx.STRING_()) {
-            RelDataType varchar = 
typeFactory.createSqlType(SqlTypeName.VARCHAR);
-            return rexBuilder.makeLiteral(ctx.STRING_().getText(), varchar, 
false);
+            String literalValue = ctx.STRING_().getText().replace("\"", 
"").replace("'", "");
+            return rexBuilder.makeLiteral(literalValue, 
typeFactory.createSqlType(SqlTypeName.VARCHAR), false);
         }
+        
         throw new OptimizationSQLRexNodeException(ctx.getText());
     }
     
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/StringToRexNodeUtil.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/StringToRexNodeUtil.java
index b028f6ea187..86c0d9ad460 100644
--- 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/StringToRexNodeUtil.java
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/StringToRexNodeUtil.java
@@ -28,6 +28,8 @@ import org.apache.calcite.rex.RexNode;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.parser.rexnode.ParseRexNodeLexer;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.parser.rexnode.ParseRexNodeParser;
 
+import java.util.Map;
+
 /**
  * Utility for parsing string and generate rex node.
  */
@@ -37,15 +39,17 @@ public final class StringToRexNodeUtil {
      * Parse string and generate rex node.
      * @param filterValue filter condition
      * @param rexBuilder used to build rex node
+     * @param parameters parameters for SQL placeholder
+     * @param columnMap mapping of column id and column type
      * @return rex node
      */
-    public static RexNode buildRexNode(final String filterValue, final 
RexBuilder rexBuilder) {
+    public static RexNode buildRexNode(final String filterValue, final 
RexBuilder rexBuilder, final Map parameters, final Map<Integer, Integer> 
columnMap) {
         CharStream input = CharStreams.fromString(filterValue);
         ParseRexNodeLexer lexer = new ParseRexNodeLexer(input);
         CommonTokenStream tokens = new CommonTokenStream(lexer);
         ParseRexNodeParser parser = new ParseRexNodeParser(tokens);
         ParseTree tree = parser.expression();
-        ParseRexNodeVisitorImpl visitor = new 
ParseRexNodeVisitorImpl(rexBuilder, new 
JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT));
+        ParseRexNodeVisitorImpl visitor = new 
ParseRexNodeVisitorImpl(rexBuilder, new 
JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT), parameters, columnMap);
         return visitor.visit(tree);
     }
 }
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableFilterRule.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableFilterRule.java
index 5e83d5320c7..89a33566923 100644
--- 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableFilterRule.java
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableFilterRule.java
@@ -21,9 +21,13 @@ import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rel.logical.LogicalFilter;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.tools.RelBuilderFactory;
 
 import java.util.Collections;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Planner rule for pushing filters into table scan.
@@ -36,6 +40,21 @@ public class TranslatableFilterRule extends RelOptRule {
         super(operand(LogicalFilter.class, 
operand(TranslatableTableScan.class, none())), relBuilderFactory, 
"TranslatableFilterRule");
     }
     
+    @Override
+    public boolean matches(final RelOptRuleCall call) {
+        LogicalFilter filter = call.rel(0);
+        RexCall condition = (RexCall) filter.getCondition();
+        for (RexNode each : condition.getOperands()) {
+            String condtionPattern = "\\$[A-Za-z]";
+            String tmp = each.toString();
+            Matcher matcher = Pattern.compile(condtionPattern).matcher(tmp);
+            if (matcher.find()) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
     @Override
     public void onMatch(final RelOptRuleCall call) {
         LogicalFilter filter = call.rel(0);
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableProjectFilterRule.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableProjectFilterRule.java
index adebcd9fedb..c32dbacdbe4 100644
--- 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableProjectFilterRule.java
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableProjectFilterRule.java
@@ -22,12 +22,15 @@ import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rel.logical.LogicalFilter;
 import org.apache.calcite.rel.logical.LogicalProject;
+import org.apache.calcite.rex.RexCall;
 import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.tools.RelBuilderFactory;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Planner rule for pushing projections and filters into table scan.
@@ -64,4 +67,19 @@ public class TranslatableProjectFilterRule extends 
RelOptRule {
         }
         return result;
     }
+    
+    @Override
+    public boolean matches(final RelOptRuleCall call) {
+        LogicalFilter filter = call.rel(1);
+        RexCall condition = (RexCall) filter.getCondition();
+        for (RexNode each : condition.getOperands()) {
+            String condtionPattern = "\\$[A-Za-z]";
+            String tmp = each.toString();
+            Matcher matcher = Pattern.compile(condtionPattern).matcher(tmp);
+            if (matcher.find()) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableTableScan.java
 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableTableScan.java
index 1905f82bda8..03c4123480d 100644
--- 
a/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableTableScan.java
+++ 
b/kernel/sql-federation/optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/TranslatableTableScan.java
@@ -39,11 +39,15 @@ import org.apache.calcite.rel.metadata.RelMetadataQuery;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexNode;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Translatable table scan.
@@ -156,11 +160,28 @@ public class TranslatableTableScan extends TableScan 
implements EnumerableRel {
     public Result implement(final EnumerableRelImplementor implementor, final 
Prefer pref) {
         PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), 
getRowType(), pref.preferArray());
         if (null == filters) {
+            return generateCodeForNullFilters(implementor, physType);
+        } else {
+            String[] filterValues = new String[number];
+            addFilter(filters, filterValues);
+            return generateCodeForFilters(implementor, physType, filterValues);
+        }
+    }
+    
+    private Result generateCodeForNullFilters(final EnumerableRelImplementor 
implementor, final PhysType physType) {
+        if (fields.length == 1) {
             return implementor.result(physType, 
Blocks.toBlock(Expressions.call(table.getExpression(FederationTranslatableTable.class),
-                    "project", implementor.getRootExpression(), 
Expressions.constant(fields))));
+                    "projectScalar", implementor.getRootExpression(), 
Expressions.constant(fields))));
+        }
+        return implementor.result(physType, 
Blocks.toBlock(Expressions.call(table.getExpression(FederationTranslatableTable.class),
+                "project", implementor.getRootExpression(), 
Expressions.constant(fields))));
+    }
+    
+    private Result generateCodeForFilters(final EnumerableRelImplementor 
implementor, final PhysType physType, final String[] filterValues) {
+        if (fields.length == 1) {
+            return implementor.result(physType, 
Blocks.toBlock(Expressions.call(table.getExpression(FederationTranslatableTable.class),
+                    "projectAndFilterScalar", implementor.getRootExpression(), 
Expressions.constant(filterValues), Expressions.constant(fields))));
         }
-        String[] filterValues = new String[number];
-        addFilter(filters, filterValues);
         return implementor.result(physType, 
Blocks.toBlock(Expressions.call(table.getExpression(FederationTranslatableTable.class),
                 "projectAndFilter", implementor.getRootExpression(), 
Expressions.constant(filterValues), Expressions.constant(fields))));
     }
@@ -168,8 +189,31 @@ public class TranslatableTableScan extends TableScan 
implements EnumerableRel {
     private void addFilter(final List<RexNode> filters, final String[] 
filterValues) {
         int index = 0;
         for (RexNode filter : filters) {
-            filterValues[index] = filter.toString();
+            RexCall call = (RexCall) filter;
+            String columnMap = generateColumnMap(call);
+            filterValues[index] = filter + columnMap;
             index++;
         }
     }
+    
+    private String generateColumnMap(final RexCall call) {
+        Map<Integer, Integer> result = new HashMap<>();
+        traverseRexCall(call, result);
+        return result.toString();
+    }
+    
+    private void traverseRexCall(final RexCall call, final Map columnMap) {
+        for (RexNode each : call.getOperands()) {
+            if (each instanceof RexInputRef) {
+                RexInputRef reference = (RexInputRef) each;
+                String referenceName = reference.getName();
+                Integer columnId = Integer.valueOf(referenceName.replace("$", 
""));
+                Integer columnType = translatableTable.getColumnType(columnId);
+                columnMap.put(columnId, columnType);
+            }
+            if (each instanceof RexCall) {
+                traverseRexCall((RexCall) each, columnMap);
+            }
+        }
+    }
 }
diff --git 
a/kernel/sql-federation/optimizer/src/test/java/org/apache/shardingsphere/sqlfederation/optimizer/it/SQLOptimizeEngineIT.java
 
b/kernel/sql-federation/optimizer/src/test/java/org/apache/shardingsphere/sqlfederation/optimizer/it/SQLOptimizeEngineIT.java
index 845548d062f..69a59e52412 100644
--- 
a/kernel/sql-federation/optimizer/src/test/java/org/apache/shardingsphere/sqlfederation/optimizer/it/SQLOptimizeEngineIT.java
+++ 
b/kernel/sql-federation/optimizer/src/test/java/org/apache/shardingsphere/sqlfederation/optimizer/it/SQLOptimizeEngineIT.java
@@ -198,7 +198,7 @@ public final class SQLOptimizeEngineIT {
     @Test
     public void assertOptimize() {
         SQLStatement sqlStatement = 
sqlParserRule.getSQLParserEngine(DatabaseTypeEngine.getTrunkDatabaseTypeName(new
 H2DatabaseType())).parse(testcase.getSql(), false);
-        String expected = 
optimizeEngine.optimize(sqlStatement).getBestPlan().explain().replaceAll("[\r\n]",
 "");
-        assertThat(testcase.getAssertion().getExpectedResult(), is(expected));
+        String actual = 
optimizeEngine.optimize(sqlStatement).getBestPlan().explain().replaceAll("[\r\n]",
 "");
+        assertThat(actual, is(testcase.getAssertion().getExpectedResult()));
     }
 }
diff --git 
a/kernel/sql-federation/optimizer/src/test/resources/cases/federation-query-sql-cases.xml
 
b/kernel/sql-federation/optimizer/src/test/resources/cases/federation-query-sql-cases.xml
index cb3da3fbf9b..b8de1975fb5 100644
--- 
a/kernel/sql-federation/optimizer/src/test/resources/cases/federation-query-sql-cases.xml
+++ 
b/kernel/sql-federation/optimizer/src/test/resources/cases/federation-query-sql-cases.xml
@@ -18,15 +18,15 @@
 
 <test-cases>
     <test-case sql="SELECT t_order_federate.order_id, 
t_order_federate.user_id, t_user_info.user_id FROM t_order_federate JOIN 
t_user_info ON t_order_federate.user_id = t_user_info.user_id WHERE 
t_user_info.user_id = 13">
-        <assertion expected-result="EnumerableCalc(expr#0..4=[{inputs}], 
proj#0..1=[{exprs}], user_id0=[$t3])  EnumerableHashJoin(condition=[=($2, $4)], 
joinType=[inner])    EnumerableCalc(expr#0..1=[{inputs}], 
expr#2=[CAST($t1):VARCHAR], proj#0..2=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 
1]])    EnumerableCalc(expr#0=[{inputs}], expr#1=[CAST($t0):VARCHAR], 
proj#0..1=[{exprs}])      TranslatableTableScan(table=[[federate_jdbc, 
t_user_in [...]
+        <assertion expected-result="EnumerableCalc(expr#0..4=[{inputs}], 
proj#0..1=[{exprs}], user_id0=[$t3])  EnumerableHashJoin(condition=[=($2, $4)], 
joinType=[inner])    EnumerableCalc(expr#0..1=[{inputs}], 
expr#2=[CAST($t1):VARCHAR], proj#0..2=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 
1]])    EnumerableCalc(expr#0=[{inputs}], expr#1=[CAST($t0):VARCHAR], 
proj#0..1=[{exprs}])      TranslatableTableScan(table=[[federate_jdbc, 
t_user_in [...]
     </test-case>
     
     <test-case sql="SELECT user_id, information FROM t_user_info WHERE user_id 
= 12">
-        <assertion 
expected-result="TranslatableTableScan(table=[[federate_jdbc, t_user_info]], 
fields=[[0, 1]], filters=[[=(CAST($0):INTEGER, 12), null]])" />
+        <assertion 
expected-result="TranslatableTableScan(table=[[federate_jdbc, t_user_info]], 
fields=[[0, 1]], filters=[[=(CAST($0):INTEGER, 12){0=12}, null]])" />
     </test-case>
     
     <test-case sql="SELECT user_id FROM t_user_info WHERE user_id = 12">
-        <assertion 
expected-result="TranslatableTableScan(table=[[federate_jdbc, t_user_info]], 
fields=[[0]], filters=[[=(CAST($0):INTEGER, 12)]])" />
+        <assertion 
expected-result="TranslatableTableScan(table=[[federate_jdbc, t_user_info]], 
fields=[[0]], filters=[[=(CAST($0):INTEGER, 12){0=12}]])" />
     </test-case>
     
     <test-case sql="SELECT t_order_federate.order_id, 
t_order_federate.user_id, t_user_info.user_id FROM t_order_federate , 
t_user_info WHERE t_order_federate.user_id = t_user_info.user_id">
@@ -38,15 +38,15 @@
     </test-case>
     
     <test-case sql="SELECT t_order_federate.order_id, 
t_order_federate.user_id, t_user_info.user_id FROM t_order_federate 
,t_user_info WHERE t_order_federate.user_id = t_user_info.user_id AND 
t_user_info.user_id = 13">
-        <assertion expected-result="EnumerableCalc(expr#0..4=[{inputs}], 
proj#0..1=[{exprs}], user_id0=[$t3])  EnumerableHashJoin(condition=[=($2, $4)], 
joinType=[inner])    EnumerableCalc(expr#0..1=[{inputs}], 
expr#2=[CAST($t1):VARCHAR], proj#0..2=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 
1]])    EnumerableCalc(expr#0=[{inputs}], expr#1=[CAST($t0):VARCHAR], 
proj#0..1=[{exprs}])      TranslatableTableScan(table=[[federate_jdbc, 
t_user_in [...]
+        <assertion expected-result="EnumerableCalc(expr#0..4=[{inputs}], 
proj#0..1=[{exprs}], user_id0=[$t3])  EnumerableHashJoin(condition=[=($2, $4)], 
joinType=[inner])    EnumerableCalc(expr#0..1=[{inputs}], 
expr#2=[CAST($t1):VARCHAR], proj#0..2=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 
1]])    EnumerableCalc(expr#0=[{inputs}], expr#1=[CAST($t0):VARCHAR], 
proj#0..1=[{exprs}])      TranslatableTableScan(table=[[federate_jdbc, 
t_user_in [...]
     </test-case>
     
     <test-case sql="SELECT user.user_id, user.information FROM (SELECT * FROM 
t_user_info WHERE user_id > 1) as user ">
-        <assertion 
expected-result="TranslatableTableScan(table=[[federate_jdbc, t_user_info]], 
fields=[[0, 1]], filters=[[>(CAST($0):INTEGER, 1), null]])" />
+        <assertion 
expected-result="TranslatableTableScan(table=[[federate_jdbc, t_user_info]], 
fields=[[0, 1]], filters=[[>(CAST($0):INTEGER, 1){0=12}, null]])" />
     </test-case>
     
     <test-case sql="SELECT t_order_federate.order_id, t_order_federate.user_id 
FROM t_order_federate WHERE EXISTS (SELECT * FROM t_user_info WHERE 
t_order_federate.user_id = t_user_info.user_id)">
-        <assertion expected-result="EnumerableCalc(expr#0..3=[{inputs}], 
expr#4=[IS NOT NULL($t3)], proj#0..1=[{exprs}], $condition=[$t4])  
EnumerableCorrelate(correlation=[$cor0], joinType=[left], 
requiredColumns=[{1}])    TranslatableTableScan(table=[[federate_jdbc, 
t_order_federate]], fields=[[0, 1, 2]])    EnumerableAggregate(group=[{}], 
agg#0=[MIN($0)])      EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], 
$f0=[$t2])        TranslatableTableScan(table=[[federate_jdbc, t_user_info [...]
+        <assertion expected-result="EnumerableCalc(expr#0..3=[{inputs}], 
expr#4=[IS NOT NULL($t3)], proj#0..1=[{exprs}], $condition=[$t4])  
EnumerableCorrelate(correlation=[$cor0], joinType=[left], 
requiredColumns=[{1}])    TranslatableTableScan(table=[[federate_jdbc, 
t_order_federate]], fields=[[0, 1, 2]])    EnumerableAggregate(group=[{}], 
agg#0=[MIN($0)])      EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], 
expr#3=[$cor0], expr#4=[$t3.user_id], expr#5=[CAST($t4):VARCHAR], expr#6=[ [...]
     </test-case>
     
     <test-case sql="SELECT t_order_federate.order_id, t_order_federate.user_id 
FROM t_order_federate WHERE t_order_federate.user_id IN (SELECT 
t_user_info.user_id FROM t_user_info)">
@@ -54,11 +54,11 @@
     </test-case>
     
     <test-case sql="SELECT t_order_federate.order_id, t_order_federate.user_id 
FROM t_order_federate WHERE user_id BETWEEN (SELECT user_id FROM t_user_info 
WHERE user_id = 1) AND (SELECT user_id FROM t_user_info WHERE user_id = 3)">
-        <assertion expected-result="EnumerableCalc(expr#0..2=[{inputs}], 
proj#0..1=[{exprs}])  EnumerableNestedLoopJoin(condition=[&lt;=($1, $2)], 
joinType=[inner])    EnumerableCalc(expr#0..2=[{inputs}], proj#0..1=[{exprs}])  
    EnumerableNestedLoopJoin(condition=[>=($1, $2)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 
1]])        EnumerableAggregate(group=[{}], agg#0=[SINGLE_VALUE($0)])          
TranslatableTableScan(table=[[f [...]
+        <assertion expected-result="EnumerableCalc(expr#0..2=[{inputs}], 
proj#0..1=[{exprs}])  EnumerableNestedLoopJoin(condition=[&lt;=($1, $2)], 
joinType=[inner])    EnumerableCalc(expr#0..2=[{inputs}], proj#0..1=[{exprs}])  
    EnumerableNestedLoopJoin(condition=[>=($1, $2)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 
1]])        EnumerableAggregate(group=[{}], agg#0=[SINGLE_VALUE($0)])          
TranslatableTableScan(table=[[f [...]
     </test-case>
     
     <test-case sql="SELECT order_id, user_id FROM t_order_federate UNION 
SELECT 1, user_id FROM t_user_info WHERE information = 'before'">
-        <assertion expected-result="EnumerableUnion(all=[false])  
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 
1]])  EnumerableCalc(expr#0=[{inputs}], expr#1=['1':VARCHAR], EXPR$0=[$t1], 
user_id=[$t0])    TranslatableTableScan(table=[[federate_jdbc, t_user_info]], 
fields=[[0]], filters=[[=(CAST($1):VARCHAR, 'before'), null]])" />
+        <assertion expected-result="EnumerableUnion(all=[false])  
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 
1]])  EnumerableCalc(expr#0=[{inputs}], expr#1=['1':VARCHAR], EXPR$0=[$t1], 
user_id=[$t0])    TranslatableTableScan(table=[[federate_jdbc, t_user_info]], 
fields=[[0]], filters=[[=(CAST($1):VARCHAR, 'before'){1=12}, null]])" />
     </test-case>
     
     <test-case sql="SELECT order_id, user_id FROM t_order_federate LIMIT 1">
@@ -74,7 +74,7 @@
     </test-case>
     
     <test-case sql="select t_order_federate.*, 
t_order_item_federate_sharding.* from t_order_federate, 
t_order_item_federate_sharding where t_order_federate.order_id = 
t_order_item_federate_sharding.item_id AND 
t_order_item_federate_sharding.remarks = 't_order_item_federate_sharding' ">
-        <assertion expected-result="EnumerableCalc(expr#0..9=[{inputs}], 
proj#0..2=[{exprs}], item_id=[$t4], order_id1=[$t5], user_id0=[$t6], 
status0=[$t7], remarks=[$t8])  EnumerableHashJoin(condition=[=($3, $9)], 
joinType=[inner])    EnumerableCalc(expr#0..2=[{inputs}], 
expr#3=[CAST($t0):INTEGER], proj#0..3=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]])    EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t0):INTEGER], 
proj#0..5=[{ [...]
+        <assertion expected-result="EnumerableCalc(expr#0..9=[{inputs}], 
proj#0..2=[{exprs}], item_id=[$t4], order_id1=[$t5], user_id0=[$t6], 
status0=[$t7], remarks=[$t8])  EnumerableHashJoin(condition=[=($3, $9)], 
joinType=[inner])    EnumerableCalc(expr#0..2=[{inputs}], 
expr#3=[CAST($t0):INTEGER], proj#0..3=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]])    EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t0):INTEGER], 
proj#0..5=[{ [...]
     </test-case>
     
     <test-case sql="select o.*, i.* from t_order_federate o, 
t_order_item_federate_sharding i where o.order_id = i.item_id">
@@ -82,7 +82,7 @@
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o JOIN t_order_item i ON o.user_id 
= i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (10, 11) AND 
o.order_id BETWEEN 1000 AND 1909 ORDER BY i.item_id">
-        <assertion expected-result="EnumerableSort(sort0=[$0], dir0=[ASC])  
EnumerableCalc(expr#0..7=[{inputs}], item_id=[$t2], order_id=[$t3], 
user_id=[$t4], product_id=[$t5], quantity=[$t6], creation_date=[$t7])    
EnumerableHashJoin(condition=[AND(=($1, $4), =($0, $3))], joinType=[inner])     
 TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1]], 
filters=[[AND(SEARCH($1, Sarg[10, 11]), SEARCH($0, Sarg[[1000..1909]])), 
null]])      TranslatableTableScan(table=[[feder [...]
+        <assertion expected-result="EnumerableSort(sort0=[$0], dir0=[ASC])  
EnumerableCalc(expr#0..7=[{inputs}], item_id=[$t2], order_id=[$t3], 
user_id=[$t4], product_id=[$t5], quantity=[$t6], creation_date=[$t7])    
EnumerableHashJoin(condition=[AND(=($1, $4), =($0, $3))], joinType=[inner])     
 TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1]], 
filters=[[AND(SEARCH($1, Sarg[10, 11]), SEARCH($0, Sarg[[1000..1909]])){0=-5, 
1=4}, null]])      TranslatableTableScan(ta [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o JOIN t_order_item i ON o.user_id 
= i.user_id AND o.order_id = i.order_id ORDER BY i.item_id">
@@ -90,35 +90,35 @@
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o JOIN t_order_item i ON 
o.order_id=i.order_id AND o.user_id = i.user_id WHERE o.order_id = 1000">
-        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($0, $3), =($1, $4))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[=(CAST($0):BIGINT, 1000), null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):BIGINT, [...]
+        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($0, $3), =($1, $4))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[=(CAST($0):BIGINT, 1000){0=-5}, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):B [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o FORCE INDEX(order_index) JOIN 
t_order_item i ON o.order_id=i.order_id AND o.user_id = i.user_id AND 
o.order_id = 1000">
-        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($0, $3), =($1, $4))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[=(CAST($0):BIGINT, 1000), null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):BIGINT, [...]
+        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($0, $3), =($1, $4))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[=(CAST($0):BIGINT, 1000){0=-5}, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):B [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o FORCE INDEX(order_index) JOIN 
t_order_item i ON o.order_id=i.order_id AND o.user_id = i.user_id AND 
o.order_id in (1000,1001)">
-        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($0, $3), =($1, $4))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[SEARCH($0, Sarg[1000L:JavaType(long), 
1001L:JavaType(long)]:JavaType(long)), null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields [...]
+        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($0, $3), =($1, $4))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[SEARCH($0, Sarg[1000L:JavaType(long), 
1001L:JavaType(long)]:JavaType(long)){0=-5}, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]],  [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o FORCE INDEX(order_index) JOIN 
t_order_item i ON o.order_id=i.order_id AND o.user_id = i.user_id AND 
o.order_id in (1000,1001)">
-        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($0, $3), =($1, $4))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[SEARCH($0, Sarg[1000L:JavaType(long), 
1001L:JavaType(long)]:JavaType(long)), null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields [...]
+        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($0, $3), =($1, $4))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[SEARCH($0, Sarg[1000L:JavaType(long), 
1001L:JavaType(long)]:JavaType(long)){0=-5}, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]],  [...]
     </test-case>
     
     <test-case sql="SELECT COUNT(*) AS items_count FROM t_order o, 
t_order_item i WHERE o.user_id = i.user_id AND o.order_id = i.order_id AND 
o.user_id IN (10, 11) AND o.order_id BETWEEN 1000 AND 1909">
-        <assertion expected-result="EnumerableAggregate(group=[{}], 
items_count=[COUNT()])  EnumerableHashJoin(condition=[AND(=($1, $8), =($0, 
$7))], joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[AND(SEARCH($1, Sarg[10, 11]), 
SEARCH($0, Sarg[[1000..1909]])), null, null, null, null, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[AND(SEARCH($2, Sarg[10, 11]) [...]
+        <assertion expected-result="EnumerableAggregate(group=[{}], 
items_count=[COUNT()])  EnumerableHashJoin(condition=[AND(=($1, $8), =($0, 
$7))], joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[AND(SEARCH($1, Sarg[10, 11]), 
SEARCH($0, Sarg[[1000..1909]])){0=-5, 1=4}, null, null, null, null, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[AND(SEARCH($2, Sa [...]
     </test-case>
     
     <test-case sql="SELECT COUNT(*) AS items_count FROM t_order o JOIN 
t_order_item i ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE 
o.user_id IN (10, 11) AND o.order_id BETWEEN 1000 AND 1909">
-        <assertion expected-result="EnumerableAggregate(group=[{}], 
items_count=[COUNT()])  EnumerableHashJoin(condition=[AND(=($1, $8), =($0, 
$7))], joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[AND(SEARCH($1, Sarg[10, 11]), 
SEARCH($0, Sarg[[1000..1909]])), null, null, null, null, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[AND(SEARCH($2, Sarg[10, 11]) [...]
+        <assertion expected-result="EnumerableAggregate(group=[{}], 
items_count=[COUNT()])  EnumerableHashJoin(condition=[AND(=($1, $8), =($0, 
$7))], joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[AND(SEARCH($1, Sarg[10, 11]), 
SEARCH($0, Sarg[[1000..1909]])){0=-5, 1=4}, null, null, null, null, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[AND(SEARCH($2, Sa [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o JOIN t_order_item i ON o.user_id 
= i.user_id AND o.order_id = i.order_id WHERE (o.order_id = 1000 OR o.order_id 
= 1100) AND o.user_id = 11">
-        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($1, $4), =($0, $3))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[AND(SEARCH(CAST($0):BIGINT, Sarg[1000L:BIGINT, 
1100L:BIGINT]:BIGINT), =(CAST($1):INTEGER, 11)), null]])    
TranslatableTableScan(table=[[federate_jdbc, t_o [...]
+        <assertion expected-result="EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])  EnumerableHashJoin(condition=[AND(=($1, $4), =($0, $3))], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1]], filters=[[AND(SEARCH(CAST($0):BIGINT, Sarg[1000L:BIGINT, 
1100L:BIGINT]:BIGINT), =(CAST($1):INTEGER, 11)){0=-5, 1=4}, null]])    
TranslatableTableScan(table=[[federat [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o JOIN t_order_item i ON o.user_id 
= i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (10, 19) AND 
o.order_id BETWEEN 1000 AND 1909 ORDER BY i.item_id DESC">
-        <assertion expected-result="EnumerableSort(sort0=[$0], dir0=[DESC])  
EnumerableCalc(expr#0..7=[{inputs}], item_id=[$t2], order_id=[$t3], 
user_id=[$t4], product_id=[$t5], quantity=[$t6], creation_date=[$t7])    
EnumerableHashJoin(condition=[AND(=($1, $4), =($0, $3))], joinType=[inner])     
 TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1]], 
filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, Sarg[[1000..1909]])), 
null]])      TranslatableTableScan(table=[[fede [...]
+        <assertion expected-result="EnumerableSort(sort0=[$0], dir0=[DESC])  
EnumerableCalc(expr#0..7=[{inputs}], item_id=[$t2], order_id=[$t3], 
user_id=[$t4], product_id=[$t5], quantity=[$t6], creation_date=[$t7])    
EnumerableHashJoin(condition=[AND(=($1, $4), =($0, $3))], joinType=[inner])     
 TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1]], 
filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, Sarg[[1000..1909]])){0=-5, 
1=4}, null]])      TranslatableTableScan(t [...]
     </test-case>
     
     <test-case sql="SELECT i.*, o.* FROM t_order o JOIN t_order_item i ON 
o.user_id = i.user_id AND o.order_id = i.order_id ORDER BY item_id">
@@ -126,35 +126,35 @@
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o JOIN t_order_item i ON o.user_id 
= i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (10, 19) AND 
o.order_id BETWEEN 1000 AND 1909 ORDER BY i.item_id DESC LIMIT 2">
-        <assertion expected-result="EnumerableLimit(fetch=[2])  
EnumerableSort(sort0=[$0], dir0=[DESC])    EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])      EnumerableHashJoin(condition=[AND(=($1, $4), =($0, 
$3))], joinType=[inner])        TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1]], filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, 
Sarg[[1000..1909]])), null]])       [...]
+        <assertion expected-result="EnumerableLimit(fetch=[2])  
EnumerableSort(sort0=[$0], dir0=[DESC])    EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])      EnumerableHashJoin(condition=[AND(=($1, $4), =($0, 
$3))], joinType=[inner])        TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1]], filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, 
Sarg[[1000..1909]])){0=-5, 1=4}, nu [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM `t_order` o JOIN `t_order_item` i ON 
o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.`user_id` IN (10, 19) 
AND o.`order_id` BETWEEN 1000 AND 1909 ORDER BY i.item_id DESC LIMIT 2, 2">
-        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[2])  
EnumerableSort(sort0=[$0], dir0=[DESC])    EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])      EnumerableHashJoin(condition=[AND(=($1, $4), =($0, 
$3))], joinType=[inner])        TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1]], filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, 
Sarg[[1000..1909]])), n [...]
+        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[2])  
EnumerableSort(sort0=[$0], dir0=[DESC])    EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])      EnumerableHashJoin(condition=[AND(=($1, $4), =($0, 
$3))], joinType=[inner])        TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1]], filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, 
Sarg[[1000..1909]])){0= [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM `t_order` o JOIN `t_order_item` i ON 
o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.`user_id` IN (10, 19) 
AND o.`order_id` BETWEEN 1000 AND 1909 ORDER BY i.item_id DESC LIMIT 2 OFFSET 
2">
-        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[2])  
EnumerableSort(sort0=[$0], dir0=[DESC])    EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])      EnumerableHashJoin(condition=[AND(=($1, $4), =($0, 
$3))], joinType=[inner])        TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1]], filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, 
Sarg[[1000..1909]])), n [...]
+        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[2])  
EnumerableSort(sort0=[$0], dir0=[DESC])    EnumerableCalc(expr#0..7=[{inputs}], 
item_id=[$t2], order_id=[$t3], user_id=[$t4], product_id=[$t5], quantity=[$t6], 
creation_date=[$t7])      EnumerableHashJoin(condition=[AND(=($1, $4), =($0, 
$3))], joinType=[inner])        TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1]], filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, 
Sarg[[1000..1909]])){0= [...]
     </test-case>
     
     <test-case sql="SELECT COUNT(i.user_id) FROM t_order o JOIN t_order_item i 
ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (10, 
19) AND o.order_id BETWEEN 1000 AND 1909 GROUP BY i.item_id ORDER BY i.item_id 
DESC LIMIT 1, 10">
-        <assertion expected-result="EnumerableLimit(offset=[1], fetch=[10])  
EnumerableSort(sort0=[$1], dir0=[DESC])    EnumerableCalc(expr#0..1=[{inputs}], 
EXPR$0=[$t1], item_id=[$t0])      EnumerableAggregate(group=[{0}], 
EXPR$0=[COUNT($1)])        EnumerableCalc(expr#0..4=[{inputs}], item_id=[$t2], 
user_id0=[$t4])          EnumerableHashJoin(condition=[AND(=($1, $4), =($0, 
$3))], joinType=[inner])            
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1]], filt 
[...]
+        <assertion expected-result="EnumerableLimit(offset=[1], fetch=[10])  
EnumerableSort(sort0=[$1], dir0=[DESC])    EnumerableCalc(expr#0..1=[{inputs}], 
EXPR$0=[$t1], item_id=[$t0])      EnumerableAggregate(group=[{0}], 
EXPR$0=[COUNT($1)])        EnumerableCalc(expr#0..4=[{inputs}], item_id=[$t2], 
user_id0=[$t4])          EnumerableHashJoin(condition=[AND(=($1, $4), =($0, 
$3))], joinType=[inner])            
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1]], filt 
[...]
     </test-case>
     
     <test-case sql="SELECT i.user_id FROM t_order o JOIN t_order_item i ON 
o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (10, 19) 
AND o.order_id BETWEEN 1000 AND 1909 GROUP BY i.user_id,i.item_id ORDER BY 
i.item_id DESC LIMIT 1, 10">
-        <assertion expected-result="EnumerableLimit(offset=[1], fetch=[10])  
EnumerableSort(sort0=[$1], dir0=[DESC])    EnumerableAggregate(group=[{0, 1}])  
    EnumerableCalc(expr#0..4=[{inputs}], user_id=[$t4], item_id=[$t2])        
EnumerableHashJoin(condition=[AND(=($1, $4), =($0, $3))], joinType=[inner])     
     TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1]], 
filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, Sarg[[1000..1909]])), 
null]])          Translata [...]
+        <assertion expected-result="EnumerableLimit(offset=[1], fetch=[10])  
EnumerableSort(sort0=[$1], dir0=[DESC])    EnumerableAggregate(group=[{0, 1}])  
    EnumerableCalc(expr#0..4=[{inputs}], user_id=[$t4], item_id=[$t2])        
EnumerableHashJoin(condition=[AND(=($1, $4), =($0, $3))], joinType=[inner])     
     TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1]], 
filters=[[AND(SEARCH($1, Sarg[10, 19]), SEARCH($0, Sarg[[1000..1909]])){0=-5, 
1=4}, null]])         [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o INNER JOIN t_order_item i ON 
o.order_id = i.order_id WHERE o.order_id = 1000">
-        <assertion expected-result="EnumerableCalc(expr#0..6=[{inputs}], 
item_id=[$t1], order_id=[$t2], user_id=[$t3], product_id=[$t4], quantity=[$t5], 
creation_date=[$t6])  EnumerableHashJoin(condition=[=($0, $2)], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0]], filters=[[=(CAST($0):BIGINT, 1000)]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):BIGINT, 1000), null, null, null, [...]
+        <assertion expected-result="EnumerableCalc(expr#0..6=[{inputs}], 
item_id=[$t1], order_id=[$t2], user_id=[$t3], product_id=[$t4], quantity=[$t5], 
creation_date=[$t6])  EnumerableHashJoin(condition=[=($0, $2)], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0]], filters=[[=(CAST($0):BIGINT, 1000){0=-5}]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):BIGINT, 1000){1=-5}, null, [...]
     </test-case>
     
     <test-case sql="SELECT t_order_item.* FROM t_order JOIN t_order_item ON 
t_order.order_id = t_order_item.order_id WHERE t_order.order_id = 1000">
-        <assertion expected-result="EnumerableCalc(expr#0..6=[{inputs}], 
item_id=[$t1], order_id=[$t2], user_id=[$t3], product_id=[$t4], quantity=[$t5], 
creation_date=[$t6])  EnumerableHashJoin(condition=[=($0, $2)], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0]], filters=[[=(CAST($0):BIGINT, 1000)]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):BIGINT, 1000), null, null, null, [...]
+        <assertion expected-result="EnumerableCalc(expr#0..6=[{inputs}], 
item_id=[$t1], order_id=[$t2], user_id=[$t3], product_id=[$t4], quantity=[$t5], 
creation_date=[$t6])  EnumerableHashJoin(condition=[=($0, $2)], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0]], filters=[[=(CAST($0):BIGINT, 1000){0=-5}]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):BIGINT, 1000){1=-5}, null, [...]
     </test-case>
     
     <test-case sql="SELECT i.* FROM t_order o JOIN t_order_item i 
USING(order_id) WHERE o.order_id = 1000">
-        <assertion expected-result="EnumerableCalc(expr#0..6=[{inputs}], 
item_id=[$t1], order_id=[$t2], user_id=[$t3], product_id=[$t4], quantity=[$t5], 
creation_date=[$t6])  EnumerableHashJoin(condition=[=($0, $2)], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0]], filters=[[=(CAST($0):BIGINT, 1000)]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):BIGINT, 1000), null, null, null, [...]
+        <assertion expected-result="EnumerableCalc(expr#0..6=[{inputs}], 
item_id=[$t1], order_id=[$t2], user_id=[$t3], product_id=[$t4], quantity=[$t5], 
creation_date=[$t6])  EnumerableHashJoin(condition=[=($0, $2)], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0]], filters=[[=(CAST($0):BIGINT, 1000){0=-5}]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($1):BIGINT, 1000){1=-5}, null, [...]
     </test-case>
     
     <test-case sql="SELECT DISTINCT t_order.*, t_order_item.order_id FROM 
t_order, t_order_item WHERE t_order.order_id = t_order_item.order_id ORDER BY 
t_order.order_id">
@@ -166,7 +166,7 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o INNER JOIN t_order_item m ON 
o.order_id = m.order_id WHERE m.order_id IN (0, 11)">
-        <assertion expected-result="EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[inner])  TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[SEARCH($0, Sarg[0L:JavaType(long), 
11L:JavaType(long)]:JavaType(long)), null, null, null, null, null]])  
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[SEARCH($1, Sarg[0L:JavaType(long), 
11L:JavaType(long)]:JavaType(long)), null, null, null, null, [...]
+        <assertion expected-result="EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[inner])  TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[SEARCH($0, Sarg[0L:JavaType(long), 
11L:JavaType(long)]:JavaType(long)){0=-5}, null, null, null, null, null]])  
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[SEARCH($1, Sarg[0L:JavaType(long), 
11L:JavaType(long)]:JavaType(long)){1=-5}, null, null, [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_single_table s INNER JOIN t_order o ON 
s.id = o.order_id">
@@ -178,23 +178,19 @@
     </test-case>
     
     <test-case sql="SELECT o.*, i.* FROM t_order_federate o, t_order_item i 
WHERE o.order_id = 1000 AND i.item_id = 100000">
-        <assertion expected-result="EnumerableNestedLoopJoin(condition=[true], 
joinType=[inner])  TranslatableTableScan(table=[[federate_jdbc, 
t_order_federate]], fields=[[0, 1, 2]], filters=[[=(CAST($0):INTEGER, 1000), 
null, null]])  TranslatableTableScan(table=[[federate_jdbc, t_order_item]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($0):BIGINT, 100000), null, null, 
null, null, null]])" />
+        <assertion expected-result="EnumerableNestedLoopJoin(condition=[true], 
joinType=[inner])  TranslatableTableScan(table=[[federate_jdbc, 
t_order_federate]], fields=[[0, 1, 2]], filters=[[=(CAST($0):INTEGER, 
1000){0=12}, null, null]])  TranslatableTableScan(table=[[federate_jdbc, 
t_order_item]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($0):BIGINT, 
100000){0=-5}, null, null, null, null, null]])" />
     </test-case>
     
     <test-case sql="SELECT o.*, i.* FROM t_order_federate o, t_order_item i 
WHERE o.order_id = 1000 AND i.item_id = 100000 LIMIT 3">
-        <assertion expected-result="EnumerableLimit(fetch=[3])  
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])    
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]], filters=[[=(CAST($0):INTEGER, 1000), null, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($0):BIGINT, 100000), null, null, null, null, 
null]])" />
+        <assertion expected-result="EnumerableLimit(fetch=[3])  
EnumerableNestedLoopJoin(condition=[true], joinType=[inner])    
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]], filters=[[=(CAST($0):INTEGER, 1000){0=12}, null, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]], filters=[[=(CAST($0):BIGINT, 100000){0=-5}, null, null, null, null, 
null]])" />
     </test-case>
     
     <test-case sql="SELECT GROUP_CONCAT(i.item_id SEPARATOR ';') AS item_ids 
FROM t_order_federate o INNER JOIN t_order_item_federate_sharding i ON 
o.order_id = i.item_id WHERE i.order_id >= 10000">
-        <assertion expected-result="EnumerableAggregate(group=[{}], 
item_ids=[LISTAGG($0, $1)])  EnumerableCalc(expr#0..2=[{inputs}], expr#3=[';'], 
$f0=[$t2], $f1=[$t3])    EnumerableHashJoin(condition=[=($0, $1)], 
joinType=[inner])      EnumerableCalc(expr#0..2=[{inputs}], 
expr#3=[CAST($t0):INTEGER], order_id0=[$t3])        
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]])      EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t0):INTEGER], 
expr#6=[CA [...]
-    </test-case>
-    
-    <test-case sql="select t_order_federate.*, 
t_order_item_federate_sharding.* from 
t_order_federate,t_order_item_federate_sharding where t_order_federate.order_id 
= t_order_item_federate_sharding.item_id">
-        <assertion expected-result="EnumerableCalc(expr#0..9=[{inputs}], 
proj#0..2=[{exprs}], item_id=[$t4], order_id1=[$t5], user_id0=[$t6], 
status0=[$t7], remarks=[$t8])  EnumerableHashJoin(condition=[=($3, $9)], 
joinType=[inner])    EnumerableCalc(expr#0..2=[{inputs}], 
expr#3=[CAST($t0):INTEGER], proj#0..3=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]])    EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t0):INTEGER], 
proj#0..5=[{ [...]
+        <assertion expected-result="EnumerableAggregate(group=[{}], 
item_ids=[LISTAGG($0, $1)])  EnumerableCalc(expr#0..2=[{inputs}], expr#3=[';'], 
$f0=[$t2], $f1=[$t3])    EnumerableHashJoin(condition=[=($0, $1)], 
joinType=[inner])      EnumerableCalc(expr#0..2=[{inputs}], 
expr#3=[CAST($t0):INTEGER], order_id0=[$t3])        
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]])      EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t0):INTEGER], 
expr#6=[CA [...]
     </test-case>
     
     <test-case sql="select t_order_federate.*, 
t_order_item_federate_sharding.* from t_order_federate, 
t_order_item_federate_sharding where t_order_federate.order_id = 
t_order_item_federate_sharding.item_id AND 
t_order_item_federate_sharding.remarks = 't_order_item_federate_sharding' ">
-        <assertion expected-result="EnumerableCalc(expr#0..9=[{inputs}], 
proj#0..2=[{exprs}], item_id=[$t4], order_id1=[$t5], user_id0=[$t6], 
status0=[$t7], remarks=[$t8])  EnumerableHashJoin(condition=[=($3, $9)], 
joinType=[inner])    EnumerableCalc(expr#0..2=[{inputs}], 
expr#3=[CAST($t0):INTEGER], proj#0..3=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]])    EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t0):INTEGER], 
proj#0..5=[{ [...]
+        <assertion expected-result="EnumerableCalc(expr#0..9=[{inputs}], 
proj#0..2=[{exprs}], item_id=[$t4], order_id1=[$t5], user_id0=[$t6], 
status0=[$t7], remarks=[$t8])  EnumerableHashJoin(condition=[=($3, $9)], 
joinType=[inner])    EnumerableCalc(expr#0..2=[{inputs}], 
expr#3=[CAST($t0):INTEGER], proj#0..3=[{exprs}])      
TranslatableTableScan(table=[[federate_jdbc, t_order_federate]], fields=[[0, 1, 
2]])    EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t0):INTEGER], 
proj#0..5=[{ [...]
     </test-case>
     
     <test-case sql="select o.*, i.* from t_order_federate o, 
t_order_item_federate_sharding i where o.order_id = i.item_id">
@@ -202,43 +198,43 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o INNER JOIN t_order_item i ON 
o.order_id = i.order_id WHERE o.user_id = ? ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=($1, ?0), null, null, null, null, 
null]])    TranslatableTableScan(table=[[federate_jdbc, t_order_item]], 
fields=[[0, 1, 2, 3, 4, 5]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[inner])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=($1, ?0){1=4}, null, null, null, null, 
null]])    TranslatableTableScan(table=[[federate_jdbc, t_order_item]], 
fields=[[0, 1, 2, 3, 4, 5]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o INNER JOIN t_order_item i ON 
o.order_id = i.order_id WHERE o.user_id = ? ORDER BY o.order_id, 7 LIMIT 5, 2">
-        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$0], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]], filters=[[=($1, ?0), null, null, null, null, null]])      
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]])" />
+        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$0], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]], filters=[[=($1, ?0){1=4}, null, null, null, null, null]])      
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o INNER JOIN t_order_item i 
USING(order_id) WHERE o.user_id = ? ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$11], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t0, $t7)], order_id=[$t12], user_id=[$t1], status=[$t2], 
merchant_id=[$t3], remark=[$t4], creation_date=[$t5], item_id=[$t6], 
user_id0=[$t8], product_id=[$t9], quantity=[$t10], creation_date0=[$t11], 
order_id0=[$t0])    EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner]) 
     TranslatableTableScan(table=[[federate_jdbc, t_or [...]
+        <assertion expected-result="EnumerableSort(sort0=[$11], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t0, $t7)], order_id=[$t12], user_id=[$t1], status=[$t2], 
merchant_id=[$t3], remark=[$t4], creation_date=[$t5], item_id=[$t6], 
user_id0=[$t8], product_id=[$t9], quantity=[$t10], creation_date0=[$t11], 
order_id0=[$t0])    EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner]) 
     TranslatableTableScan(table=[[federate_jdbc, t_or [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o INNER JOIN t_order_item i 
USING(order_id) WHERE o.user_id = ? ORDER BY o.order_id, 7 LIMIT 5, 2">
-        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$11], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t0, $t7)], 
order_id=[$t12], user_id=[$t1], status=[$t2], merchant_id=[$t3], remark=[$t4], 
creation_date=[$t5], item_id=[$t6], user_id0=[$t8], product_id=[$t9], 
quantity=[$t10], creation_date0=[$t11], order_id0=[$t0])      
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])        Tra [...]
+        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$11], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t0, $t7)], 
order_id=[$t12], user_id=[$t1], status=[$t2], merchant_id=[$t3], remark=[$t4], 
creation_date=[$t5], item_id=[$t6], user_id0=[$t8], product_id=[$t9], 
quantity=[$t10], creation_date0=[$t11], order_id0=[$t0])      
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])        Tra [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL JOIN t_order_item i WHERE 
o.user_id = ? ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$9], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t0, $t7)], expr#13=[COALESCE($t1, $t8)], 
expr#14=[COALESCE($t5, $t11)], order_id=[$t12], user_id=[$t13], 
creation_date=[$t14], status=[$t2], merchant_id=[$t3], remark=[$t4], 
item_id=[$t6], product_id=[$t9], quantity=[$t10], order_id0=[$t0])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($1, $8), =($5, $11))], 
joinType=[inner])     [...]
+        <assertion expected-result="EnumerableSort(sort0=[$9], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t0, $t7)], expr#13=[COALESCE($t1, $t8)], 
expr#14=[COALESCE($t5, $t11)], order_id=[$t12], user_id=[$t13], 
creation_date=[$t14], status=[$t2], merchant_id=[$t3], remark=[$t4], 
item_id=[$t6], product_id=[$t9], quantity=[$t10], order_id0=[$t0])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($1, $8), =($5, $11))], 
joinType=[inner])     [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL JOIN t_order_item i WHERE 
o.user_id = ? ORDER BY o.order_id, 7 LIMIT 5, 2">
-        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$9], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t0, $t7)], 
expr#13=[COALESCE($t1, $t8)], expr#14=[COALESCE($t5, $t11)], order_id=[$t12], 
user_id=[$t13], creation_date=[$t14], status=[$t2], merchant_id=[$t3], 
remark=[$t4], item_id=[$t6], product_id=[$t9], quantity=[$t10], 
order_id0=[$t0])      EnumerableHashJoin(condition=[AND(=($0, $7), =( [...]
+        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$9], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t0, $t7)], 
expr#13=[COALESCE($t1, $t8)], expr#14=[COALESCE($t5, $t11)], order_id=[$t12], 
user_id=[$t13], creation_date=[$t14], status=[$t2], merchant_id=[$t3], 
remark=[$t4], item_id=[$t6], product_id=[$t9], quantity=[$t10], 
order_id0=[$t0])      EnumerableHashJoin(condition=[AND(=($0, $7), =( [...]
     </test-case>
     
     <test-case sql="SELECT MIN(o.order_id), MIN(o.merchant_id), i.product_id 
FROM t_order o INNER JOIN t_order_item i ON o.order_id = i.order_id WHERE 
o.user_id = 10 GROUP BY i.product_id">
-        <assertion expected-result="EnumerableCalc(expr#0..2=[{inputs}], 
EXPR$0=[$t1], EXPR$1=[$t2], product_id=[$t0])  EnumerableAggregate(group=[{0}], 
EXPR$0=[MIN($1)], EXPR$1=[MIN($2)])    EnumerableCalc(expr#0..3=[{inputs}], 
product_id=[$t3], order_id=[$t0], merchant_id=[$t1])      
EnumerableHashJoin(condition=[=($0, $2)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 3]], 
filters=[[=(CAST($1):INTEGER, 10), null]])        TranslatableTab [...]
+        <assertion expected-result="EnumerableCalc(expr#0..2=[{inputs}], 
EXPR$0=[$t1], EXPR$1=[$t2], product_id=[$t0])  EnumerableAggregate(group=[{0}], 
EXPR$0=[MIN($1)], EXPR$1=[MIN($2)])    EnumerableCalc(expr#0..3=[{inputs}], 
product_id=[$t3], order_id=[$t0], merchant_id=[$t1])      
EnumerableHashJoin(condition=[=($0, $2)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 3]], 
filters=[[=(CAST($1):INTEGER, 10){1=4}, null]])        Translatab [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o CROSS JOIN t_order_item i ON 
o.order_id = i.order_id WHERE o.user_id = 7 ORDER BY o.order_id LIMIT 10, 10">
-        <assertion expected-result="EnumerableLimit(offset=[10], fetch=[10])  
EnumerableSort(sort0=[$0], dir0=[ASC])    EnumerableHashJoin(condition=[=($0, 
$7)], joinType=[inner])      TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($1):INTEGER, 7), null, 
null, null, null, null]])      TranslatableTableScan(table=[[federate_jdbc, 
t_order_item]], fields=[[0, 1, 2, 3, 4, 5]])" />
+        <assertion expected-result="EnumerableLimit(offset=[10], fetch=[10])  
EnumerableSort(sort0=[$0], dir0=[ASC])    EnumerableHashJoin(condition=[=($0, 
$7)], joinType=[inner])      TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($1):INTEGER, 7){1=4}, 
null, null, null, null, null]])      
TranslatableTableScan(table=[[federate_jdbc, t_order_item]], fields=[[0, 1, 2, 
3, 4, 5]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o LEFT JOIN t_order_item i ON 
o.order_id = i.order_id WHERE o.user_id = 10 ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[left])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($1):INTEGER, 10), null, null, 
null, null, null]])    TranslatableTableScan(table=[[federate_jdbc, 
t_order_item]], fields=[[0, 1, 2, 3, 4, 5]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[left])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($1):INTEGER, 10){1=4}, null, 
null, null, null, null]])    TranslatableTableScan(table=[[federate_jdbc, 
t_order_item]], fields=[[0, 1, 2, 3, 4, 5]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o RIGHT JOIN t_order_item i ON 
o.order_id = i.order_id WHERE i.user_id = 10 ORDER BY i.item_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$6], dir0=[ASC])  
EnumerableHashJoin(condition=[=($0, $7)], joinType=[right])    
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]])    TranslatableTableScan(table=[[federate_jdbc, t_order_item]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($2):INTEGER, 10), null, null, 
null, null, null]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$6], dir0=[ASC])  
EnumerableHashJoin(condition=[=($0, $7)], joinType=[right])    
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]])    TranslatableTableScan(table=[[federate_jdbc, t_order_item]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($2):INTEGER, 10){2=4}, null, 
null, null, null, null]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o JOIN t_order_item i ON o.order_id 
= i.order_id WHERE o.user_id = 10 OR i.user_id = 10 ORDER BY o.order_id">
@@ -246,11 +242,11 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o LEFT JOIN t_order_item i 
USING(order_id) WHERE o.user_id = 10 ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$11], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t0, $t7)], order_id=[$t12], user_id=[$t1], status=[$t2], 
merchant_id=[$t3], remark=[$t4], creation_date=[$t5], item_id=[$t6], 
user_id0=[$t8], product_id=[$t9], quantity=[$t10], creation_date0=[$t11], 
order_id0=[$t0])    EnumerableHashJoin(condition=[=($0, $7)], joinType=[left])  
    TranslatableTableScan(table=[[federate_jdbc, t_ord [...]
+        <assertion expected-result="EnumerableSort(sort0=[$11], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t0, $t7)], order_id=[$t12], user_id=[$t1], status=[$t2], 
merchant_id=[$t3], remark=[$t4], creation_date=[$t5], item_id=[$t6], 
user_id0=[$t8], product_id=[$t9], quantity=[$t10], creation_date0=[$t11], 
order_id0=[$t0])    EnumerableHashJoin(condition=[=($0, $7)], joinType=[left])  
    TranslatableTableScan(table=[[federate_jdbc, t_ord [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o RIGHT JOIN t_order_item i 
USING(order_id) WHERE i.user_id = 10 ORDER BY i.item_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$6], dir0=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t0, $t7)], 
order_id=[$t12], user_id=[$t1], status=[$t2], merchant_id=[$t3], remark=[$t4], 
creation_date=[$t5], item_id=[$t6], user_id0=[$t8], product_id=[$t9], 
quantity=[$t10], creation_date0=[$t11])    EnumerableHashJoin(condition=[=($0, 
$7)], joinType=[right])      TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1, 2, 3, 4, 5]])      T [...]
+        <assertion expected-result="EnumerableSort(sort0=[$6], dir0=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t0, $t7)], 
order_id=[$t12], user_id=[$t1], status=[$t2], merchant_id=[$t3], remark=[$t4], 
creation_date=[$t5], item_id=[$t6], user_id0=[$t8], product_id=[$t9], 
quantity=[$t10], creation_date0=[$t11])    EnumerableHashJoin(condition=[=($0, 
$7)], joinType=[right])      TranslatableTableScan(table=[[federate_jdbc, 
t_order]], fields=[[0, 1, 2, 3, 4, 5]])      T [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o JOIN t_order_item i 
USING(order_id) WHERE o.user_id = 10 OR i.user_id = 10 ORDER BY o.order_id, 7">
@@ -258,19 +254,19 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o INNER JOIN t_merchant m 
USING(merchant_id) WHERE o.user_id = 10 ORDER BY o.order_id">
-        <assertion expected-result="EnumerableSort(sort0=[$1], dir0=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t3, $t6)], 
merchant_id=[$t12], order_id=[$t0], user_id=[$t1], status=[$t2], remark=[$t4], 
creation_date=[$t5], country_id=[$t7], merchant_name=[$t8], 
business_code=[$t9], telephone=[$t10], creation_date0=[$t11])    
EnumerableHashJoin(condition=[=($3, $6)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
[...]
+        <assertion expected-result="EnumerableSort(sort0=[$1], dir0=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t3, $t6)], 
merchant_id=[$t12], order_id=[$t0], user_id=[$t1], status=[$t2], remark=[$t4], 
creation_date=[$t5], country_id=[$t7], merchant_name=[$t8], 
business_code=[$t9], telephone=[$t10], creation_date0=[$t11])    
EnumerableHashJoin(condition=[=($3, $6)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
[...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o INNER JOIN t_merchant m 
USING(merchant_id) WHERE o.user_id = 10 ORDER BY o.order_id LIMIT 5, 2">
-        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$1], dir0=[ASC])    EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t3, $t6)], merchant_id=[$t12], order_id=[$t0], 
user_id=[$t1], status=[$t2], remark=[$t4], creation_date=[$t5], 
country_id=[$t7], merchant_name=[$t8], business_code=[$t9], telephone=[$t10], 
creation_date0=[$t11])      EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[inner])        TranslatableTableScan(table=[[fed [...]
+        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$1], dir0=[ASC])    EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t3, $t6)], merchant_id=[$t12], order_id=[$t0], 
user_id=[$t1], status=[$t2], remark=[$t4], creation_date=[$t5], 
country_id=[$t7], merchant_name=[$t8], business_code=[$t9], telephone=[$t10], 
creation_date0=[$t11])      EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[inner])        TranslatableTableScan(table=[[fed [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL LEFT JOIN t_order_item i 
WHERE o.user_id = 10 ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$9], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t0, $t7)], expr#13=[COALESCE($t1, $t8)], 
expr#14=[COALESCE($t5, $t11)], order_id=[$t12], user_id=[$t13], 
creation_date=[$t14], status=[$t2], merchant_id=[$t3], remark=[$t4], 
item_id=[$t6], product_id=[$t9], quantity=[$t10], order_id0=[$t0])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($1, $8), =($5, $11))], 
joinType=[left])      [...]
+        <assertion expected-result="EnumerableSort(sort0=[$9], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t0, $t7)], expr#13=[COALESCE($t1, $t8)], 
expr#14=[COALESCE($t5, $t11)], order_id=[$t12], user_id=[$t13], 
creation_date=[$t14], status=[$t2], merchant_id=[$t3], remark=[$t4], 
item_id=[$t6], product_id=[$t9], quantity=[$t10], order_id0=[$t0])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($1, $8), =($5, $11))], 
joinType=[left])      [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL RIGHT JOIN t_order_item i 
WHERE i.user_id = 10 ORDER BY i.item_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$6], dir0=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t0, $t7)], 
expr#13=[COALESCE($t1, $t8)], expr#14=[COALESCE($t5, $t11)], order_id=[$t12], 
user_id=[$t13], creation_date=[$t14], status=[$t2], merchant_id=[$t3], 
remark=[$t4], item_id=[$t6], product_id=[$t9], quantity=[$t10])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($1, $8), =($5, $11))], 
joinType=[right])      TranslatableTableScan(table=[[federate_ [...]
+        <assertion expected-result="EnumerableSort(sort0=[$6], dir0=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t0, $t7)], 
expr#13=[COALESCE($t1, $t8)], expr#14=[COALESCE($t5, $t11)], order_id=[$t12], 
user_id=[$t13], creation_date=[$t14], status=[$t2], merchant_id=[$t3], 
remark=[$t4], item_id=[$t6], product_id=[$t9], quantity=[$t10])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($1, $8), =($5, $11))], 
joinType=[right])      TranslatableTableScan(table=[[federate_ [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL JOIN t_order_item i WHERE 
o.user_id = 10 OR i.user_id = 10 ORDER BY o.order_id, 7">
@@ -278,27 +274,27 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL JOIN t_merchant m WHERE 
o.user_id = 10 ORDER BY o.order_id">
-        <assertion expected-result="EnumerableSort(sort0=[$2], dir0=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t3, $t6)], 
expr#13=[COALESCE($t5, $t11)], merchant_id=[$t12], creation_date=[$t13], 
order_id=[$t0], user_id=[$t1], status=[$t2], remark=[$t4], country_id=[$t7], 
merchant_name=[$t8], business_code=[$t9], telephone=[$t10])    
EnumerableHashJoin(condition=[AND(=($3, $6), =($5, $11))], joinType=[inner])    
  TranslatableTableScan(table=[[federate_jdbc, t_order] [...]
+        <assertion expected-result="EnumerableSort(sort0=[$2], dir0=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t3, $t6)], 
expr#13=[COALESCE($t5, $t11)], merchant_id=[$t12], creation_date=[$t13], 
order_id=[$t0], user_id=[$t1], status=[$t2], remark=[$t4], country_id=[$t7], 
merchant_name=[$t8], business_code=[$t9], telephone=[$t10])    
EnumerableHashJoin(condition=[AND(=($3, $6), =($5, $11))], joinType=[inner])    
  TranslatableTableScan(table=[[federate_jdbc, t_order] [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL JOIN t_merchant m WHERE 
o.user_id = 10 ORDER BY o.order_id LIMIT 5, 2">
-        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$2], dir0=[ASC])    EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t3, $t6)], expr#13=[COALESCE($t5, $t11)], 
merchant_id=[$t12], creation_date=[$t13], order_id=[$t0], user_id=[$t1], 
status=[$t2], remark=[$t4], country_id=[$t7], merchant_name=[$t8], 
business_code=[$t9], telephone=[$t10])      
EnumerableHashJoin(condition=[AND(=($3, $6), =($5, $11))], joinType=[inner])    
    Transla [...]
+        <assertion expected-result="EnumerableLimit(offset=[5], fetch=[2])  
EnumerableSort(sort0=[$2], dir0=[ASC])    EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t3, $t6)], expr#13=[COALESCE($t5, $t11)], 
merchant_id=[$t12], creation_date=[$t13], order_id=[$t0], user_id=[$t1], 
status=[$t2], remark=[$t4], country_id=[$t7], merchant_name=[$t8], 
business_code=[$t9], telephone=[$t10])      
EnumerableHashJoin(condition=[AND(=($3, $6), =($5, $11))], joinType=[inner])    
    Transla [...]
     </test-case>
     
     <test-case sql="SELECT MIN(o.order_id), MIN(o.merchant_id), 
MIN(m.merchant_name) FROM t_order o INNER JOIN t_merchant m ON o.merchant_id = 
m.merchant_id WHERE o.user_id = 10 GROUP BY m.merchant_id">
-        <assertion expected-result="EnumerableCalc(expr#0..3=[{inputs}], 
EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])  EnumerableAggregate(group=[{0}], 
EXPR$0=[MIN($1)], EXPR$1=[MIN($2)], EXPR$2=[MIN($3)])    
EnumerableCalc(expr#0..3=[{inputs}], merchant_id0=[$t2], order_id=[$t0], 
merchant_id=[$t1], merchant_name=[$t3])      
EnumerableHashJoin(condition=[=($1, $2)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 3]], 
filters=[[=(CAST($1):INTEGER [...]
+        <assertion expected-result="EnumerableCalc(expr#0..3=[{inputs}], 
EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])  EnumerableAggregate(group=[{0}], 
EXPR$0=[MIN($1)], EXPR$1=[MIN($2)], EXPR$2=[MIN($3)])    
EnumerableCalc(expr#0..3=[{inputs}], merchant_id0=[$t2], order_id=[$t0], 
merchant_id=[$t1], merchant_name=[$t3])      
EnumerableHashJoin(condition=[=($1, $2)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 3]], 
filters=[[=(CAST($1):INTEGER [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o CROSS JOIN t_merchant m ON 
o.merchant_id = m.merchant_id WHERE o.user_id = 10 ORDER BY o.order_id, 7 LIMIT 
10, 10">
-        <assertion expected-result="EnumerableLimit(offset=[10], fetch=[10])  
EnumerableSort(sort0=[$0], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableHashJoin(condition=[=($3, $6)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]], filters=[[=(CAST($1):INTEGER, 10), null, null, null, null, null]])      
TranslatableTableScan(table=[[federate_jdbc, t_merchant]], fields=[[0, 1, 2, 3, 
4, 5]])" />
+        <assertion expected-result="EnumerableLimit(offset=[10], fetch=[10])  
EnumerableSort(sort0=[$0], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableHashJoin(condition=[=($3, $6)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]], filters=[[=(CAST($1):INTEGER, 10){1=4}, null, null, null, null, null]])    
  TranslatableTableScan(table=[[federate_jdbc, t_merchant]], fields=[[0, 1, 2, 
3, 4, 5]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o LEFT JOIN t_merchant m ON 
o.merchant_id = m.merchant_id WHERE o.user_id = 10 ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[left])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($1):INTEGER, 10), null, null, 
null, null, null]])    TranslatableTableScan(table=[[federate_jdbc, 
t_merchant]], fields=[[0, 1, 2, 3, 4, 5]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[left])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($1):INTEGER, 10){1=4}, null, 
null, null, null, null]])    TranslatableTableScan(table=[[federate_jdbc, 
t_merchant]], fields=[[0, 1, 2, 3, 4, 5]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o RIGHT JOIN t_merchant m ON 
o.merchant_id = m.merchant_id WHERE m.country_id = 1 ORDER BY o.order_id, 
m.merchant_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[right])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]])    TranslatableTableScan(table=[[federate_jdbc, 
t_merchant]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($1):INTEGER, 1), 
null, null, null, null, null]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[right])    TranslatableTableScan(table=[[federate_jdbc, t_order]], 
fields=[[0, 1, 2, 3, 4, 5]])    TranslatableTableScan(table=[[federate_jdbc, 
t_merchant]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($1):INTEGER, 
1){1=5}, null, null, null, null, null]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o JOIN t_merchant m ON o.merchant_id 
= m.merchant_id  where o.user_id = 10 OR m.country_id = 1 ORDER BY o.order_id, 
7">
@@ -306,19 +302,19 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p INNER JOIN t_product_detail d ON 
p.product_id = d.product_id WHERE p.product_id > 10 ORDER BY p.product_id DESC">
-        <assertion expected-result="EnumerableSort(sort0=[$0], dir0=[DESC])  
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])    
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, 2, 3, 
4, 5]], filters=[[>($0, 10), null, null, null, null, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_product_detail]], fields=[[0, 1, 
2, 3]], filters=[[>($1, 10), null, null, null]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$0], dir0=[DESC])  
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])    
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, 2, 3, 
4, 5]], filters=[[>($0, 10){0=4}, null, null, null, null, null]])    
TranslatableTableScan(table=[[federate_jdbc, t_product_detail]], fields=[[0, 1, 
2, 3]], filters=[[>($1, 10){1=4}, null, null, null]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p INNER JOIN t_product_detail d ON 
p.product_id = d.product_id WHERE p.product_id > 10 ORDER BY p.product_id DESC 
LIMIT 2, 5">
-        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[5])  
EnumerableSort(sort0=[$0], dir0=[DESC])    EnumerableHashJoin(condition=[=($0, 
$7)], joinType=[inner])      TranslatableTableScan(table=[[federate_jdbc, 
t_product]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[>($0, 10), null, null, 
null, null, null]])      TranslatableTableScan(table=[[federate_jdbc, 
t_product_detail]], fields=[[0, 1, 2, 3]], filters=[[>($1, 10), null, null, 
null]])" />
+        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[5])  
EnumerableSort(sort0=[$0], dir0=[DESC])    EnumerableHashJoin(condition=[=($0, 
$7)], joinType=[inner])      TranslatableTableScan(table=[[federate_jdbc, 
t_product]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[>($0, 10){0=4}, null, null, 
null, null, null]])      TranslatableTableScan(table=[[federate_jdbc, 
t_product_detail]], fields=[[0, 1, 2, 3]], filters=[[>($1, 10){1=4}, null, 
null, null]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o LEFT JOIN t_merchant m 
USING(merchant_id) WHERE o.user_id = 10 ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$1], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t3, $t6)], merchant_id=[$t12], order_id=[$t0], 
user_id=[$t1], status=[$t2], remark=[$t4], creation_date=[$t5], 
country_id=[$t7], merchant_name=[$t8], business_code=[$t9], telephone=[$t10], 
creation_date0=[$t11])    EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[left])      TranslatableTableScan(table=[[federate_jdbc, t_order]],  
[...]
+        <assertion expected-result="EnumerableSort(sort0=[$1], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t3, $t6)], merchant_id=[$t12], order_id=[$t0], 
user_id=[$t1], status=[$t2], remark=[$t4], creation_date=[$t5], 
country_id=[$t7], merchant_name=[$t8], business_code=[$t9], telephone=[$t10], 
creation_date0=[$t11])    EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[left])      TranslatableTableScan(table=[[federate_jdbc, t_order]],  
[...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o RIGHT JOIN t_merchant m 
USING(merchant_id) WHERE m.country_id = 1 ORDER BY o.order_id, m.merchant_id, 
7">
-        <assertion expected-result="EnumerableSort(sort0=[$1], sort1=[$11], 
sort2=[$6], dir0=[ASC], dir1=[ASC], dir2=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t3, $t6)], 
merchant_id=[$t12], order_id=[$t0], user_id=[$t1], status=[$t2], remark=[$t4], 
creation_date=[$t5], country_id=[$t7], merchant_name=[$t8], 
business_code=[$t9], telephone=[$t10], creation_date0=[$t11], 
merchant_id0=[$t6])    EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[right])      Translatab [...]
+        <assertion expected-result="EnumerableSort(sort0=[$1], sort1=[$11], 
sort2=[$6], dir0=[ASC], dir1=[ASC], dir2=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t3, $t6)], 
merchant_id=[$t12], order_id=[$t0], user_id=[$t1], status=[$t2], remark=[$t4], 
creation_date=[$t5], country_id=[$t7], merchant_name=[$t8], 
business_code=[$t9], telephone=[$t10], creation_date0=[$t11], 
merchant_id0=[$t6])    EnumerableHashJoin(condition=[=($3, $6)], 
joinType=[right])      Translatab [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o JOIN t_merchant m 
USING(merchant_id) where o.user_id = 10 OR m.country_id = 1 ORDER BY 
o.order_id, 7">
@@ -326,19 +322,19 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p INNER JOIN t_product_detail d 
USING(product_id) WHERE p.product_id > 10 ORDER BY p.product_id DESC">
-        <assertion expected-result="EnumerableSort(sort0=[$9], dir0=[DESC])  
EnumerableCalc(expr#0..9=[{inputs}], expr#10=[COALESCE($t0, $t7)], 
product_id=[$t10], product_name=[$t1], category_id=[$t2], price=[$t3], 
status=[$t4], creation_date=[$t5], detail_id=[$t6], description=[$t8], 
creation_date0=[$t9], product_id0=[$t0])    EnumerableHashJoin(condition=[=($0, 
$7)], joinType=[inner])      TranslatableTableScan(table=[[federate_jdbc, 
t_product]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[ [...]
+        <assertion expected-result="EnumerableSort(sort0=[$9], dir0=[DESC])  
EnumerableCalc(expr#0..9=[{inputs}], expr#10=[COALESCE($t0, $t7)], 
product_id=[$t10], product_name=[$t1], category_id=[$t2], price=[$t3], 
status=[$t4], creation_date=[$t5], detail_id=[$t6], description=[$t8], 
creation_date0=[$t9], product_id0=[$t0])    EnumerableHashJoin(condition=[=($0, 
$7)], joinType=[inner])      TranslatableTableScan(table=[[federate_jdbc, 
t_product]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[ [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p INNER JOIN t_product_detail d 
USING(product_id) WHERE p.product_id > 10 ORDER BY p.product_id DESC LIMIT 2, 
5">
-        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[5])  
EnumerableSort(sort0=[$9], dir0=[DESC])    EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], product_id=[$t10], product_name=[$t1], 
category_id=[$t2], price=[$t3], status=[$t4], creation_date=[$t5], 
detail_id=[$t6], description=[$t8], creation_date0=[$t9], product_id0=[$t0])    
  EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_prod [...]
+        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[5])  
EnumerableSort(sort0=[$9], dir0=[DESC])    EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], product_id=[$t10], product_name=[$t1], 
category_id=[$t2], price=[$t3], status=[$t4], creation_date=[$t5], 
detail_id=[$t6], description=[$t8], creation_date0=[$t9], product_id0=[$t0])    
  EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_prod [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL LEFT JOIN t_merchant m 
WHERE o.user_id = 10 ORDER BY o.order_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$2], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t3, $t6)], expr#13=[COALESCE($t5, $t11)], 
merchant_id=[$t12], creation_date=[$t13], order_id=[$t0], user_id=[$t1], 
status=[$t2], remark=[$t4], country_id=[$t7], merchant_name=[$t8], 
business_code=[$t9], telephone=[$t10])    
EnumerableHashJoin(condition=[AND(=($3, $6), =($5, $11))], joinType=[left])     
 TranslatableTableScan(table=[[ [...]
+        <assertion expected-result="EnumerableSort(sort0=[$2], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..11=[{inputs}], 
expr#12=[COALESCE($t3, $t6)], expr#13=[COALESCE($t5, $t11)], 
merchant_id=[$t12], creation_date=[$t13], order_id=[$t0], user_id=[$t1], 
status=[$t2], remark=[$t4], country_id=[$t7], merchant_name=[$t8], 
business_code=[$t9], telephone=[$t10])    
EnumerableHashJoin(condition=[AND(=($3, $6), =($5, $11))], joinType=[left])     
 TranslatableTableScan(table=[[ [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL RIGHT JOIN t_merchant m 
WHERE m.country_id = 1 ORDER BY o.order_id, m.merchant_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$2], sort1=[$10], 
sort2=[$6], dir0=[ASC], dir1=[ASC], dir2=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t3, $t6)], 
expr#13=[COALESCE($t5, $t11)], merchant_id=[$t12], creation_date=[$t13], 
order_id=[$t0], user_id=[$t1], status=[$t2], remark=[$t4], country_id=[$t7], 
merchant_name=[$t8], business_code=[$t9], telephone=[$t10], merchant_id0=[$t6]) 
   EnumerableHashJoin(condition=[AND(=($3, $6), =($5, $11))], joinTyp [...]
+        <assertion expected-result="EnumerableSort(sort0=[$2], sort1=[$10], 
sort2=[$6], dir0=[ASC], dir1=[ASC], dir2=[ASC])  
EnumerableCalc(expr#0..11=[{inputs}], expr#12=[COALESCE($t3, $t6)], 
expr#13=[COALESCE($t5, $t11)], merchant_id=[$t12], creation_date=[$t13], 
order_id=[$t0], user_id=[$t1], status=[$t2], remark=[$t4], country_id=[$t7], 
merchant_name=[$t8], business_code=[$t9], telephone=[$t10], merchant_id0=[$t6]) 
   EnumerableHashJoin(condition=[AND(=($3, $6), =($5, $11))], joinTyp [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o NATURAL JOIN t_merchant m where 
o.user_id = 10 OR m.country_id = 1 ORDER BY o.order_id, 7">
@@ -346,27 +342,27 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p NATURAL JOIN t_product_detail d 
WHERE p.product_id > 10 ORDER BY p.product_id DESC">
-        <assertion expected-result="EnumerableSort(sort0=[$8], dir0=[DESC])  
EnumerableCalc(expr#0..9=[{inputs}], expr#10=[COALESCE($t0, $t7)], 
expr#11=[COALESCE($t5, $t9)], product_id=[$t10], creation_date=[$t11], 
product_name=[$t1], category_id=[$t2], price=[$t3], status=[$t4], 
detail_id=[$t6], description=[$t8], product_id0=[$t0])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($5, $9))], joinType=[inner])     
 TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, [...]
+        <assertion expected-result="EnumerableSort(sort0=[$8], dir0=[DESC])  
EnumerableCalc(expr#0..9=[{inputs}], expr#10=[COALESCE($t0, $t7)], 
expr#11=[COALESCE($t5, $t9)], product_id=[$t10], creation_date=[$t11], 
product_name=[$t1], category_id=[$t2], price=[$t3], status=[$t4], 
detail_id=[$t6], description=[$t8], product_id0=[$t0])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($5, $9))], joinType=[inner])     
 TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p NATURAL JOIN t_product_detail d 
WHERE p.product_id > 10 ORDER BY p.product_id DESC LIMIT 2, 5">
-        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[5])  
EnumerableSort(sort0=[$8], dir0=[DESC])    EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], expr#11=[COALESCE($t5, $t9)], product_id=[$t10], 
creation_date=[$t11], product_name=[$t1], category_id=[$t2], price=[$t3], 
status=[$t4], detail_id=[$t6], description=[$t8], product_id0=[$t0])      
EnumerableHashJoin(condition=[AND(=($0, $7), =($5, $9))], joinType=[inner])     
   TranslatableTableScan(tabl [...]
+        <assertion expected-result="EnumerableLimit(offset=[2], fetch=[5])  
EnumerableSort(sort0=[$8], dir0=[DESC])    EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], expr#11=[COALESCE($t5, $t9)], product_id=[$t10], 
creation_date=[$t11], product_name=[$t1], category_id=[$t2], price=[$t3], 
status=[$t4], detail_id=[$t6], description=[$t8], product_id0=[$t0])      
EnumerableHashJoin(condition=[AND(=($0, $7), =($5, $9))], joinType=[inner])     
   TranslatableTableScan(tabl [...]
     </test-case>
     
     <test-case sql="SELECT MIN(d.detail_id), MIN(p.category_id), p.product_id 
FROM t_product p INNER JOIN t_product_detail d ON p.product_id = d.product_id 
WHERE p.product_id = 10 GROUP BY p.product_id">
-        <assertion expected-result="EnumerableCalc(expr#0..2=[{inputs}], 
EXPR$0=[$t1], EXPR$1=[$t2], product_id=[$t0])  EnumerableAggregate(group=[{0}], 
EXPR$0=[MIN($1)], EXPR$1=[MIN($2)])    EnumerableCalc(expr#0..3=[{inputs}], 
product_id=[$t0], detail_id=[$t2], category_id=[$t1])      
EnumerableHashJoin(condition=[=($0, $3)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 2]], 
filters=[[=(CAST($0):INTEGER, 10), null]])        Translatable [...]
+        <assertion expected-result="EnumerableCalc(expr#0..2=[{inputs}], 
EXPR$0=[$t1], EXPR$1=[$t2], product_id=[$t0])  EnumerableAggregate(group=[{0}], 
EXPR$0=[MIN($1)], EXPR$1=[MIN($2)])    EnumerableCalc(expr#0..3=[{inputs}], 
product_id=[$t0], detail_id=[$t2], category_id=[$t1])      
EnumerableHashJoin(condition=[=($0, $3)], joinType=[inner])        
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 2]], 
filters=[[=(CAST($0):INTEGER, 10){0=4}, null]])        Transla [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p CROSS JOIN t_product_detail d ON 
p.product_id = d.product_id WHERE p.product_id = 10 ORDER BY d.product_id, 7 
LIMIT 10, 10">
-        <assertion expected-result="EnumerableLimit(offset=[10], fetch=[10])  
EnumerableSort(sort0=[$7], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, 2, 3, 
4, 5]], filters=[[=(CAST($0):INTEGER, 10), null, null, null, null, null]])      
TranslatableTableScan(table=[[federate_jdbc, t_product_detail]], fields=[[0, 1, 
2, 3]], filters=[[=(CAST($1):INTEGER, 10), n [...]
+        <assertion expected-result="EnumerableLimit(offset=[10], fetch=[10])  
EnumerableSort(sort0=[$7], sort1=[$6], dir0=[ASC], dir1=[ASC])    
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, 2, 3, 
4, 5]], filters=[[=(CAST($0):INTEGER, 10){0=4}, null, null, null, null, null]]) 
     TranslatableTableScan(table=[[federate_jdbc, t_product_detail]], 
fields=[[0, 1, 2, 3]], filters=[[=(CAST($1):INTEGER, 1 [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p LEFT JOIN t_product_detail d ON 
d.product_id = p.product_id WHERE p.category_id = 10 ORDER BY p.product_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[left])    TranslatableTableScan(table=[[federate_jdbc, t_product]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($2):INTEGER, 10), null, null, 
null, null, null]])    TranslatableTableScan(table=[[federate_jdbc, 
t_product_detail]], fields=[[0, 1, 2, 3]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$0], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[left])    TranslatableTableScan(table=[[federate_jdbc, t_product]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[=(CAST($2):INTEGER, 10){2=4}, null, 
null, null, null, null]])    TranslatableTableScan(table=[[federate_jdbc, 
t_product_detail]], fields=[[0, 1, 2, 3]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p RIGHT JOIN t_product_detail d ON 
d.product_id = p.product_id WHERE d.detail_id = 10 ORDER BY d.product_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$7], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[right])    TranslatableTableScan(table=[[federate_jdbc, t_product]], 
fields=[[0, 1, 2, 3, 4, 5]])    TranslatableTableScan(table=[[federate_jdbc, 
t_product_detail]], fields=[[0, 1, 2, 3]], filters=[[=(CAST($0):INTEGER, 10), 
null, null, null]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$7], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableHashJoin(condition=[=($0, $7)], 
joinType=[right])    TranslatableTableScan(table=[[federate_jdbc, t_product]], 
fields=[[0, 1, 2, 3, 4, 5]])    TranslatableTableScan(table=[[federate_jdbc, 
t_product_detail]], fields=[[0, 1, 2, 3]], filters=[[=(CAST($0):INTEGER, 
10){0=4}, null, null, null]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p JOIN t_product_detail d ON 
d.product_id = p.product_id WHERE d.detail_id = 10 OR p.category_id = 10 ORDER 
BY d.product_id, 7">
@@ -374,11 +370,11 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p LEFT JOIN t_product_detail d 
USING(product_id) WHERE p.category_id = 10 ORDER BY p.product_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$9], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], product_id=[$t10], product_name=[$t1], 
category_id=[$t2], price=[$t3], status=[$t4], creation_date=[$t5], 
detail_id=[$t6], description=[$t8], creation_date0=[$t9], product_id0=[$t0])    
EnumerableHashJoin(condition=[=($0, $7)], joinType=[left])      
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, 2, 
[...]
+        <assertion expected-result="EnumerableSort(sort0=[$9], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], product_id=[$t10], product_name=[$t1], 
category_id=[$t2], price=[$t3], status=[$t4], creation_date=[$t5], 
detail_id=[$t6], description=[$t8], creation_date0=[$t9], product_id0=[$t0])    
EnumerableHashJoin(condition=[=($0, $7)], joinType=[left])      
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, 2, 
[...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p RIGHT JOIN t_product_detail d 
USING(product_id) WHERE d.detail_id = 10 ORDER BY d.product_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$9], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], product_id=[$t10], product_name=[$t1], 
category_id=[$t2], price=[$t3], status=[$t4], creation_date=[$t5], 
detail_id=[$t6], description=[$t8], creation_date0=[$t9], product_id0=[$t7])    
EnumerableHashJoin(condition=[=($0, $7)], joinType=[right])      
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, 2 [...]
+        <assertion expected-result="EnumerableSort(sort0=[$9], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], product_id=[$t10], product_name=[$t1], 
category_id=[$t2], price=[$t3], status=[$t4], creation_date=[$t5], 
detail_id=[$t6], description=[$t8], creation_date0=[$t9], product_id0=[$t7])    
EnumerableHashJoin(condition=[=($0, $7)], joinType=[right])      
TranslatableTableScan(table=[[federate_jdbc, t_product]], fields=[[0, 1, 2 [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p JOIN t_product_detail d 
USING(product_id) WHERE d.detail_id = 10 OR p.category_id = 10 ORDER BY 
d.product_id, 7">
@@ -386,11 +382,11 @@
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p NATURAL LEFT JOIN 
t_product_detail d WHERE p.category_id = 10 ORDER BY p.product_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$8], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], expr#11=[COALESCE($t5, $t9)], product_id=[$t10], 
creation_date=[$t11], product_name=[$t1], category_id=[$t2], price=[$t3], 
status=[$t4], detail_id=[$t6], description=[$t8], product_id0=[$t0])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($5, $9))], joinType=[left])      
TranslatableTableScan(table=[[federate_jdbc, t_pro [...]
+        <assertion expected-result="EnumerableSort(sort0=[$8], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], expr#11=[COALESCE($t5, $t9)], product_id=[$t10], 
creation_date=[$t11], product_name=[$t1], category_id=[$t2], price=[$t3], 
status=[$t4], detail_id=[$t6], description=[$t8], product_id0=[$t0])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($5, $9))], joinType=[left])      
TranslatableTableScan(table=[[federate_jdbc, t_pro [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p NATURAL RIGHT JOIN 
t_product_detail d WHERE d.detail_id = 10 ORDER BY d.product_id, 7">
-        <assertion expected-result="EnumerableSort(sort0=[$8], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], expr#11=[COALESCE($t5, $t9)], product_id=[$t10], 
creation_date=[$t11], product_name=[$t1], category_id=[$t2], price=[$t3], 
status=[$t4], detail_id=[$t6], description=[$t8], product_id0=[$t7])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($5, $9))], joinType=[right])     
 TranslatableTableScan(table=[[federate_jdbc, t_pr [...]
+        <assertion expected-result="EnumerableSort(sort0=[$8], sort1=[$6], 
dir0=[ASC], dir1=[ASC])  EnumerableCalc(expr#0..9=[{inputs}], 
expr#10=[COALESCE($t0, $t7)], expr#11=[COALESCE($t5, $t9)], product_id=[$t10], 
creation_date=[$t11], product_name=[$t1], category_id=[$t2], price=[$t3], 
status=[$t4], detail_id=[$t6], description=[$t8], product_id0=[$t7])    
EnumerableHashJoin(condition=[AND(=($0, $7), =($5, $9))], joinType=[right])     
 TranslatableTableScan(table=[[federate_jdbc, t_pr [...]
     </test-case>
     
     <test-case sql="SELECT * FROM t_product p NATURAL JOIN t_product_detail d 
WHERE d.detail_id = 10 OR p.category_id = 10 ORDER BY d.product_id, 7">
@@ -398,11 +394,11 @@
     </test-case>
     
     <test-case sql="SELECT * FROM (SELECT o.* FROM t_order o WHERE o.user_id 
IN (10, 11, 12)) AS t, t_order_item i WHERE t.order_id = i.order_id AND 
t.order_id > 10 ORDER BY item_id">
-        <assertion expected-result="EnumerableSort(sort0=[$6], dir0=[ASC])  
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])    
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]], filters=[[AND(SEARCH($1, Sarg[10, 11, 12]), >($0, 10)), null, null, null, 
null, null]])    TranslatableTableScan(table=[[federate_jdbc, t_order_item]], 
fields=[[0, 1, 2, 3, 4, 5]], filters=[[>($1, 10), null, null, null, null, 
null]])" />
+        <assertion expected-result="EnumerableSort(sort0=[$6], dir0=[ASC])  
EnumerableHashJoin(condition=[=($0, $7)], joinType=[inner])    
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]], filters=[[AND(SEARCH($1, Sarg[10, 11, 12]), >($0, 10)){0=-5, 1=4}, null, 
null, null, null, null]])    TranslatableTableScan(table=[[federate_jdbc, 
t_order_item]], fields=[[0, 1, 2, 3, 4, 5]], filters=[[>($1, 10){1=-5}, null, 
null, null, null, null]])" />
     </test-case>
     
     <test-case sql="SELECT * FROM t_order o WHERE o.order_id IN (SELECT 
i.order_id FROM t_order_item i INNER JOIN t_product p ON i.product_id = 
p.product_id WHERE p.product_id = 10) ORDER BY order_id">
-        <assertion expected-result="EnumerableSort(sort0=[$0], dir0=[ASC])  
EnumerableCalc(expr#0..6=[{inputs}], proj#0..5=[{exprs}])    
EnumerableHashJoin(condition=[=($0, $6)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]])      EnumerableAggregate(group=[{0}])        
EnumerableCalc(expr#0..2=[{inputs}], order_id=[$t0])          
EnumerableHashJoin(condition=[=($1, $2)], joinType=[inner])            
TranslatableTableScan(table [...]
+        <assertion expected-result="EnumerableSort(sort0=[$0], dir0=[ASC])  
EnumerableCalc(expr#0..6=[{inputs}], proj#0..5=[{exprs}])    
EnumerableHashJoin(condition=[=($0, $6)], joinType=[inner])      
TranslatableTableScan(table=[[federate_jdbc, t_order]], fields=[[0, 1, 2, 3, 4, 
5]])      EnumerableAggregate(group=[{0}])        
EnumerableCalc(expr#0..2=[{inputs}], order_id=[$t0])          
EnumerableHashJoin(condition=[=($1, $2)], joinType=[inner])            
TranslatableTableScan(table [...]
     </test-case>
     
     <test-case sql="SELECT MAX(p.price) AS max_price, MIN(p.price) AS 
min_price, SUM(p.price) AS sum_price, AVG(p.price) AS avg_price, COUNT(1) AS 
count FROM t_order o INNER JOIN t_order_item i ON o.order_id = i.order_id INNER 
JOIN t_product p ON i.product_id = p.product_id GROUP BY o.order_id HAVING 
SUM(p.price) > 10 ORDER BY max_price">


Reply via email to