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

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


The following commit(s) were added to refs/heads/master by this push:
     new 32aa357e140 Support view expand and execute for sql federation (#21161)
32aa357e140 is described below

commit 32aa357e140c33292cb900f8a33f09aeae5660dd
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Sat Sep 24 13:21:06 2022 +0800

    Support view expand and execute for sql federation (#21161)
---
 .../engine/type/ShardingRouteEngineFactory.java    |  9 ++++
 .../decorator/model/ShardingSphereSchema.java      | 14 +++++-
 .../type/CreateViewStatementSchemaRefresher.java   |  6 ++-
 .../decider/SingleTableSQLFederationDecider.java   | 13 +++++
 .../SingleTableSQLFederationDeciderTest.java       |  4 +-
 .../advanced/AdvancedSQLFederationExecutor.java    | 14 +++---
 .../executor/FilterableTableScanExecutor.java      |  5 +-
 .../executor/TranslatableTableScanExecutor.java    |  4 +-
 .../original/OriginalSQLFederationExecutor.java    |  8 +++-
 .../expander/ShardingSphereViewExpander.java       | 53 ++++++++++++++++++++
 .../metadata/filter/FilterableDatabase.java        | 11 +++--
 .../metadata/filter/FilterableSchema.java          | 31 +++++++++---
 .../optimizer/metadata/filter/FilterableTable.java | 22 ++-------
 .../translatable/FederationTranslatableTable.java  | 20 +-------
 .../SQLFederationDataTypeUtil.java}                | 56 +++++++---------------
 .../optimizer/util/SQLFederationPlannerUtil.java   | 23 +++++++--
 .../optimizer/SQLOptimizeEngineTest.java           |  7 ++-
 .../scenario/sharding/config/sharding-rule.yaml    |  3 --
 18 files changed, 192 insertions(+), 111 deletions(-)

diff --git 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
index ed5508ad38e..d0e70463f6f 100644
--- 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
+++ 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
@@ -24,6 +24,7 @@ import 
org.apache.shardingsphere.infra.binder.statement.ddl.CloseStatementContex
 import org.apache.shardingsphere.infra.binder.type.CursorAvailable;
 import org.apache.shardingsphere.infra.binder.type.TableAvailable;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
+import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
 import org.apache.shardingsphere.infra.context.ConnectionContext;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.sharding.route.engine.condition.ShardingCondition;
@@ -48,13 +49,16 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dcl.DCLStatemen
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.AlterFunctionStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.AlterProcedureStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.AlterTablespaceStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.AlterViewStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateFunctionStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateProcedureStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTablespaceStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateViewStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DDLStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DropFunctionStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DropProcedureStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DropTablespaceStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DropViewStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DMLStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.TCLStatement;
@@ -117,6 +121,11 @@ public final class ShardingRouteEngineFactory {
                 ? ((TableAvailable) 
sqlStatementContext).getAllTables().stream().map(each -> 
each.getTableName().getIdentifier().getValue()).collect(Collectors.toSet())
                 : sqlStatementContext.getTablesContext().getTableNames();
         Collection<String> shardingRuleTableNames = 
shardingRule.getShardingRuleTableNames(tableNames);
+        String sqlFederationType = 
props.getValue(ConfigurationPropertyKey.SQL_FEDERATION_TYPE);
+        // TODO remove this logic when jdbc adapter can support executing 
create logic view
+        if (!"NONE".equals(sqlFederationType) && (sqlStatement instanceof 
CreateViewStatement || sqlStatement instanceof AlterViewStatement || 
sqlStatement instanceof DropViewStatement)) {
+            return new ShardingUnicastRoutingEngine(sqlStatementContext, 
shardingRuleTableNames, connectionContext);
+        }
         if (!tableNames.isEmpty() && shardingRuleTableNames.isEmpty()) {
             return new ShardingIgnoreRoutingEngine();
         }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/decorator/model/ShardingSphereSchema.java
 
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/decorator/model/ShardingSphereSchema.java
index ca3a83fd7ea..c22d9461641 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/decorator/model/ShardingSphereSchema.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/decorator/model/ShardingSphereSchema.java
@@ -137,10 +137,10 @@ public final class ShardingSphereSchema {
     }
     
     /**
-     * Judge contains table from table meta data or not.
+     * Judge contains table from table metadata or not.
      *
      * @param tableName table name
-     * @return contains table from table meta data or not
+     * @return contains table from table metadata or not
      */
     public boolean containsTable(final String tableName) {
         return tables.containsKey(tableName.toLowerCase());
@@ -168,6 +168,16 @@ public final class ShardingSphereSchema {
         return containsTable(tableName) && 
getTable(tableName).getIndexes().containsKey(indexName.toLowerCase());
     }
     
+    /**
+     * Judge contains view from table metadata or not.
+     *
+     * @param viewName view name
+     * @return contains view from table metadata or not
+     */
+    public boolean containsView(final String viewName) {
+        return views.containsKey(viewName.toLowerCase());
+    }
+    
     /**
      * Get all column names via table.
      *
diff --git 
a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/CreateViewStatementSchemaRefresher.java
 
b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/CreateViewStatementSchemaRefresher.java
index 18aed121d12..b87e9c2337c 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/CreateViewStatementSchemaRefresher.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/refresher/type/CreateViewStatementSchemaRefresher.java
@@ -46,7 +46,7 @@ public final class CreateViewStatementSchemaRefresher 
implements MetaDataRefresh
     public Optional<MetaDataRefreshedEvent> refresh(final 
ShardingSphereDatabase database, final Collection<String> logicDataSourceNames,
                                                     final String schemaName, 
final CreateViewStatement sqlStatement, final ConfigurationProperties props) 
throws SQLException {
         String viewName = 
sqlStatement.getView().getTableName().getIdentifier().getValue();
-        String viewDefinition = 
sqlStatement.getViewSQL().substring(sqlStatement.getViewSQL().substring(0, 
sqlStatement.getViewSQL().indexOf(" as ")).length() + 4).trim();
+        String viewDefinition = 
sqlStatement.getViewSQL().substring(getViewDefinitionStartIndex(sqlStatement)).trim();
         if (!containsInImmutableDataNodeContainedRule(viewName, database)) {
             
database.getRuleMetaData().findRules(MutableDataNodeRule.class).forEach(each -> 
each.put(logicDataSourceNames.iterator().next(), schemaName, viewName));
         }
@@ -66,6 +66,10 @@ public final class CreateViewStatementSchemaRefresher 
implements MetaDataRefresh
         return Optional.empty();
     }
     
+    private static int getViewDefinitionStartIndex(final CreateViewStatement 
sqlStatement) {
+        return sqlStatement.getViewSQL().toUpperCase().indexOf("AS") + 
"AS".length();
+    }
+    
     private boolean containsInImmutableDataNodeContainedRule(final String 
tableName, final ShardingSphereDatabase database) {
         return 
database.getRuleMetaData().findRules(DataNodeContainedRule.class).stream()
                 .filter(each -> !(each instanceof 
MutableDataNodeRule)).anyMatch(each -> each.getAllTables().contains(tableName));
diff --git 
a/shardingsphere-kernel/shardingsphere-single-table/shardingsphere-single-table-core/src/main/java/org/apache/shardingsphere/singletable/decider/SingleTableSQLFederationDecider.java
 
b/shardingsphere-kernel/shardingsphere-single-table/shardingsphere-single-table-core/src/main/java/org/apache/shardingsphere/singletable/decider/SingleTableSQLFederationDecider.java
index 9561613d385..02cc7b500ef 100644
--- 
a/shardingsphere-kernel/shardingsphere-single-table/shardingsphere-single-table-core/src/main/java/org/apache/shardingsphere/singletable/decider/SingleTableSQLFederationDecider.java
+++ 
b/shardingsphere-kernel/shardingsphere-single-table/shardingsphere-single-table-core/src/main/java/org/apache/shardingsphere/singletable/decider/SingleTableSQLFederationDecider.java
@@ -51,6 +51,10 @@ public final class SingleTableSQLFederationDecider 
implements SQLFederationDecid
         if (singleTableNames.isEmpty()) {
             return;
         }
+        if (containsView(database, singleTableNames)) {
+            deciderContext.setUseSQLFederation(true);
+            return;
+        }
         
deciderContext.setUseSQLFederation(!isAllTablesInSameDataSource(deciderContext, 
rule, singleTableNames));
         addTableDataNodes(deciderContext, rule, singleTableNames);
     }
@@ -98,6 +102,15 @@ public final class SingleTableSQLFederationDecider 
implements SQLFederationDecid
         return result;
     }
     
+    private boolean containsView(final ShardingSphereDatabase database, final 
Collection<QualifiedTable> singleTableNames) {
+        for (QualifiedTable each : singleTableNames) {
+            if 
(database.getSchema(each.getSchemaName()).containsView(each.getTableName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
     @Override
     public int getOrder() {
         return SingleTableOrder.ORDER;
diff --git 
a/shardingsphere-kernel/shardingsphere-single-table/shardingsphere-single-table-core/src/test/java/org/apache/shardingsphere/singletable/decider/SingleTableSQLFederationDeciderTest.java
 
b/shardingsphere-kernel/shardingsphere-single-table/shardingsphere-single-table-core/src/test/java/org/apache/shardingsphere/singletable/decider/SingleTableSQLFederationDeciderTest.java
index 2be0afd1624..8cfc6709c6d 100644
--- 
a/shardingsphere-kernel/shardingsphere-single-table/shardingsphere-single-table-core/src/test/java/org/apache/shardingsphere/singletable/decider/SingleTableSQLFederationDeciderTest.java
+++ 
b/shardingsphere-kernel/shardingsphere-single-table/shardingsphere-single-table-core/src/test/java/org/apache/shardingsphere/singletable/decider/SingleTableSQLFederationDeciderTest.java
@@ -26,6 +26,7 @@ import 
org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
 import org.apache.shardingsphere.infra.datanode.DataNode;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable;
+import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import org.apache.shardingsphere.singletable.rule.SingleTableRule;
 import org.junit.Test;
 
@@ -35,9 +36,9 @@ import java.util.Collections;
 import java.util.Optional;
 import java.util.Properties;
 
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertFalse;
-import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -132,6 +133,7 @@ public final class SingleTableSQLFederationDeciderTest {
     private static ShardingSphereDatabase createDatabase() {
         ShardingSphereDatabase result = mock(ShardingSphereDatabase.class);
         when(result.getName()).thenReturn(DefaultDatabase.LOGIC_NAME);
+        
when(result.getSchema(DefaultDatabase.LOGIC_NAME)).thenReturn(mock(ShardingSphereSchema.class));
         return result;
     }
 }
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-advanced/src/main/java/org/apache/shardingsphere/sqlfederation/advanced/AdvancedSQLFederationExecutor.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-advanced/src/main/java/org/apache/shardingsphere/sqlfederation/advanced/AdvancedSQLFederationExecutor.java
index 7f347fe5f73..af4d29fc5b7 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-advanced/src/main/java/org/apache/shardingsphere/sqlfederation/advanced/AdvancedSQLFederationExecutor.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-advanced/src/main/java/org/apache/shardingsphere/sqlfederation/advanced/AdvancedSQLFederationExecutor.java
@@ -20,12 +20,12 @@ package org.apache.shardingsphere.sqlfederation.advanced;
 import com.google.common.base.Preconditions;
 import org.apache.calcite.adapter.enumerable.EnumerableInterpretable;
 import org.apache.calcite.adapter.enumerable.EnumerableRel;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.config.CalciteConnectionConfig;
 import org.apache.calcite.config.CalciteConnectionConfigImpl;
 import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
 import org.apache.calcite.linq4j.Enumerator;
 import org.apache.calcite.prepare.CalciteCatalogReader;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.runtime.Bindable;
 import org.apache.calcite.schema.impl.AbstractSchema;
 import org.apache.calcite.sql.validate.SqlValidator;
@@ -70,6 +70,8 @@ import java.util.Map;
  */
 public final class AdvancedSQLFederationExecutor implements 
SQLFederationExecutor {
     
+    private static final JavaTypeFactory JAVA_TYPE_FACTORY = new 
JavaTypeFactoryImpl();
+    
     private String databaseName;
     
     private String schemaName;
@@ -124,17 +126,17 @@ public final class AdvancedSQLFederationExecutor 
implements SQLFederationExecuto
         // TODO replace FilterableTableScanExecutor with 
TranslatableTableScanExecutor
         TableScanExecutor executor = new 
FilterableTableScanExecutor(prepareEngine, jdbcExecutor, callback, 
optimizerContext, globalRuleMetaData, executorContext, eventBusContext);
         // TODO replace FilterableSchema with TranslatableSchema
-        return new FilterableSchema(schemaName, schema, executor);
+        return new FilterableSchema(schemaName, schema, JAVA_TYPE_FACTORY, 
executor);
     }
     
     @SuppressWarnings("unchecked")
     private ResultSet execute(final SelectStatementContext 
selectStatementContext, final ShardingSphereSchema schema, final AbstractSchema 
sqlFederationSchema, final Map<String, Object> parameters) {
         OptimizerParserContext parserContext = 
optimizerContext.getParserContexts().get(databaseName);
         CalciteConnectionConfig connectionConfig = new 
CalciteConnectionConfigImpl(parserContext.getDialectProps());
-        RelDataTypeFactory relDataTypeFactory = new JavaTypeFactoryImpl();
-        CalciteCatalogReader catalogReader = 
SQLFederationPlannerUtil.createCatalogReader(schemaName, sqlFederationSchema, 
relDataTypeFactory, connectionConfig);
-        SqlValidator validator = 
SQLFederationPlannerUtil.createSqlValidator(catalogReader, relDataTypeFactory, 
parserContext.getDatabaseType(), connectionConfig);
-        SqlToRelConverter converter = 
SQLFederationPlannerUtil.createSqlToRelConverter(catalogReader, validator, 
relDataTypeFactory);
+        CalciteCatalogReader catalogReader = 
SQLFederationPlannerUtil.createCatalogReader(schemaName, sqlFederationSchema, 
JAVA_TYPE_FACTORY, connectionConfig);
+        SqlValidator validator = 
SQLFederationPlannerUtil.createSqlValidator(catalogReader, JAVA_TYPE_FACTORY, 
parserContext.getDatabaseType(), connectionConfig);
+        SqlToRelConverter converter = 
SQLFederationPlannerUtil.createSqlToRelConverter(catalogReader, validator,
+                
SQLFederationPlannerUtil.createRelOptCluster(JAVA_TYPE_FACTORY), 
optimizerContext, true);
         SQLOptimizeContext optimizeContext =
                 new SQLOptimizeEngine(converter, 
SQLFederationPlannerUtil.createHepPlanner()).optimize(selectStatementContext.getSqlStatement());
         Bindable<Object> executablePlan = 
EnumerableInterpretable.toBindable(Collections.emptyMap(), null, 
(EnumerableRel) optimizeContext.getBestPlan(), EnumerableRel.Prefer.ARRAY);
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutor.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutor.java
index 40ee83e127e..8f1d374ce76 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutor.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/FilterableTableScanExecutor.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.sqlfederation.executor;
 
 import lombok.RequiredArgsConstructor;
 import lombok.SneakyThrows;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.config.CalciteConnectionConfig;
 import org.apache.calcite.config.CalciteConnectionConfigImpl;
 import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
@@ -94,6 +95,8 @@ import java.util.stream.Collectors;
 @RequiredArgsConstructor
 public final class FilterableTableScanExecutor implements TableScanExecutor {
     
+    private static final JavaTypeFactory JAVA_TYPE_FACTORY = new 
JavaTypeFactoryImpl();
+    
     private final DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine;
     
     private final JDBCExecutor jdbcExecutor;
@@ -196,7 +199,7 @@ public final class FilterableTableScanExecutor implements 
TableScanExecutor {
         CalciteConnectionConfig connectionConfig = new 
CalciteConnectionConfigImpl(optimizerContext.getParserContexts().get(databaseName).getDialectProps());
         ShardingSphereSchema schema = 
executorContext.getFederationContext().getDatabases().get(databaseName).getSchema(schemaName);
         CalciteCatalogReader catalogReader = 
SQLFederationPlannerUtil.createCatalogReader(schemaName,
-                new FilterableSchema(schemaName, schema, null), new 
JavaTypeFactoryImpl(), connectionConfig);
+                new FilterableSchema(schemaName, schema, JAVA_TYPE_FACTORY, 
null), new JavaTypeFactoryImpl(), connectionConfig);
         RelOptCluster relOptCluster = 
RelOptCluster.create(SQLFederationPlannerUtil.createVolcanoPlanner(), new 
RexBuilder(new JavaTypeFactoryImpl()));
         RelBuilder builder = 
RelFactories.LOGICAL_BUILDER.create(relOptCluster, 
catalogReader).scan(table.getName()).filter(scanContext.getFilterValues());
         if (null != scanContext.getProjects()) {
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/TranslatableTableScanExecutor.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/TranslatableTableScanExecutor.java
index 9846b54f916..67dd29c786d 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/TranslatableTableScanExecutor.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-core/src/main/java/org/apache/shardingsphere/sqlfederation/executor/TranslatableTableScanExecutor.java
@@ -99,6 +99,8 @@ import java.util.stream.Collectors;
 @RequiredArgsConstructor
 public final class TranslatableTableScanExecutor implements TableScanExecutor {
     
+    private static final JavaTypeFactory JAVA_TYPE_FACTORY = new 
JavaTypeFactoryImpl();
+    
     private final DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine;
     
     private final JDBCExecutor jdbcExecutor;
@@ -200,7 +202,7 @@ public final class TranslatableTableScanExecutor implements 
TableScanExecutor {
         CalciteConnectionConfig connectionConfig = new 
CalciteConnectionConfigImpl(optimizerContext.getParserContexts().get(databaseName).getDialectProps());
         ShardingSphereSchema schema = 
executorContext.getFederationContext().getDatabases().get(databaseName).getSchema(schemaName);
         CalciteCatalogReader catalogReader = 
SQLFederationPlannerUtil.createCatalogReader(schemaName,
-                new FilterableSchema(schemaName, schema, null), new 
JavaTypeFactoryImpl(), connectionConfig);
+                new FilterableSchema(schemaName, schema, JAVA_TYPE_FACTORY, 
null), new JavaTypeFactoryImpl(), connectionConfig);
         RelOptCluster relOptCluster = 
RelOptCluster.create(SQLFederationPlannerUtil.createVolcanoPlanner(), new 
RexBuilder(new JavaTypeFactoryImpl()));
         RelBuilder builder = 
RelFactories.LOGICAL_BUILDER.create(relOptCluster, 
catalogReader).scan(table.getName());
         if (null != scanContext.getFilterValues()) {
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-original/src/main/java/org/apache/shardingsphere/sqlfederation/original/OriginalSQLFederationExecutor.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-original/src/main/java/org/apache/shardingsphere/sqlfederation/original/OriginalSQLFederationExecutor.java
index 2eed82ee5d0..644c5d98175 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-original/src/main/java/org/apache/shardingsphere/sqlfederation/original/OriginalSQLFederationExecutor.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-executor/shardingsphere-sql-federation-executor-original/src/main/java/org/apache/shardingsphere/sqlfederation/original/OriginalSQLFederationExecutor.java
@@ -18,7 +18,9 @@
 package org.apache.shardingsphere.sqlfederation.original;
 
 import lombok.RequiredArgsConstructor;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.jdbc.CalciteConnection;
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutionUnit;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutor;
@@ -30,12 +32,12 @@ import 
org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRule
 import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
 import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtil;
 import 
org.apache.shardingsphere.sqlfederation.executor.FilterableTableScanExecutor;
+import 
org.apache.shardingsphere.sqlfederation.executor.TableScanExecutorContext;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.context.OptimizerContext;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.context.OptimizerContextFactory;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.filter.FilterableDatabase;
 import org.apache.shardingsphere.sqlfederation.spi.SQLFederationExecutor;
 import 
org.apache.shardingsphere.sqlfederation.spi.SQLFederationExecutorContext;
-import 
org.apache.shardingsphere.sqlfederation.executor.TableScanExecutorContext;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
@@ -55,6 +57,8 @@ public final class OriginalSQLFederationExecutor implements 
SQLFederationExecuto
     
     public static final String DRIVER_NAME = "org.apache.calcite.jdbc.Driver";
     
+    private static final JavaTypeFactory JAVA_TYPE_FACTORY = new 
JavaTypeFactoryImpl();
+    
     private String databaseName;
     
     private String schemaName;
@@ -113,7 +117,7 @@ public final class OriginalSQLFederationExecutor implements 
SQLFederationExecuto
                            final JDBCExecutorCallback<? extends ExecuteResult> 
callback, final SQLFederationExecutorContext federationContext) throws 
SQLException {
         TableScanExecutorContext executorContext = new 
TableScanExecutorContext(databaseName, schemaName, props, federationContext);
         FilterableTableScanExecutor executor = new 
FilterableTableScanExecutor(prepareEngine, jdbcExecutor, callback, 
optimizerContext, globalRuleMetaData, executorContext, eventBusContext);
-        FilterableDatabase database = new 
FilterableDatabase(federationContext.getDatabases().get(databaseName.toLowerCase()),
 executor);
+        FilterableDatabase database = new 
FilterableDatabase(federationContext.getDatabases().get(databaseName.toLowerCase()),
 JAVA_TYPE_FACTORY, executor);
         // TODO support database.schema.table query when switch to 
AdvancedFederationExecutor, calcite jdbc just support schema.table query now
         connection.getRootSchema().add(schemaName, 
database.getSubSchema(schemaName));
         connection.setSchema(schemaName);
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/expander/ShardingSphereViewExpander.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/expander/ShardingSphereViewExpander.java
new file mode 100644
index 00000000000..2dd3d4874f8
--- /dev/null
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/expander/ShardingSphereViewExpander.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sqlfederation.optimizer.metadata.expander;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.calcite.plan.RelOptTable.ViewExpander;
+import org.apache.calcite.rel.RelRoot;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
+import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
+import org.apache.shardingsphere.infra.parser.sql.SQLStatementParserEngine;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.context.OptimizerContext;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.converter.SQLNodeConverterEngine;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.util.List;
+
+/**
+ * ShardingSphere view expander.
+ */
+@RequiredArgsConstructor
+public final class ShardingSphereViewExpander implements ViewExpander {
+    
+    private final OptimizerContext optimizerContext;
+    
+    private final SqlToRelConverter sqlToRelConverter;
+    
+    @Override
+    public RelRoot expandView(final RelDataType rowType, final String 
queryString, final List<String> schemaPath, @Nullable final List<String> 
viewPath) {
+        SQLStatement sqlStatement = new SQLStatementParserEngine(new 
MySQLDatabaseType().getType(),
+                optimizerContext.getSqlParserRule().getSqlStatementCache(), 
optimizerContext.getSqlParserRule().getParseTreeCache(),
+                
optimizerContext.getSqlParserRule().isSqlCommentParseEnabled()).parse(queryString,
 false);
+        SqlNode sqlNode = SQLNodeConverterEngine.convert(sqlStatement);
+        return sqlToRelConverter.convertQuery(sqlNode, true, true);
+    }
+}
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableDatabase.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableDatabase.java
index 9f0a25dc810..77546eccbfa 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableDatabase.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableDatabase.java
@@ -18,11 +18,12 @@
 package org.apache.shardingsphere.sqlfederation.optimizer.metadata.filter;
 
 import lombok.Getter;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.schema.Schema;
 import org.apache.calcite.schema.impl.AbstractSchema;
-import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TableScanExecutor;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TableScanExecutor;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -38,15 +39,15 @@ public final class FilterableDatabase extends 
AbstractSchema {
     
     private final Map<String, Schema> subSchemaMap;
     
-    public FilterableDatabase(final ShardingSphereDatabase database, final 
TableScanExecutor executor) {
+    public FilterableDatabase(final ShardingSphereDatabase database, final 
JavaTypeFactory javaTypeFactory, final TableScanExecutor executor) {
         name = database.getName();
-        subSchemaMap = createSubSchemaMap(database, executor);
+        subSchemaMap = createSubSchemaMap(database, javaTypeFactory, executor);
     }
     
-    private Map<String, Schema> createSubSchemaMap(final 
ShardingSphereDatabase database, final TableScanExecutor executor) {
+    private Map<String, Schema> createSubSchemaMap(final 
ShardingSphereDatabase database, final JavaTypeFactory javaTypeFactory, final 
TableScanExecutor executor) {
         Map<String, Schema> result = new 
LinkedHashMap<>(database.getSchemas().size(), 1);
         for (Entry<String, ShardingSphereSchema> entry : 
database.getSchemas().entrySet()) {
-            result.put(entry.getKey(), new FilterableSchema(entry.getKey(), 
entry.getValue(), executor));
+            result.put(entry.getKey(), new FilterableSchema(entry.getKey(), 
entry.getValue(), javaTypeFactory, executor));
         }
         return result;
     }
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableSchema.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableSchema.java
index f90346a8d8f..b5cd1452329 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableSchema.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableSchema.java
@@ -18,13 +18,20 @@
 package org.apache.shardingsphere.sqlfederation.optimizer.metadata.filter;
 
 import lombok.Getter;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeImpl;
 import org.apache.calcite.schema.Table;
 import org.apache.calcite.schema.impl.AbstractSchema;
-import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TableScanExecutor;
-import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.statistic.FederationStatistic;
+import org.apache.calcite.schema.impl.ViewTable;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereView;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TableScanExecutor;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.statistic.FederationStatistic;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.util.SQLFederationDataTypeUtil;
 
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -38,17 +45,27 @@ public final class FilterableSchema extends AbstractSchema {
     
     private final Map<String, Table> tableMap;
     
-    public FilterableSchema(final String schemaName, final 
ShardingSphereSchema schema, final TableScanExecutor executor) {
+    public FilterableSchema(final String schemaName, final 
ShardingSphereSchema schema, final JavaTypeFactory javaTypeFactory, final 
TableScanExecutor executor) {
         name = schemaName;
-        tableMap = createTableMap(schema, executor);
+        tableMap = createTableMap(schema, javaTypeFactory, executor);
     }
     
-    private Map<String, Table> createTableMap(final ShardingSphereSchema 
schema, final TableScanExecutor executor) {
+    private Map<String, Table> createTableMap(final ShardingSphereSchema 
schema, final JavaTypeFactory javaTypeFactory, final TableScanExecutor 
executor) {
         Map<String, Table> result = new 
LinkedHashMap<>(schema.getTables().size(), 1);
         for (ShardingSphereTable each : schema.getTables().values()) {
-            // TODO implement table statistic logic after using custom 
operators
-            result.put(each.getName(), new FilterableTable(each, executor, new 
FederationStatistic()));
+            if (schema.containsView(each.getName())) {
+                result.put(each.getName(), getViewTable(schema, each, 
javaTypeFactory));
+            } else {
+                // TODO implement table statistic logic after using custom 
operators
+                result.put(each.getName(), new FilterableTable(each, executor, 
new FederationStatistic()));
+            }
         }
         return result;
     }
+    
+    private static ViewTable getViewTable(final ShardingSphereSchema schema, 
final ShardingSphereTable table, final JavaTypeFactory javaTypeFactory) {
+        RelDataType relDataType = 
SQLFederationDataTypeUtil.createRelDataType(table, javaTypeFactory);
+        ShardingSphereView view = schema.getView(table.getName());
+        return new ViewTable(javaTypeFactory.getJavaClass(relDataType), 
RelDataTypeImpl.proto(relDataType), view.getViewDefinition(), 
Collections.emptyList(), Collections.emptyList());
+    }
 }
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableTable.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableTable.java
index aeb106e6db1..c7f95c2e899 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableTable.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableTable.java
@@ -19,20 +19,18 @@ package 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.filter;
 
 import lombok.RequiredArgsConstructor;
 import org.apache.calcite.DataContext;
-import org.apache.calcite.avatica.SqlType;
 import org.apache.calcite.linq4j.Enumerable;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.rel.type.RelDataTypeFactory.Builder;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.schema.ProjectableFilterableTable;
 import org.apache.calcite.schema.Statistic;
 import org.apache.calcite.schema.impl.AbstractTable;
+import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.FilterableScanNodeExecutorContext;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TableScanExecutor;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.statistic.FederationStatistic;
-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.sqlfederation.optimizer.util.SQLFederationDataTypeUtil;
 
 import java.util.List;
 
@@ -50,7 +48,7 @@ public final class FilterableTable extends AbstractTable 
implements ProjectableF
     
     @Override
     public RelDataType getRowType(final RelDataTypeFactory typeFactory) {
-        return createRelDataType(table, typeFactory);
+        return SQLFederationDataTypeUtil.createRelDataType(table, typeFactory);
     }
     
     @Override
@@ -62,18 +60,4 @@ public final class FilterableTable extends AbstractTable 
implements ProjectableF
     public Statistic getStatistic() {
         return statistic;
     }
-    
-    private RelDataType createRelDataType(final ShardingSphereTable table, 
final RelDataTypeFactory typeFactory) {
-        Builder fieldInfoBuilder = typeFactory.builder();
-        for (ShardingSphereColumn each : table.getColumns().values()) {
-            fieldInfoBuilder.add(each.getName(), getRelDataType(each, 
typeFactory));
-        }
-        return fieldInfoBuilder.build();
-    }
-    
-    private RelDataType getRelDataType(final ShardingSphereColumn column, 
final RelDataTypeFactory typeFactory) {
-        Class<?> sqlTypeClass = SqlType.valueOf(column.getDataType()).clazz;
-        RelDataType javaType = typeFactory.createJavaType(sqlTypeClass);
-        return typeFactory.createTypeWithNullability(javaType, true);
-    }
 }
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/FederationTranslatableTable.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/FederationTranslatableTable.java
index e2c98e6890a..567c9645db8 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/FederationTranslatableTable.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/translatable/FederationTranslatableTable.java
@@ -19,7 +19,6 @@ package 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.translatable;
 
 import lombok.RequiredArgsConstructor;
 import org.apache.calcite.DataContext;
-import org.apache.calcite.avatica.SqlType;
 import org.apache.calcite.linq4j.Enumerable;
 import org.apache.calcite.linq4j.QueryProvider;
 import org.apache.calcite.linq4j.Queryable;
@@ -29,19 +28,18 @@ import org.apache.calcite.plan.RelOptTable.ToRelContext;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.rel.type.RelDataTypeFactory.Builder;
 import org.apache.calcite.schema.QueryableTable;
 import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.schema.Schemas;
 import org.apache.calcite.schema.Statistic;
 import org.apache.calcite.schema.TranslatableTable;
 import org.apache.calcite.schema.impl.AbstractTable;
-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;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TranslatableScanNodeExecutorContext;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.statistic.FederationStatistic;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.util.SQLFederationDataTypeUtil;
 
 import java.lang.reflect.Type;
 
@@ -59,7 +57,7 @@ public final class FederationTranslatableTable extends 
AbstractTable implements
     
     @Override
     public RelDataType getRowType(final RelDataTypeFactory typeFactory) {
-        return createRelDataType(table, typeFactory);
+        return SQLFederationDataTypeUtil.createRelDataType(table, typeFactory);
     }
     
     /**
@@ -123,18 +121,4 @@ public final class FederationTranslatableTable extends 
AbstractTable implements
         }
         return result;
     }
-    
-    private RelDataType createRelDataType(final ShardingSphereTable table, 
final RelDataTypeFactory typeFactory) {
-        Builder fieldInfoBuilder = typeFactory.builder();
-        for (ShardingSphereColumn each : table.getColumns().values()) {
-            fieldInfoBuilder.add(each.getName(), getRelDataType(each, 
typeFactory));
-        }
-        return fieldInfoBuilder.build();
-    }
-    
-    private RelDataType getRelDataType(final ShardingSphereColumn column, 
final RelDataTypeFactory typeFactory) {
-        Class<?> sqlTypeClass = SqlType.valueOf(column.getDataType()).clazz;
-        RelDataType javaType = typeFactory.createJavaType(sqlTypeClass);
-        return typeFactory.createTypeWithNullability(javaType, true);
-    }
 }
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableTable.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/util/SQLFederationDataTypeUtil.java
similarity index 50%
copy from 
shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableTable.java
copy to 
shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/util/SQLFederationDataTypeUtil.java
index aeb106e6db1..ca55a923cb7 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/metadata/filter/FilterableTable.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/util/SQLFederationDataTypeUtil.java
@@ -15,55 +15,31 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sqlfederation.optimizer.metadata.filter;
+package org.apache.shardingsphere.sqlfederation.optimizer.util;
 
-import lombok.RequiredArgsConstructor;
-import org.apache.calcite.DataContext;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
 import org.apache.calcite.avatica.SqlType;
-import org.apache.calcite.linq4j.Enumerable;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rel.type.RelDataTypeFactory.Builder;
-import org.apache.calcite.rex.RexNode;
-import org.apache.calcite.schema.ProjectableFilterableTable;
-import org.apache.calcite.schema.Statistic;
-import org.apache.calcite.schema.impl.AbstractTable;
-import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.FilterableScanNodeExecutorContext;
-import 
org.apache.shardingsphere.sqlfederation.optimizer.executor.TableScanExecutor;
-import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.statistic.FederationStatistic;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereColumn;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
 
-import java.util.List;
-
 /**
- * Filterable table.
+ * SQL federation data type util.
  */
-@RequiredArgsConstructor
-public final class FilterableTable extends AbstractTable implements 
ProjectableFilterableTable {
-    
-    private final ShardingSphereTable table;
-    
-    private final TableScanExecutor executor;
-    
-    private final FederationStatistic statistic;
-    
-    @Override
-    public RelDataType getRowType(final RelDataTypeFactory typeFactory) {
-        return createRelDataType(table, typeFactory);
-    }
-    
-    @Override
-    public Enumerable<Object[]> scan(final DataContext root, final 
List<RexNode> filters, final int[] projects) {
-        return executor.execute(table, new 
FilterableScanNodeExecutorContext(root, filters, projects));
-    }
-    
-    @Override
-    public Statistic getStatistic() {
-        return statistic;
-    }
-    
-    private RelDataType createRelDataType(final ShardingSphereTable table, 
final RelDataTypeFactory typeFactory) {
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class SQLFederationDataTypeUtil {
+    
+    /**
+     * Create rel data type.
+     * 
+     * @param table ShardingSphere table
+     * @param typeFactory type factory
+     * @return rel data type
+     */
+    public static RelDataType createRelDataType(final ShardingSphereTable 
table, final RelDataTypeFactory typeFactory) {
         Builder fieldInfoBuilder = typeFactory.builder();
         for (ShardingSphereColumn each : table.getColumns().values()) {
             fieldInfoBuilder.add(each.getName(), getRelDataType(each, 
typeFactory));
@@ -71,7 +47,7 @@ public final class FilterableTable extends AbstractTable 
implements ProjectableF
         return fieldInfoBuilder.build();
     }
     
-    private RelDataType getRelDataType(final ShardingSphereColumn column, 
final RelDataTypeFactory typeFactory) {
+    private static RelDataType getRelDataType(final ShardingSphereColumn 
column, final RelDataTypeFactory typeFactory) {
         Class<?> sqlTypeClass = SqlType.valueOf(column.getDataType()).clazz;
         RelDataType javaType = typeFactory.createJavaType(sqlTypeClass);
         return typeFactory.createTypeWithNullability(javaType, true);
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/util/SQLFederationPlannerUtil.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/util/SQLFederationPlannerUtil.java
index c2f11ff2129..3bdafe4706f 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/util/SQLFederationPlannerUtil.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/main/java/org/apache/shardingsphere/sqlfederation/optimizer/util/SQLFederationPlannerUtil.java
@@ -49,6 +49,8 @@ import org.apache.calcite.sql2rel.SqlToRelConverter;
 import org.apache.calcite.sql2rel.SqlToRelConverter.Config;
 import org.apache.calcite.sql2rel.StandardConvertletTable;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.context.OptimizerContext;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.expander.ShardingSphereViewExpander;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.translatable.TranslatableFilterRule;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.translatable.TranslatableProjectFilterRule;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.translatable.TranslatableProjectRule;
@@ -214,13 +216,26 @@ public final class SQLFederationPlannerUtil {
      *
      * @param catalogReader catalog reader
      * @param validator validator
-     * @param relDataTypeFactory rel data type factory
+     * @param cluster cluster
+     * @param optimizerContext optimizer context
+     * @param needsViewExpand whether sql needs view expand or not
      * @return sql to rel converter
      */
-    public static SqlToRelConverter createSqlToRelConverter(final 
CalciteCatalogReader catalogReader, final SqlValidator validator, final 
RelDataTypeFactory relDataTypeFactory) {
-        ViewExpander expander = (rowType, queryString, schemaPath, viewPath) 
-> null;
+    public static SqlToRelConverter createSqlToRelConverter(final 
CalciteCatalogReader catalogReader, final SqlValidator validator,
+                                                            final 
RelOptCluster cluster, final OptimizerContext optimizerContext, final boolean 
needsViewExpand) {
+        ViewExpander expander = needsViewExpand ? new 
ShardingSphereViewExpander(optimizerContext,
+                createSqlToRelConverter(catalogReader, validator, cluster, 
optimizerContext, false)) : (rowType, queryString, schemaPath, viewPath) -> 
null;
         Config converterConfig = 
SqlToRelConverter.config().withTrimUnusedFields(true);
-        RelOptCluster cluster = 
RelOptCluster.create(SQLFederationPlannerUtil.createVolcanoPlanner(), new 
RexBuilder(relDataTypeFactory));
         return new SqlToRelConverter(expander, validator, catalogReader, 
cluster, StandardConvertletTable.INSTANCE, converterConfig);
     }
+    
+    /**
+     * Create rel opt cluster.
+     * 
+     * @param relDataTypeFactory rel data type factory
+     * @return rel opt cluster
+     */
+    public static RelOptCluster createRelOptCluster(final RelDataTypeFactory 
relDataTypeFactory) {
+        return 
RelOptCluster.create(SQLFederationPlannerUtil.createVolcanoPlanner(), new 
RexBuilder(relDataTypeFactory));
+    }
 }
diff --git 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/test/java/org/apache/shardingsphere/sqlfederation/optimizer/SQLOptimizeEngineTest.java
 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/test/java/org/apache/shardingsphere/sqlfederation/optimizer/SQLOptimizeEngineTest.java
index 8b34c557ee9..571a34decc9 100644
--- 
a/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/test/java/org/apache/shardingsphere/sqlfederation/optimizer/SQLOptimizeEngineTest.java
+++ 
b/shardingsphere-kernel/shardingsphere-sql-federation/shardingsphere-sql-federation-optimizer/src/test/java/org/apache/shardingsphere/sqlfederation/optimizer/SQLOptimizeEngineTest.java
@@ -20,8 +20,10 @@ package org.apache.shardingsphere.sqlfederation.optimizer;
 import org.apache.calcite.config.CalciteConnectionConfig;
 import org.apache.calcite.config.CalciteConnectionConfigImpl;
 import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
+import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.prepare.CalciteCatalogReader;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql2rel.SqlToRelConverter;
 import org.apache.shardingsphere.infra.database.type.DatabaseTypeEngine;
@@ -33,6 +35,7 @@ import 
org.apache.shardingsphere.infra.parser.ShardingSphereSQLParserEngine;
 import org.apache.shardingsphere.parser.rule.SQLParserRule;
 import 
org.apache.shardingsphere.parser.rule.builder.DefaultSQLParserRuleConfigurationBuilder;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import 
org.apache.shardingsphere.sqlfederation.optimizer.context.OptimizerContext;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.metadata.translatable.TranslatableSchema;
 import 
org.apache.shardingsphere.sqlfederation.optimizer.util.SQLFederationPlannerUtil;
 import org.hamcrest.MatcherAssert;
@@ -47,6 +50,7 @@ import java.util.Map;
 import java.util.Properties;
 
 import static org.hamcrest.CoreMatchers.is;
+import static org.mockito.Mockito.mock;
 
 public final class SQLOptimizeEngineTest {
     
@@ -122,7 +126,8 @@ public final class SQLOptimizeEngineTest {
         TranslatableSchema federationSchema = new 
TranslatableSchema(SCHEMA_NAME, schema, null);
         CalciteCatalogReader catalogReader = 
SQLFederationPlannerUtil.createCatalogReader(SCHEMA_NAME, federationSchema, 
relDataTypeFactory, connectionConfig);
         SqlValidator validator = 
SQLFederationPlannerUtil.createSqlValidator(catalogReader, relDataTypeFactory, 
new H2DatabaseType(), connectionConfig);
-        return SQLFederationPlannerUtil.createSqlToRelConverter(catalogReader, 
validator, relDataTypeFactory);
+        RelOptCluster cluster = 
RelOptCluster.create(SQLFederationPlannerUtil.createVolcanoPlanner(), new 
RexBuilder(relDataTypeFactory));
+        return SQLFederationPlannerUtil.createSqlToRelConverter(catalogReader, 
validator, cluster, mock(OptimizerContext.class), false);
     }
     
     @Test
diff --git 
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/sharding/config/sharding-rule.yaml
 
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/sharding/config/sharding-rule.yaml
index 1e03665ab50..e953b8e3cd6 100644
--- 
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/sharding/config/sharding-rule.yaml
+++ 
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/sharding/config/sharding-rule.yaml
@@ -98,6 +98,3 @@ rules:
   keyGenerators:
     rewrite_keygen_fixture:
       type: REWRITE.FIXTURE
-
-props:
-  sql-federation-type: ADVANCED

Reply via email to