You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by wu...@apache.org on 2021/09/25 16:40:40 UTC

[shardingsphere] branch master updated: Use schema map into TranslatableOptimizerContext (#12712)

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

wuweijie 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 1ddc1ad  Use schema map into TranslatableOptimizerContext (#12712)
1ddc1ad is described below

commit 1ddc1ad0e85e688b8e7c2746e8bb27b1c96b15c5
Author: Liang Zhang <te...@163.com>
AuthorDate: Sun Sep 26 00:40:00 2021 +0800

    Use schema map into TranslatableOptimizerContext (#12712)
    
    * Refactor FederationExecutorFactory
    
    * Unify OptimizerContext
    
    * Refactor TranslatableExecuteDataContext
    
    * Refactor TranslatableOptimizerContext
    
    * Refactor TranslatableOptimizerContext
---
 .../sql/federate/FederationExecutorFactory.java    |  6 +-
 .../federate/filterable/table/FilterableTable.java |  2 +-
 .../TranslatableExecuteDataContext.java            | 17 +++--
 .../translatable/TranslatableExecutor.java         | 11 ++--
 .../sql/federate/FederateJDBCExecutorTest.java     | 76 +++++++---------------
 .../infra/optimize/ShardingSphereOptimizer.java    | 17 ++---
 .../filterable/FilterableOptimizerContext.java     |  4 +-
 .../FilterableOptimizerContextFactory.java         |  4 +-
 .../translatable/TranslatableOptimizerContext.java | 11 ++--
 .../TranslatableOptimizerContextFactory.java       | 31 ++++++---
 .../metadata/calcite/FederationSchema.java         | 48 ++++++++++++++
 .../metadata/calcite/FederationTable.java}         | 37 +++++------
 12 files changed, 148 insertions(+), 116 deletions(-)

diff --git a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/FederationExecutorFactory.java b/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/FederationExecutorFactory.java
index b8f1554..6b16073 100644
--- a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/FederationExecutorFactory.java
+++ b/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/FederationExecutorFactory.java
@@ -33,14 +33,14 @@ public final class FederationExecutorFactory {
     /**
      * Create new instance of federation executor factory.
      * 
-     * @param schema schema name
+     * @param schemaName schema name
      * @param optimizerContext filterable optimizer context 
      * @param props configuration properties
      * @param jdbcExecutor jdbc executor
      * @return new instance of federation executor
      */
-    public static FederationExecutor newInstance(final String schema, final FilterableOptimizerContext optimizerContext, final ConfigurationProperties props, final JDBCExecutor jdbcExecutor) {
+    public static FederationExecutor newInstance(final String schemaName, final FilterableOptimizerContext optimizerContext, final ConfigurationProperties props, final JDBCExecutor jdbcExecutor) {
         // TODO Consider about TranslatableExecutor
-        return new FilterableExecutor(schema, optimizerContext, props, jdbcExecutor);
+        return new FilterableExecutor(schemaName, optimizerContext, props, jdbcExecutor);
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/filterable/table/FilterableTable.java b/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/filterable/table/FilterableTable.java
index ab4670e..c57b630 100644
--- a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/filterable/table/FilterableTable.java
+++ b/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/filterable/table/FilterableTable.java
@@ -33,7 +33,7 @@ import java.util.Collection;
 import java.util.List;
 
 /**
- * Filterable Table.
+ * Filterable table.
  */
 public final class FilterableTable extends AbstractFederationTable implements ProjectableFilterableTable {
     
diff --git a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecuteDataContext.java b/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecuteDataContext.java
index 1e2885c..21dae39 100644
--- a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecuteDataContext.java
+++ b/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecuteDataContext.java
@@ -17,29 +17,36 @@
 
 package org.apache.shardingsphere.infra.executor.sql.federate.translatable;
 
-import lombok.RequiredArgsConstructor;
 import org.apache.calcite.DataContext;
 import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.linq4j.QueryProvider;
 import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.sql.validate.SqlValidator;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
 import org.apache.shardingsphere.infra.optimize.context.translatable.TranslatableOptimizerContext;
 
 /**
  * Translatable execute data context.
  */
-@RequiredArgsConstructor
 public final class TranslatableExecuteDataContext implements DataContext {
     
-    private final TranslatableOptimizerContext context;
+    private final SqlValidator validator;
+    
+    private final SqlToRelConverter converter;
+    
+    public TranslatableExecuteDataContext(final String schemaName, final TranslatableOptimizerContext context) {
+        validator = context.getValidators().get(schemaName);
+        converter = context.getConverters().get(schemaName);
+    }
     
     @Override
     public SchemaPlus getRootSchema() {
-        return context.getValidator().getCatalogReader().getRootSchema().plus();
+        return validator.getCatalogReader().getRootSchema().plus();
     }
     
     @Override
     public JavaTypeFactory getTypeFactory() {
-        return (JavaTypeFactory) context.getRelConverter().getCluster().getTypeFactory();
+        return (JavaTypeFactory) converter.getCluster().getTypeFactory();
     }
     
     @Override
diff --git a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecutor.java b/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecutor.java
index 7bc409b..6e246cc 100644
--- a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecutor.java
+++ b/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecutor.java
@@ -45,9 +45,12 @@ import java.util.List;
  */
 public final class TranslatableExecutor implements FederationExecutor {
     
+    private final String schemaName;
+    
     private final ShardingSphereOptimizer optimizer;
     
-    public TranslatableExecutor(final TranslatableOptimizerContext context) {
+    public TranslatableExecutor(final String schemaName, final TranslatableOptimizerContext context) {
+        this.schemaName = schemaName;
         optimizer = new ShardingSphereOptimizer(context);
     }
     
@@ -65,12 +68,12 @@ public final class TranslatableExecutor implements FederationExecutor {
     
     private Enumerable<Object[]> execute(final SQLStatement sqlStatement) {
         // TODO
-        return execute(optimizer.optimize(sqlStatement));
+        return execute(optimizer.optimize(schemaName, sqlStatement));
     }
     
     private Enumerable<Object[]> execute(final RelNode bestPlan) {
-        RelOptCluster cluster = optimizer.getContext().getRelConverter().getCluster();
-        return new FederateInterpretableConverter(cluster, cluster.traitSetOf(InterpretableConvention.INSTANCE), bestPlan).bind(new TranslatableExecuteDataContext(optimizer.getContext()));
+        RelOptCluster cluster = optimizer.getContext().getConverters().get(schemaName).getCluster();
+        return new FederateInterpretableConverter(cluster, cluster.traitSetOf(InterpretableConvention.INSTANCE), bestPlan).bind(new TranslatableExecuteDataContext(schemaName, optimizer.getContext()));
     }
     
     @Override
diff --git a/shardingsphere-infra/shardingsphere-infra-executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/federate/FederateJDBCExecutorTest.java b/shardingsphere-infra/shardingsphere-infra-executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/federate/FederateJDBCExecutorTest.java
index 908941d..9b78f4c 100644
--- a/shardingsphere-infra/shardingsphere-infra-executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/federate/FederateJDBCExecutorTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/federate/FederateJDBCExecutorTest.java
@@ -20,23 +20,21 @@ package org.apache.shardingsphere.infra.executor.sql.federate;
 import org.apache.shardingsphere.infra.config.properties.ConfigurationProperties;
 import org.apache.shardingsphere.infra.database.type.DatabaseTypeRegistry;
 import org.apache.shardingsphere.infra.database.type.dialect.H2DatabaseType;
-import org.apache.shardingsphere.infra.executor.sql.federate.translatable.TranslatableSchema;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.schema.model.ColumnMetaData;
-import org.apache.shardingsphere.infra.metadata.schema.model.IndexMetaData;
 import org.apache.shardingsphere.infra.metadata.schema.model.TableMetaData;
 import org.apache.shardingsphere.infra.optimize.ShardingSphereOptimizer;
 import org.apache.shardingsphere.infra.optimize.context.translatable.TranslatableOptimizerContextFactory;
-import org.apache.shardingsphere.infra.optimize.metadata.FederationSchemaMetaData;
 import org.apache.shardingsphere.infra.parser.ShardingSphereSQLParserEngine;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.ArrayList;
-import java.util.Collection;
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
@@ -50,60 +48,30 @@ public final class FederateJDBCExecutorTest {
             + "FROM t_order_federate , t_user_info "
             + "WHERE t_order_federate.user_id = t_user_info.user_id";
     
+    private final String schemaName = "federate_jdbc";
+    
     private ShardingSphereOptimizer optimizer;
     
     @Before
     public void init() throws Exception {
-        String schemaName = "federate_jdbc";
-        TranslatableSchema schema = createSchema(schemaName);
-        optimizer = new ShardingSphereOptimizer(TranslatableOptimizerContextFactory.create(schemaName, schema));
-    }
-    
-    private TranslatableSchema createSchema(final String schemaName) {
-        Map<String, List<String>> columnMap = createColumnMap();
-        Map<String, List<String>> tableMap = createTableMap();
-        return new TranslatableSchema(createSchemaMetaData(schemaName, tableMap.get(schemaName), columnMap));
-    }
-    
-    private Map<String, List<String>> createColumnMap() {
-        final Map<String, List<String>> result = new HashMap<>();
-        List<String> columnList = new ArrayList<>();
-        columnList.add("order_id");
-        columnList.add("user_id");
-        columnList.add("status");
-        result.put("t_order_federate", columnList);
-        List<String> columnList2 = new ArrayList<>();
-        columnList2.add("user_id");
-        columnList2.add("information");
-        result.put("t_user_info", columnList2);
-        return result;
-    }
-    
-    private Map<String, List<String>> createTableMap() {
-        Map<String, List<String>> result = new HashMap<>();
-        List<String> tableList = new ArrayList<>();
-        tableList.add("t_order_federate");
-        tableList.add("t_user_info");
-        result.put("federate_jdbc", tableList);
-        return result;
+        Map<String, TableMetaData> tableMetaDataMap = new HashMap<>(2, 1);
+        tableMetaDataMap.put("t_order_federate", createOrderTableMetaData());
+        tableMetaDataMap.put("t_user_info", createUserInfoTableMetaData());
+        ShardingSphereMetaData metaData = new ShardingSphereMetaData(schemaName, null, null, new ShardingSphereSchema(tableMetaDataMap));
+        optimizer = new ShardingSphereOptimizer(TranslatableOptimizerContextFactory.create(Collections.singletonMap(schemaName, metaData)));
     }
     
-    private FederationSchemaMetaData createSchemaMetaData(final String schemaName, final List<String> tableNames, final Map<String, List<String>> tableColumns) {
-        Map<String, TableMetaData> tableMetaDataList = new HashMap<>(tableNames.size(), 1);
-        for (String each: tableNames) {
-            tableMetaDataList.put(each, createTableMetaData(each, tableColumns.get(each)));
-        }
-        return new FederationSchemaMetaData(schemaName, tableMetaDataList);
+    private TableMetaData createOrderTableMetaData() {
+        ColumnMetaData orderIdColumn = new ColumnMetaData("order_id", Types.VARCHAR, true, false, false);
+        ColumnMetaData userIdColumn = new ColumnMetaData("user_id", Types.VARCHAR, false, false, false);
+        ColumnMetaData statusColumn = new ColumnMetaData("status", Types.VARCHAR, false, false, false);
+        return new TableMetaData("t_order_federate", Arrays.asList(orderIdColumn, userIdColumn, statusColumn), Collections.emptyList());
     }
     
-    private TableMetaData createTableMetaData(final String tableName, final Collection<String> columnNames) {
-        Collection<ColumnMetaData> columnMetaDataList = new LinkedList<>();
-        Collection<IndexMetaData> indexMetaDataList = new LinkedList<>();
-        for (String each: columnNames) {
-            columnMetaDataList.add(new ColumnMetaData(each, 1, false, false, false));
-            indexMetaDataList.add(new IndexMetaData("index"));
-        }
-        return new TableMetaData(tableName, columnMetaDataList, indexMetaDataList);
+    private TableMetaData createUserInfoTableMetaData() {
+        ColumnMetaData userIdColumn = new ColumnMetaData("user_id", Types.VARCHAR, true, false, false);
+        ColumnMetaData informationColumn = new ColumnMetaData("information", Types.VARCHAR, false, false, false);
+        return new TableMetaData("t_user_info", Arrays.asList(userIdColumn, informationColumn), Collections.emptyList());
     }
     
     @Test
@@ -111,7 +79,7 @@ public final class FederateJDBCExecutorTest {
         ShardingSphereSQLParserEngine sqlParserEngine = new ShardingSphereSQLParserEngine(
                 DatabaseTypeRegistry.getTrunkDatabaseTypeName(new H2DatabaseType()), new ConfigurationProperties(new Properties()));
         SQLStatement sqlStatement = sqlParserEngine.parse(SELECT_SQL_BY_ID_ACROSS_SINGLE_AND_SHARDING_TABLES, false);
-        String actual = optimizer.optimize(sqlStatement).explain();
+        String actual = optimizer.optimize(schemaName, sqlStatement).explain();
         String expected = "EnumerableCalc(expr#0..4=[{inputs}],expr#5=[CAST($t1):VARCHAR],expr#6=[CAST($t3):VARCHAR],expr#7=[=($t5,$t6)],proj#0..1=[{exprs}],information=[$t4],$condition=[$t7])"
                 + "  EnumerableNestedLoopJoin(condition=[true],joinType=[inner])"
                 + "    EnumerableTableScan(table=[[federate_jdbc,t_order_federate]])"
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/ShardingSphereOptimizer.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/ShardingSphereOptimizer.java
index ae16169..1673467 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/ShardingSphereOptimizer.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/ShardingSphereOptimizer.java
@@ -55,24 +55,25 @@ public final class ShardingSphereOptimizer {
     /**
      * Optimize query execution plan.
      * 
+     * @param schemaName schema name
      * @param sqlStatement SQL statement to be optimized
      * @return optimized relational node
      */
-    public RelNode optimize(final SQLStatement sqlStatement) {
+    public RelNode optimize(final String schemaName, final SQLStatement sqlStatement) {
         try {
             SqlNode sqlNode = SQLNodeConvertEngine.convert(sqlStatement);
-            SqlNode validNode = context.getValidator().validate(sqlNode);
-            RelDataType resultType = context.getValidator().getValidatedNodeType(sqlNode);
-            RelNode queryPlan = context.getRelConverter().convertQuery(validNode, false, true).rel;
-            return optimize(queryPlan, resultType);
+            SqlNode validNode = context.getValidators().get(schemaName).validate(sqlNode);
+            RelDataType resultType = context.getValidators().get(schemaName).getValidatedNodeType(sqlNode);
+            RelNode queryPlan = context.getConverters().get(schemaName).convertQuery(validNode, false, true).rel;
+            return optimize(schemaName, queryPlan, resultType);
         } catch (final UnsupportedOperationException ex) {
             throw new ShardingSphereException(ex);
         }
     }
     
-    private RelNode optimize(final RelNode queryPlan, final RelDataType resultType) {
-        RelOptPlanner planner = context.getRelConverter().getCluster().getPlanner();
-        RelNode node = planner.changeTraits(queryPlan, context.getRelConverter().getCluster().traitSet().replace(EnumerableConvention.INSTANCE));
+    private RelNode optimize(final String schemaName, final RelNode queryPlan, final RelDataType resultType) {
+        RelOptPlanner planner = context.getConverters().get(schemaName).getCluster().getPlanner();
+        RelNode node = planner.changeTraits(queryPlan, context.getConverters().get(schemaName).getCluster().traitSet().replace(EnumerableConvention.INSTANCE));
         RelRoot root = constructRoot(node, resultType);
         Program program = Programs.standard();
         return program.run(planner, root.rel, getDesireRootTraitSet(root), ImmutableList.of(), ImmutableList.of());
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/filterable/FilterableOptimizerContext.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/filterable/FilterableOptimizerContext.java
index 2652d2b..4fcf227 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/filterable/FilterableOptimizerContext.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/filterable/FilterableOptimizerContext.java
@@ -31,9 +31,9 @@ import java.util.Properties;
 @Getter
 public final class FilterableOptimizerContext {
     
-    private final DatabaseType databaseType;
-    
     private final FederationMetaData metaData;
     
+    private final DatabaseType databaseType;
+    
     private final Properties props;
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/filterable/FilterableOptimizerContextFactory.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/filterable/FilterableOptimizerContextFactory.java
index 5a96ec8..d50e7be 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/filterable/FilterableOptimizerContextFactory.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/filterable/FilterableOptimizerContextFactory.java
@@ -41,10 +41,10 @@ public final class FilterableOptimizerContextFactory {
      * @return created filterable optimizer context
      */
     public static FilterableOptimizerContext create(final Map<String, ShardingSphereMetaData> metaDataMap) {
-        DatabaseType databaseType = metaDataMap.isEmpty() ? null : metaDataMap.values().iterator().next().getResource().getDatabaseType();
         FederationMetaData metaData = new FederationMetaData(metaDataMap);
+        DatabaseType databaseType = metaDataMap.isEmpty() ? null : metaDataMap.values().iterator().next().getResource().getDatabaseType();
         Properties props = createSQLDialectProperties(databaseType);
-        return new FilterableOptimizerContext(databaseType, metaData, props);
+        return new FilterableOptimizerContext(metaData, databaseType, props);
     }
     
     private static Properties createSQLDialectProperties(final DatabaseType databaseType) {
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/translatable/TranslatableOptimizerContext.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/translatable/TranslatableOptimizerContext.java
index 3bd5c70..19850fa 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/translatable/TranslatableOptimizerContext.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/translatable/TranslatableOptimizerContext.java
@@ -19,10 +19,11 @@ package org.apache.shardingsphere.infra.optimize.context.translatable;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
-import org.apache.calcite.schema.Schema;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql2rel.SqlToRelConverter;
 
+import java.util.Map;
+
 /**
  * Translatable optimize context.
  */
@@ -30,11 +31,7 @@ import org.apache.calcite.sql2rel.SqlToRelConverter;
 @Getter
 public final class TranslatableOptimizerContext {
     
-    private final String schemaName;
-    
-    private final Schema schema;
-    
-    private final SqlValidator validator;
+    private final Map<String, SqlValidator> validators;
     
-    private final SqlToRelConverter relConverter;
+    private final Map<String, SqlToRelConverter> converters;
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/translatable/TranslatableOptimizerContextFactory.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/translatable/TranslatableOptimizerContextFactory.java
index 1c6f179..584995f 100644
--- a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/translatable/TranslatableOptimizerContextFactory.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/context/translatable/TranslatableOptimizerContextFactory.java
@@ -35,9 +35,16 @@ import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorUtil;
 import org.apache.calcite.sql2rel.SqlToRelConverter;
 import org.apache.calcite.sql2rel.StandardConvertletTable;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.optimize.metadata.FederationMetaData;
+import org.apache.shardingsphere.infra.optimize.metadata.FederationSchemaMetaData;
+import org.apache.shardingsphere.infra.optimize.metadata.calcite.FederationSchema;
 import org.apache.shardingsphere.infra.optimize.planner.QueryOptimizePlannerFactory;
 
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Properties;
 
 /**
@@ -49,17 +56,23 @@ public final class TranslatableOptimizerContextFactory {
     /**
      * Create translatable optimize context.
      *
-     * @param schemaName schema name
-     * @param schema schema
+     * @param metaDataMap meta data map
      * @return created translatable optimizer context
      */
-    public static TranslatableOptimizerContext create(final String schemaName, final Schema schema) {
-        CalciteConnectionConfig connectionConfig = new CalciteConnectionConfigImpl(createConnectionProperties());
-        RelDataTypeFactory relDataTypeFactory = new JavaTypeFactoryImpl();
-        CalciteCatalogReader catalogReader = createCatalogReader(schemaName, schema, relDataTypeFactory, connectionConfig);
-        SqlValidator validator = createValidator(catalogReader, relDataTypeFactory, connectionConfig);
-        SqlToRelConverter relConverter = createRelConverter(catalogReader, validator, relDataTypeFactory);
-        return new TranslatableOptimizerContext(schemaName, schema, validator, relConverter);
+    public static TranslatableOptimizerContext create(final Map<String, ShardingSphereMetaData> metaDataMap) {
+        Map<String, SqlValidator> validators = new HashMap<>(metaDataMap.size(), 1);
+        Map<String, SqlToRelConverter> relConverters = new HashMap<>(metaDataMap.size(), 1);
+        for (Entry<String, FederationSchemaMetaData> entry : new FederationMetaData(metaDataMap).getSchemas().entrySet()) {
+            String schemaName = entry.getKey();
+            FederationSchema schema = new FederationSchema(entry.getValue());
+            CalciteConnectionConfig connectionConfig = new CalciteConnectionConfigImpl(createConnectionProperties());
+            RelDataTypeFactory relDataTypeFactory = new JavaTypeFactoryImpl();
+            CalciteCatalogReader catalogReader = createCatalogReader(schemaName, schema, relDataTypeFactory, connectionConfig);
+            SqlValidator validator = createValidator(catalogReader, relDataTypeFactory, connectionConfig);
+            validators.put(schemaName, validator);
+            relConverters.put(schemaName, createRelConverter(catalogReader, validator, relDataTypeFactory));
+        }
+        return new TranslatableOptimizerContext(validators, relConverters);
     }
     
     private static Properties createConnectionProperties() {
diff --git a/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/metadata/calcite/FederationSchema.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/metadata/calcite/FederationSchema.java
new file mode 100644
index 0000000..18f3d9e
--- /dev/null
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/metadata/calcite/FederationSchema.java
@@ -0,0 +1,48 @@
+/*
+ * 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.infra.optimize.metadata.calcite;
+
+import lombok.Getter;
+import org.apache.calcite.schema.Table;
+import org.apache.calcite.schema.impl.AbstractSchema;
+import org.apache.commons.collections4.map.LinkedMap;
+import org.apache.shardingsphere.infra.optimize.metadata.FederationSchemaMetaData;
+import org.apache.shardingsphere.infra.optimize.metadata.FederationTableMetaData;
+
+import java.util.Map;
+
+/**
+ * Federation schema.
+ */
+@Getter
+public final class FederationSchema extends AbstractSchema {
+    
+    private final Map<String, Table> tableMap;
+    
+    public FederationSchema(final FederationSchemaMetaData metaData) {
+        tableMap = getTableMap(metaData);
+    }
+    
+    private Map<String, Table> getTableMap(final FederationSchemaMetaData metaData) {
+        Map<String, Table> result = new LinkedMap<>(metaData.getTables().size(), 1);
+        for (FederationTableMetaData each : metaData.getTables().values()) {
+            result.put(each.getName(), new FederationTable(each));
+        }
+        return result;
+    }
+}
diff --git a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecuteDataContext.java b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/metadata/calcite/FederationTable.java
similarity index 52%
copy from shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecuteDataContext.java
copy to shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/metadata/calcite/FederationTable.java
index 1e2885c..a0852ed 100644
--- a/shardingsphere-infra/shardingsphere-infra-executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/federate/translatable/TranslatableExecuteDataContext.java
+++ b/shardingsphere-infra/shardingsphere-infra-optimize/src/main/java/org/apache/shardingsphere/infra/optimize/metadata/calcite/FederationTable.java
@@ -15,40 +15,35 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.executor.sql.federate.translatable;
+package org.apache.shardingsphere.infra.optimize.metadata.calcite;
 
 import lombok.RequiredArgsConstructor;
 import org.apache.calcite.DataContext;
-import org.apache.calcite.adapter.java.JavaTypeFactory;
-import org.apache.calcite.linq4j.QueryProvider;
-import org.apache.calcite.schema.SchemaPlus;
-import org.apache.shardingsphere.infra.optimize.context.translatable.TranslatableOptimizerContext;
+import org.apache.calcite.linq4j.Enumerable;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.schema.ProjectableFilterableTable;
+import org.apache.calcite.schema.impl.AbstractTable;
+import org.apache.shardingsphere.infra.optimize.metadata.FederationTableMetaData;
+
+import java.util.List;
 
 /**
- * Translatable execute data context.
+ * Federation table.
  */
 @RequiredArgsConstructor
-public final class TranslatableExecuteDataContext implements DataContext {
-    
-    private final TranslatableOptimizerContext context;
-    
-    @Override
-    public SchemaPlus getRootSchema() {
-        return context.getValidator().getCatalogReader().getRootSchema().plus();
-    }
+public final class FederationTable extends AbstractTable implements ProjectableFilterableTable {
     
-    @Override
-    public JavaTypeFactory getTypeFactory() {
-        return (JavaTypeFactory) context.getRelConverter().getCluster().getTypeFactory();
-    }
+    private final FederationTableMetaData metaData;
     
     @Override
-    public QueryProvider getQueryProvider() {
-        return null;
+    public RelDataType getRowType(final RelDataTypeFactory typeFactory) {
+        return metaData.getRelProtoDataType().apply(typeFactory);
     }
     
     @Override
-    public Object get(final String name) {
+    public Enumerable<Object[]> scan(final DataContext root, final List<RexNode> filters, final int[] projects) {
         return null;
     }
 }