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 674961b1398 19937 add trabslate table (#20186)
674961b1398 is described below
commit 674961b1398f9986ac7ba51aec5797f984ff07f5
Author: boyjoy1127 <[email protected]>
AuthorDate: Sat Aug 20 21:15:46 2022 +0800
19937 add trabslate table (#20186)
* feat: add translatable federation.
* fix: fix conflicts during merge.
* fix: fix conflicts during merge.
* style: fix code style.
* style: fix code style.
* style: fix code style.
* style: fix code style.
* style: fix code style.
* style: remove useless method.
---
.../parser/DatabaseDiscoveryDistSQLTest.java | 8 +-
.../executor/FederationExecutorFactory.java | 6 +-
.../advanced/AdvancedFederationExecutor.java | 7 +-
...or.java => TranslatableFederationExecutor.java} | 41 ++---
.../advanced/resultset/FederationResultSet.java | 4 +-
.../resultset/FederationResultSetMetaData.java | 4 +-
.../table/TranslatableTableScanExecutor.java} | 56 ++++--
.../CommonExecuteDataContext.java} | 4 +-
.../row/CommonRowEnumerator.java} | 6 +-
.../row/EmptyRowEnumerator.java | 2 +-
.../table/CommonTableScanExecutorContext.java} | 6 +-
.../original/OriginalFederationExecutor.java | 8 +-
.../table/FilterableTableScanExecutor.java | 22 ++-
...java => FilterableScanNodeExecutorContext.java} | 4 +-
...orContext.java => ScanNodeExecutorContext.java} | 20 +-
.../optimizer/executor/TableScanExecutor.java | 2 +-
...va => TranslatableScanNodeExecutorContext.java} | 7 +-
.../optimizer/metadata/filter/FilterableTable.java | 4 +-
.../FederationTranslatableTable.java} | 83 ++++++++-
.../translatable/TranslatableDatabase.java | 53 ++++++
.../translatable/TranslatableFilterRule.java | 66 +++++++
.../TranslatableProjectFilterRule.java | 87 +++++++++
.../translatable/TranslatableProjectRule.java | 76 ++++++++
.../metadata/translatable/TranslatableSchema.java | 54 ++++++
.../translatable/TranslatableTableScan.java | 205 +++++++++++++++++++++
.../planner/QueryOptimizePlannerFactory.java | 1 +
26 files changed, 725 insertions(+), 111 deletions(-)
diff --git
a/shardingsphere-features/shardingsphere-db-discovery/shardingsphere-db-discovery-distsql/shardingsphere-db-discovery-distsql-parser/src/test/java/org/apache/shardingsphere/dbdiscovery/distsql/parser/DatabaseDiscoveryDistSQLTest.java
b/shardingsphere-features/shardingsphere-db-discovery/shardingsphere-db-discovery-distsql/shardingsphere-db-discovery-distsql-parser/src/test/java/org/apache/shardingsphere/dbdiscovery/distsql/parser/DatabaseDiscoveryDistSQLTest.java
index 75057e6aad3..5b8709625cd 100644
---
a/shardingsphere-features/shardingsphere-db-discovery/shardingsphere-db-discovery-distsql/shardingsphere-db-discovery-distsql-parser/src/test/java/org/apache/shardingsphere/dbdiscovery/distsql/parser/DatabaseDiscoveryDistSQLTest.java
+++
b/shardingsphere-features/shardingsphere-db-discovery/shardingsphere-db-discovery-distsql/shardingsphere-db-discovery-distsql-parser/src/test/java/org/apache/shardingsphere/dbdiscovery/distsql/parser/DatabaseDiscoveryDistSQLTest.java
@@ -17,10 +17,6 @@
package org.apache.shardingsphere.dbdiscovery.distsql.parser;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
import lombok.SneakyThrows;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
import
org.apache.shardingsphere.dbdiscovery.distsql.parser.facade.DatabaseDiscoveryDistSQLStatementParserFacade;
@@ -41,6 +37,10 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.Properties;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
public class DatabaseDiscoveryDistSQLTest {
@Test
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/FederationExecutorFactory.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/FederationExecutorFactory.java
index d4bcb510a4e..3f9019f2b8e 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/FederationExecutorFactory.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/FederationExecutorFactory.java
@@ -34,20 +34,20 @@ public final class FederationExecutorFactory {
/**
* Create new instance of federation executor factory.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param globalRuleMetaData global rule meta data
* @param optimizerContext filterable optimizer context
* @param props configuration properties
* @param jdbcExecutor jdbc executor
- * @param eventBusContext event bus context
+ * @param eventBusContext event bus context
* @return created instance
*/
public static FederationExecutor newInstance(final String databaseName,
final String schemaName, final OptimizerContext optimizerContext,
final
ShardingSphereRuleMetaData globalRuleMetaData, final ConfigurationProperties
props, final JDBCExecutor jdbcExecutor,
final EventBusContext
eventBusContext) {
- // TODO Consider about AdvancedFederationExecutor
+ // TODO Consider about AdvancedFederationExecutor and
TranslatableFederationExecutor
return new OriginalFederationExecutor(databaseName, schemaName,
optimizerContext, globalRuleMetaData, props, jdbcExecutor, eventBusContext);
}
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedFederationExecutor.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedFederationExecutor.java
index 72b3cdcf206..39c972749da 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedFederationExecutor.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedFederationExecutor.java
@@ -42,8 +42,9 @@ import
org.apache.shardingsphere.infra.executor.sql.prepare.driver.DriverExecuti
import org.apache.shardingsphere.infra.federation.executor.FederationContext;
import org.apache.shardingsphere.infra.federation.executor.FederationExecutor;
import
org.apache.shardingsphere.infra.federation.executor.advanced.resultset.FederationResultSet;
+import
org.apache.shardingsphere.infra.federation.executor.common.CommonExecuteDataContext;
+import
org.apache.shardingsphere.infra.federation.executor.common.table.CommonTableScanExecutorContext;
import
org.apache.shardingsphere.infra.federation.executor.original.table.FilterableTableScanExecutor;
-import
org.apache.shardingsphere.infra.federation.executor.original.table.FilterableTableScanExecutorContext;
import
org.apache.shardingsphere.infra.federation.optimizer.ShardingSphereOptimizer;
import
org.apache.shardingsphere.infra.federation.optimizer.context.OptimizerContext;
import
org.apache.shardingsphere.infra.federation.optimizer.context.planner.OptimizerPlannerContextFactory;
@@ -119,7 +120,7 @@ public final class AdvancedFederationExecutor implements
FederationExecutor {
private FilterableSchema createFilterableSchema(final
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine,
final ShardingSphereSchema schema,
final
JDBCExecutorCallback<? extends ExecuteResult> callback, final FederationContext
federationContext) {
- FilterableTableScanExecutorContext executorContext = new
FilterableTableScanExecutorContext(databaseName, schemaName, props,
federationContext);
+ CommonTableScanExecutorContext executorContext = new
CommonTableScanExecutorContext(databaseName, schemaName, props,
federationContext);
FilterableTableScanExecutor executor = new
FilterableTableScanExecutor(prepareEngine, jdbcExecutor, callback,
optimizerContext, globalRuleMetaData, executorContext, eventBusContext);
return new FilterableSchema(schemaName, schema, executor);
}
@@ -134,7 +135,7 @@ public final class AdvancedFederationExecutor implements
FederationExecutor {
SqlToRelConverter converter =
OptimizerPlannerContextFactory.createConverter(catalogReader, validator,
relDataTypeFactory);
RelNode bestPlan = new ShardingSphereOptimizer(converter,
QueryOptimizePlannerFactory.createHepPlanner()).optimize(sqlStatement);
Bindable<Object[]> executablePlan =
EnumerableInterpretable.toBindable(Collections.emptyMap(), null,
(EnumerableRel) bestPlan, EnumerableRel.Prefer.ARRAY);
- return executablePlan.bind(new AdvancedExecuteDataContext(validator,
converter, parameters));
+ return executablePlan.bind(new CommonExecuteDataContext(validator,
converter, parameters));
}
@Override
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedFederationExecutor.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/TranslatableFederationExecutor.java
similarity index 76%
copy from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedFederationExecutor.java
copy to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/TranslatableFederationExecutor.java
index 72b3cdcf206..b7e8fd8881f 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedFederationExecutor.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/TranslatableFederationExecutor.java
@@ -42,12 +42,13 @@ import
org.apache.shardingsphere.infra.executor.sql.prepare.driver.DriverExecuti
import org.apache.shardingsphere.infra.federation.executor.FederationContext;
import org.apache.shardingsphere.infra.federation.executor.FederationExecutor;
import
org.apache.shardingsphere.infra.federation.executor.advanced.resultset.FederationResultSet;
-import
org.apache.shardingsphere.infra.federation.executor.original.table.FilterableTableScanExecutor;
-import
org.apache.shardingsphere.infra.federation.executor.original.table.FilterableTableScanExecutorContext;
+import
org.apache.shardingsphere.infra.federation.executor.advanced.table.TranslatableTableScanExecutor;
+import
org.apache.shardingsphere.infra.federation.executor.common.CommonExecuteDataContext;
+import
org.apache.shardingsphere.infra.federation.executor.common.table.CommonTableScanExecutorContext;
import
org.apache.shardingsphere.infra.federation.optimizer.ShardingSphereOptimizer;
import
org.apache.shardingsphere.infra.federation.optimizer.context.OptimizerContext;
import
org.apache.shardingsphere.infra.federation.optimizer.context.planner.OptimizerPlannerContextFactory;
-import
org.apache.shardingsphere.infra.federation.optimizer.metadata.filter.FilterableSchema;
+import
org.apache.shardingsphere.infra.federation.optimizer.metadata.translatable.TranslatableSchema;
import
org.apache.shardingsphere.infra.federation.optimizer.planner.QueryOptimizePlannerFactory;
import
org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
@@ -65,7 +66,7 @@ import java.util.Map;
/**
* Advanced federation executor.
*/
-public final class AdvancedFederationExecutor implements FederationExecutor {
+public final class TranslatableFederationExecutor implements
FederationExecutor {
private final String databaseName;
@@ -83,9 +84,9 @@ public final class AdvancedFederationExecutor implements
FederationExecutor {
private ResultSet resultSet;
- public AdvancedFederationExecutor(final String databaseName, final String
schemaName, final OptimizerContext optimizerContext,
- final ShardingSphereRuleMetaData
globalRuleMetaData, final ConfigurationProperties props, final JDBCExecutor
jdbcExecutor,
- final EventBusContext eventBusContext) {
+ public TranslatableFederationExecutor(final String databaseName, final
String schemaName, final OptimizerContext optimizerContext,
+ final ShardingSphereRuleMetaData
globalRuleMetaData, final ConfigurationProperties props, final JDBCExecutor
jdbcExecutor,
+ final EventBusContext
eventBusContext) {
this.databaseName = databaseName;
this.schemaName = schemaName;
this.optimizerContext = optimizerContext;
@@ -101,10 +102,10 @@ public final class AdvancedFederationExecutor implements
FederationExecutor {
SQLStatementContext<?> sqlStatementContext =
federationContext.getLogicSQL().getSqlStatementContext();
Preconditions.checkArgument(sqlStatementContext instanceof
SelectStatementContext, "SQL statement context must be select statement
context.");
ShardingSphereSchema schema =
federationContext.getDatabases().get(databaseName.toLowerCase()).getSchema(schemaName);
- FilterableSchema filterableSchema =
createFilterableSchema(prepareEngine, schema, callback, federationContext);
+ TranslatableSchema translatableSchema =
createTranslatableSchema(prepareEngine, schema, callback, federationContext);
Map<String, Object> parameters =
createParameters(federationContext.getLogicSQL().getParameters());
- Enumerator<Object[]> enumerator =
execute(sqlStatementContext.getSqlStatement(), filterableSchema,
parameters).enumerator();
- resultSet = new FederationResultSet(enumerator, schema,
filterableSchema, sqlStatementContext);
+ Enumerator<Object[]> enumerator =
execute(sqlStatementContext.getSqlStatement(), translatableSchema,
parameters).enumerator();
+ resultSet = new FederationResultSet(enumerator, schema,
translatableSchema, sqlStatementContext);
return resultSet;
}
@@ -117,24 +118,24 @@ public final class AdvancedFederationExecutor implements
FederationExecutor {
return result;
}
- private FilterableSchema createFilterableSchema(final
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine,
final ShardingSphereSchema schema,
- final
JDBCExecutorCallback<? extends ExecuteResult> callback, final FederationContext
federationContext) {
- FilterableTableScanExecutorContext executorContext = new
FilterableTableScanExecutorContext(databaseName, schemaName, props,
federationContext);
- FilterableTableScanExecutor executor = new
FilterableTableScanExecutor(prepareEngine, jdbcExecutor, callback,
optimizerContext, globalRuleMetaData, executorContext, eventBusContext);
- return new FilterableSchema(schemaName, schema, executor);
+ private TranslatableSchema createTranslatableSchema(final
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine,
final ShardingSphereSchema schema,
+ final
JDBCExecutorCallback<? extends ExecuteResult> callback, final FederationContext
federationContext) {
+ CommonTableScanExecutorContext executorContext = new
CommonTableScanExecutorContext(databaseName, schemaName, props,
federationContext);
+ TranslatableTableScanExecutor executor = new
TranslatableTableScanExecutor(prepareEngine, jdbcExecutor, callback,
optimizerContext, globalRuleMetaData, executorContext, eventBusContext);
+ return new TranslatableSchema(schemaName, schema, executor);
}
@SuppressWarnings("unchecked")
- private Enumerable<Object[]> execute(final SQLStatement sqlStatement,
final FilterableSchema filterableSchema, final Map<String, Object> parameters) {
+ private Enumerable<Object[]> execute(final SQLStatement sqlStatement,
final TranslatableSchema translatableSchema, final Map<String, Object>
parameters) {
// TODO remove OptimizerPlannerContextFactory call and use setup
executor to handle this logic
CalciteConnectionConfig connectionConfig = new
CalciteConnectionConfigImpl(OptimizerPlannerContextFactory.createConnectionProperties());
RelDataTypeFactory relDataTypeFactory = new JavaTypeFactoryImpl();
- CalciteCatalogReader catalogReader =
OptimizerPlannerContextFactory.createCatalogReader(schemaName,
filterableSchema, relDataTypeFactory, connectionConfig);
+ CalciteCatalogReader catalogReader =
OptimizerPlannerContextFactory.createCatalogReader(schemaName,
translatableSchema, relDataTypeFactory, connectionConfig);
SqlValidator validator =
OptimizerPlannerContextFactory.createValidator(catalogReader,
relDataTypeFactory, connectionConfig);
SqlToRelConverter converter =
OptimizerPlannerContextFactory.createConverter(catalogReader, validator,
relDataTypeFactory);
RelNode bestPlan = new ShardingSphereOptimizer(converter,
QueryOptimizePlannerFactory.createHepPlanner()).optimize(sqlStatement);
Bindable<Object[]> executablePlan =
EnumerableInterpretable.toBindable(Collections.emptyMap(), null,
(EnumerableRel) bestPlan, EnumerableRel.Prefer.ARRAY);
- return executablePlan.bind(new AdvancedExecuteDataContext(validator,
converter, parameters));
+ return executablePlan.bind(new CommonExecuteDataContext(validator,
converter, parameters));
}
@Override
@@ -144,8 +145,6 @@ public final class AdvancedFederationExecutor implements
FederationExecutor {
@Override
public void close() throws SQLException {
- if (null != resultSet) {
- resultSet.close();
- }
+ resultSet.close();
}
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/resultset/FederationResultSet.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/resultset/FederationResultSet.java
index be2b6d418ae..ebc2472f161 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/resultset/FederationResultSet.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/resultset/FederationResultSet.java
@@ -19,11 +19,11 @@ package
org.apache.shardingsphere.infra.federation.executor.advanced.resultset;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.linq4j.Enumerator;
+import org.apache.calcite.schema.impl.AbstractSchema;
import
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
import
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.type.util.ResultSetUtil;
-import
org.apache.shardingsphere.infra.federation.optimizer.metadata.filter.FilterableSchema;
import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
import java.io.InputStream;
@@ -71,7 +71,7 @@ public final class FederationResultSet extends
AbstractUnsupportedOperationResul
private boolean closed;
- public FederationResultSet(final Enumerator<Object[]> enumerator, final
ShardingSphereSchema schema, final FilterableSchema filterableSchema, final
SQLStatementContext<?> sqlStatementContext) {
+ public FederationResultSet(final Enumerator<Object[]> enumerator, final
ShardingSphereSchema schema, final AbstractSchema filterableSchema, final
SQLStatementContext<?> sqlStatementContext) {
this.enumerator = enumerator;
columnLabelAndIndexMap =
createColumnLabelAndIndexMap(sqlStatementContext);
resultSetMetaData = new FederationResultSetMetaData(schema,
filterableSchema, new JavaTypeFactoryImpl(), (SelectStatementContext)
sqlStatementContext);
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/resultset/FederationResultSetMetaData.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/resultset/FederationResultSetMetaData.java
index 377e0e153eb..f4ea1cf6eff 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/resultset/FederationResultSetMetaData.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/resultset/FederationResultSetMetaData.java
@@ -21,11 +21,11 @@ import lombok.RequiredArgsConstructor;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.schema.Table;
+import org.apache.calcite.schema.impl.AbstractSchema;
import
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
import
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
import
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.database.DefaultDatabase;
-import
org.apache.shardingsphere.infra.federation.optimizer.metadata.filter.FilterableSchema;
import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
import java.sql.ResultSetMetaData;
@@ -42,7 +42,7 @@ public final class FederationResultSetMetaData extends
WrapperAdapter implements
private final ShardingSphereSchema schema;
- private final FilterableSchema filterableSchema;
+ private final AbstractSchema filterableSchema;
private final RelDataTypeFactory relDataTypeFactory;
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutor.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/table/TranslatableTableScanExecutor.java
similarity index 84%
copy from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutor.java
copy to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/table/TranslatableTableScanExecutor.java
index 53e11b0a356..67ef1e6271e 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutor.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/table/TranslatableTableScanExecutor.java
@@ -15,10 +15,12 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.federation.executor.original.table;
+package org.apache.shardingsphere.infra.federation.executor.advanced.table;
+import com.google.common.base.Strings;
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;
@@ -30,9 +32,13 @@ import org.apache.calcite.prepare.CalciteCatalogReader;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.RelFactories;
import org.apache.calcite.rel.rel2sql.RelToSqlConverter;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlDialect;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.util.SqlString;
import org.apache.calcite.tools.RelBuilder;
import org.apache.shardingsphere.infra.binder.LogicSQL;
@@ -56,13 +62,15 @@ import
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.dr
import
org.apache.shardingsphere.infra.executor.sql.prepare.driver.DriverExecutionPrepareEngine;
import
org.apache.shardingsphere.infra.executor.sql.process.ExecuteProcessEngine;
import org.apache.shardingsphere.infra.federation.executor.FederationContext;
+import
org.apache.shardingsphere.infra.federation.executor.common.row.EmptyRowEnumerator;
+import
org.apache.shardingsphere.infra.federation.executor.common.row.CommonRowEnumerator;
+import
org.apache.shardingsphere.infra.federation.executor.common.table.CommonTableScanExecutorContext;
import
org.apache.shardingsphere.infra.federation.executor.original.SQLDialectFactory;
-import
org.apache.shardingsphere.infra.federation.executor.original.row.EmptyRowEnumerator;
-import
org.apache.shardingsphere.infra.federation.executor.original.row.FilterableRowEnumerator;
import
org.apache.shardingsphere.infra.federation.optimizer.context.OptimizerContext;
import
org.apache.shardingsphere.infra.federation.optimizer.context.planner.OptimizerPlannerContextFactory;
import
org.apache.shardingsphere.infra.federation.optimizer.executor.TableScanExecutor;
-import
org.apache.shardingsphere.infra.federation.optimizer.executor.TableScanExecutorContext;
+import
org.apache.shardingsphere.infra.federation.optimizer.executor.ScanNodeExecutorContext;
+import
org.apache.shardingsphere.infra.federation.optimizer.executor.TranslatableScanNodeExecutorContext;
import
org.apache.shardingsphere.infra.federation.optimizer.metadata.filter.FilterableSchema;
import
org.apache.shardingsphere.infra.federation.optimizer.planner.QueryOptimizePlannerFactory;
import org.apache.shardingsphere.infra.merge.MergeEngine;
@@ -89,10 +97,10 @@ import java.util.Map;
import java.util.stream.Collectors;
/**
- * Filterable table scan executor.
+ * Translatable table scan executor.
*/
@RequiredArgsConstructor
-public final class FilterableTableScanExecutor implements TableScanExecutor {
+public final class TranslatableTableScanExecutor implements TableScanExecutor {
private final DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection>
prepareEngine;
@@ -104,20 +112,20 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
private final ShardingSphereRuleMetaData globalRuleMetaData;
- private final FilterableTableScanExecutorContext executorContext;
+ private final CommonTableScanExecutorContext executorContext;
private final EventBusContext eventBusContext;
@Override
- public Enumerable<Object[]> execute(final ShardingSphereTable table, final
TableScanExecutorContext scanContext) {
+ public Enumerable<Object[]> execute(final ShardingSphereTable table, final
ScanNodeExecutorContext scanContext) {
String databaseName = executorContext.getDatabaseName();
String schemaName = executorContext.getSchemaName();
DatabaseType databaseType =
DatabaseTypeEngine.getTrunkDatabaseType(optimizerContext.getParserContexts().get(databaseName).getDatabaseType().getType());
- SqlString sqlString = createSQLString(table, scanContext,
SQLDialectFactory.getSQLDialect(databaseType));
+ SqlString sqlString = createSQLString(table,
(TranslatableScanNodeExecutorContext) scanContext,
SQLDialectFactory.getSQLDialect(databaseType));
+ // TODO replace sql parse with sql convert
FederationContext federationContext =
executorContext.getFederationContext();
LogicSQL logicSQL = createLogicSQL(federationContext.getDatabases(),
sqlString, databaseType);
ShardingSphereDatabase database =
federationContext.getDatabases().get(databaseName.toLowerCase());
- // TODO need to get session context
ExecutionContext context = new
KernelProcessor().generateExecutionContext(logicSQL, database,
globalRuleMetaData, executorContext.getProps(), new ConnectionContext());
if (federationContext.isPreview() ||
databaseType.getSystemSchemas().contains(schemaName)) {
federationContext.getExecutionUnits().addAll(context.getExecutionUnits());
@@ -133,7 +141,6 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
ExecuteProcessEngine.initialize(context.getLogicSQL(),
executionGroupContext, eventBusContext);
List<QueryResult> queryResults = execute(executionGroupContext,
databaseType);
ExecuteProcessEngine.finish(executionGroupContext.getExecutionID(),
eventBusContext);
- // TODO need to get session context
MergeEngine mergeEngine = new MergeEngine(database,
executorContext.getProps(), new ConnectionContext());
MergedResult mergedResult = mergeEngine.merge(queryResults,
logicSQL.getSqlStatementContext());
Collection<Statement> statements =
getStatements(executionGroupContext.getInputGroups());
@@ -167,7 +174,7 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
return result;
}
- private SqlString createSQLString(final ShardingSphereTable table, final
TableScanExecutorContext scanContext, final SqlDialect sqlDialect) {
+ private SqlString createSQLString(final ShardingSphereTable table, final
TranslatableScanNodeExecutorContext scanContext, final SqlDialect sqlDialect) {
return new
RelToSqlConverter(sqlDialect).visitRoot(createRelNode(table,
scanContext)).asStatement().toSqlString(sqlDialect);
}
@@ -190,7 +197,7 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
}
}
- private RelNode createRelNode(final ShardingSphereTable table, final
TableScanExecutorContext scanContext) {
+ private RelNode createRelNode(final ShardingSphereTable table, final
TranslatableScanNodeExecutorContext scanContext) {
String databaseName = executorContext.getDatabaseName();
String schemaName = executorContext.getSchemaName();
CalciteConnectionConfig connectionConfig = new
CalciteConnectionConfigImpl(OptimizerPlannerContextFactory.createConnectionProperties());
@@ -198,13 +205,32 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
CalciteCatalogReader catalogReader =
OptimizerPlannerContextFactory.createCatalogReader(schemaName,
new FilterableSchema(schemaName, schema, null), new
JavaTypeFactoryImpl(), connectionConfig);
RelOptCluster relOptCluster =
RelOptCluster.create(QueryOptimizePlannerFactory.createVolcanoPlanner(), new
RexBuilder(new JavaTypeFactoryImpl()));
- RelBuilder builder =
RelFactories.LOGICAL_BUILDER.create(relOptCluster,
catalogReader).scan(table.getName()).filter(scanContext.getFilters());
+ RelBuilder builder =
RelFactories.LOGICAL_BUILDER.create(relOptCluster,
catalogReader).scan(table.getName());
+ if (null != scanContext.getFilterValues()) {
+ builder.filter(createFilters(scanContext.getFilterValues(),
builder, table.getColumnNames()));
+ }
if (null != scanContext.getProjects()) {
builder.project(createProjections(scanContext.getProjects(),
builder, table.getColumnNames()));
}
return builder.build();
}
+ private Collection<RexNode> createFilters(final String[] filterValues,
final RelBuilder builder, final List<String> columnNames) {
+ Collection<RexNode> result = new LinkedList<>();
+ JavaTypeFactory typeFactory = new
JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+ RexBuilder rexBuilder = new RexBuilder(typeFactory);
+ for (int i = 0; i < filterValues.length; i++) {
+ if (!Strings.isNullOrEmpty(filterValues[i])) {
+ RelDataType nonNullableInt =
typeFactory.createSqlType(SqlTypeName.INTEGER);
+ RexNode n2 =
rexBuilder.makeLiteral(Integer.valueOf(filterValues[i]), nonNullableInt, false);
+ RexNode n1 = rexBuilder.makeInputRef(nonNullableInt, i);
+ RexNode tmp = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
n1, n2);
+ result.add(tmp);
+ }
+ }
+ return result;
+ }
+
private Collection<RexNode> createProjections(final int[] projects, final
RelBuilder relBuilder, final List<String> columnNames) {
Collection<RexNode> result = new LinkedList<>();
for (int each : projects) {
@@ -218,7 +244,7 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
@Override
public Enumerator<Object[]> enumerator() {
- return new FilterableRowEnumerator(mergedResult, metaData,
statements);
+ return new CommonRowEnumerator(mergedResult, metaData,
statements);
}
};
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedExecuteDataContext.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/CommonExecuteDataContext.java
similarity index 92%
rename from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedExecuteDataContext.java
rename to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/CommonExecuteDataContext.java
index 731a12171b5..d0203b0954d 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/advanced/AdvancedExecuteDataContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/CommonExecuteDataContext.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.federation.executor.advanced;
+package org.apache.shardingsphere.infra.federation.executor.common;
import lombok.RequiredArgsConstructor;
import org.apache.calcite.DataContext;
@@ -31,7 +31,7 @@ import java.util.Map;
* Advanced execute data context.
*/
@RequiredArgsConstructor
-public final class AdvancedExecuteDataContext implements DataContext {
+public final class CommonExecuteDataContext implements DataContext {
private final SqlValidator validator;
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/row/FilterableRowEnumerator.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/row/CommonRowEnumerator.java
similarity index 93%
rename from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/row/FilterableRowEnumerator.java
rename to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/row/CommonRowEnumerator.java
index 63406172358..b0cf4b47f09 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/row/FilterableRowEnumerator.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/row/CommonRowEnumerator.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.federation.executor.original.row;
+package org.apache.shardingsphere.infra.federation.executor.common.row;
import lombok.RequiredArgsConstructor;
import org.apache.calcite.linq4j.Enumerator;
@@ -28,10 +28,10 @@ import java.sql.Statement;
import java.util.Collection;
/**
- * Filterable row enumerator.
+ * Common row enumerator.
*/
@RequiredArgsConstructor
-public final class FilterableRowEnumerator implements Enumerator<Object[]> {
+public final class CommonRowEnumerator implements Enumerator<Object[]> {
private final MergedResult queryResult;
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/row/EmptyRowEnumerator.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/row/EmptyRowEnumerator.java
similarity index 94%
rename from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/row/EmptyRowEnumerator.java
rename to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/row/EmptyRowEnumerator.java
index 1f73f3f86e2..b144720b2c5 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/row/EmptyRowEnumerator.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/row/EmptyRowEnumerator.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.federation.executor.original.row;
+package org.apache.shardingsphere.infra.federation.executor.common.row;
import org.apache.calcite.linq4j.Enumerator;
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutorContext.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/table/CommonTableScanExecutorContext.java
similarity index 87%
rename from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutorContext.java
rename to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/table/CommonTableScanExecutorContext.java
index e7f70bf5058..58a52553a81 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutorContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/common/table/CommonTableScanExecutorContext.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.federation.executor.original.table;
+package org.apache.shardingsphere.infra.federation.executor.common.table;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -23,11 +23,11 @@ import
org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.federation.executor.FederationContext;
/**
- * Filterable table scan executor context.
+ * Translatable table scan executor context.
*/
@RequiredArgsConstructor
@Getter
-public final class FilterableTableScanExecutorContext {
+public final class CommonTableScanExecutorContext {
private final String databaseName;
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/OriginalFederationExecutor.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/OriginalFederationExecutor.java
index 19e8aa0f759..0e3cc070d9d 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/OriginalFederationExecutor.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/OriginalFederationExecutor.java
@@ -20,7 +20,6 @@ package
org.apache.shardingsphere.infra.federation.executor.original;
import lombok.RequiredArgsConstructor;
import org.apache.calcite.jdbc.CalciteConnection;
import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
-import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
import
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutionUnit;
import
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutor;
import
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutorCallback;
@@ -28,11 +27,12 @@ import
org.apache.shardingsphere.infra.executor.sql.execute.result.ExecuteResult
import
org.apache.shardingsphere.infra.executor.sql.prepare.driver.DriverExecutionPrepareEngine;
import org.apache.shardingsphere.infra.federation.executor.FederationContext;
import org.apache.shardingsphere.infra.federation.executor.FederationExecutor;
-import
org.apache.shardingsphere.infra.federation.optimizer.metadata.filter.FilterableDatabase;
+import
org.apache.shardingsphere.infra.federation.executor.common.table.CommonTableScanExecutorContext;
import
org.apache.shardingsphere.infra.federation.executor.original.table.FilterableTableScanExecutor;
-import
org.apache.shardingsphere.infra.federation.executor.original.table.FilterableTableScanExecutorContext;
import
org.apache.shardingsphere.infra.federation.optimizer.context.OptimizerContext;
+import
org.apache.shardingsphere.infra.federation.optimizer.metadata.filter.FilterableDatabase;
import
org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
+import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtil;
import java.sql.Connection;
@@ -96,7 +96,7 @@ public final class OriginalFederationExecutor implements
FederationExecutor {
private void addSchema(final CalciteConnection connection, final
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine,
final JDBCExecutorCallback<? extends ExecuteResult>
callback, final FederationContext federationContext) throws SQLException {
- FilterableTableScanExecutorContext executorContext = new
FilterableTableScanExecutorContext(databaseName, schemaName, props,
federationContext);
+ CommonTableScanExecutorContext executorContext = new
CommonTableScanExecutorContext(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);
// TODO support database.schema.table query when switch to
CustomizedFilterableExecutor, calcite jdbc just support schema.table query now
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutor.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutor.java
index 53e11b0a356..56218a91a06 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutor.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-executor/src/main/java/org/apache/shardingsphere/infra/federation/executor/original/table/FilterableTableScanExecutor.java
@@ -56,13 +56,15 @@ import
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.dr
import
org.apache.shardingsphere.infra.executor.sql.prepare.driver.DriverExecutionPrepareEngine;
import
org.apache.shardingsphere.infra.executor.sql.process.ExecuteProcessEngine;
import org.apache.shardingsphere.infra.federation.executor.FederationContext;
+import
org.apache.shardingsphere.infra.federation.executor.common.table.CommonTableScanExecutorContext;
import
org.apache.shardingsphere.infra.federation.executor.original.SQLDialectFactory;
-import
org.apache.shardingsphere.infra.federation.executor.original.row.EmptyRowEnumerator;
-import
org.apache.shardingsphere.infra.federation.executor.original.row.FilterableRowEnumerator;
+import
org.apache.shardingsphere.infra.federation.executor.common.row.EmptyRowEnumerator;
+import
org.apache.shardingsphere.infra.federation.executor.common.row.CommonRowEnumerator;
import
org.apache.shardingsphere.infra.federation.optimizer.context.OptimizerContext;
import
org.apache.shardingsphere.infra.federation.optimizer.context.planner.OptimizerPlannerContextFactory;
+import
org.apache.shardingsphere.infra.federation.optimizer.executor.FilterableScanNodeExecutorContext;
+import
org.apache.shardingsphere.infra.federation.optimizer.executor.ScanNodeExecutorContext;
import
org.apache.shardingsphere.infra.federation.optimizer.executor.TableScanExecutor;
-import
org.apache.shardingsphere.infra.federation.optimizer.executor.TableScanExecutorContext;
import
org.apache.shardingsphere.infra.federation.optimizer.metadata.filter.FilterableSchema;
import
org.apache.shardingsphere.infra.federation.optimizer.planner.QueryOptimizePlannerFactory;
import org.apache.shardingsphere.infra.merge.MergeEngine;
@@ -104,16 +106,16 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
private final ShardingSphereRuleMetaData globalRuleMetaData;
- private final FilterableTableScanExecutorContext executorContext;
+ private final CommonTableScanExecutorContext executorContext;
private final EventBusContext eventBusContext;
@Override
- public Enumerable<Object[]> execute(final ShardingSphereTable table, final
TableScanExecutorContext scanContext) {
+ public Enumerable<Object[]> execute(final ShardingSphereTable table, final
ScanNodeExecutorContext scanContext) {
String databaseName = executorContext.getDatabaseName();
String schemaName = executorContext.getSchemaName();
DatabaseType databaseType =
DatabaseTypeEngine.getTrunkDatabaseType(optimizerContext.getParserContexts().get(databaseName).getDatabaseType().getType());
- SqlString sqlString = createSQLString(table, scanContext,
SQLDialectFactory.getSQLDialect(databaseType));
+ SqlString sqlString = createSQLString(table,
(FilterableScanNodeExecutorContext) scanContext,
SQLDialectFactory.getSQLDialect(databaseType));
FederationContext federationContext =
executorContext.getFederationContext();
LogicSQL logicSQL = createLogicSQL(federationContext.getDatabases(),
sqlString, databaseType);
ShardingSphereDatabase database =
federationContext.getDatabases().get(databaseName.toLowerCase());
@@ -167,7 +169,7 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
return result;
}
- private SqlString createSQLString(final ShardingSphereTable table, final
TableScanExecutorContext scanContext, final SqlDialect sqlDialect) {
+ private SqlString createSQLString(final ShardingSphereTable table, final
FilterableScanNodeExecutorContext scanContext, final SqlDialect sqlDialect) {
return new
RelToSqlConverter(sqlDialect).visitRoot(createRelNode(table,
scanContext)).asStatement().toSqlString(sqlDialect);
}
@@ -190,7 +192,7 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
}
}
- private RelNode createRelNode(final ShardingSphereTable table, final
TableScanExecutorContext scanContext) {
+ private RelNode createRelNode(final ShardingSphereTable table, final
FilterableScanNodeExecutorContext scanContext) {
String databaseName = executorContext.getDatabaseName();
String schemaName = executorContext.getSchemaName();
CalciteConnectionConfig connectionConfig = new
CalciteConnectionConfigImpl(OptimizerPlannerContextFactory.createConnectionProperties());
@@ -198,7 +200,7 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
CalciteCatalogReader catalogReader =
OptimizerPlannerContextFactory.createCatalogReader(schemaName,
new FilterableSchema(schemaName, schema, null), new
JavaTypeFactoryImpl(), connectionConfig);
RelOptCluster relOptCluster =
RelOptCluster.create(QueryOptimizePlannerFactory.createVolcanoPlanner(), new
RexBuilder(new JavaTypeFactoryImpl()));
- RelBuilder builder =
RelFactories.LOGICAL_BUILDER.create(relOptCluster,
catalogReader).scan(table.getName()).filter(scanContext.getFilters());
+ RelBuilder builder =
RelFactories.LOGICAL_BUILDER.create(relOptCluster,
catalogReader).scan(table.getName()).filter(scanContext.getFilterValues());
if (null != scanContext.getProjects()) {
builder.project(createProjections(scanContext.getProjects(),
builder, table.getColumnNames()));
}
@@ -218,7 +220,7 @@ public final class FilterableTableScanExecutor implements
TableScanExecutor {
@Override
public Enumerator<Object[]> enumerator() {
- return new FilterableRowEnumerator(mergedResult, metaData,
statements);
+ return new CommonRowEnumerator(mergedResult, metaData,
statements);
}
};
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/FilterableScanNodeExecutorContext.java
similarity index 89%
copy from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
copy to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/FilterableScanNodeExecutorContext.java
index bfb5b423544..0e5f52abeee 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/FilterableScanNodeExecutorContext.java
@@ -29,11 +29,11 @@ import java.util.List;
*/
@RequiredArgsConstructor
@Getter
-public final class TableScanExecutorContext {
+public final class FilterableScanNodeExecutorContext implements
ScanNodeExecutorContext {
private final DataContext root;
- private final List<RexNode> filters;
+ private final List<RexNode> filterValues;
private final int[] projects;
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/ScanNodeExecutorContext.java
similarity index 68%
copy from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
copy to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/ScanNodeExecutorContext.java
index bfb5b423544..0b86ebc8e83 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/ScanNodeExecutorContext.java
@@ -17,23 +17,5 @@
package org.apache.shardingsphere.infra.federation.optimizer.executor;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.calcite.DataContext;
-import org.apache.calcite.rex.RexNode;
-
-import java.util.List;
-
-/**
- * Table scan executor context.
- */
-@RequiredArgsConstructor
-@Getter
-public final class TableScanExecutorContext {
-
- private final DataContext root;
-
- private final List<RexNode> filters;
-
- private final int[] projects;
+public interface ScanNodeExecutorContext {
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutor.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutor.java
index 3a6cbf68a4a..040d620803a 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutor.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutor.java
@@ -32,5 +32,5 @@ public interface TableScanExecutor {
* @param scanContext filterable table scan context
* @return query results
*/
- Enumerable<Object[]> execute(ShardingSphereTable table,
TableScanExecutorContext scanContext);
+ Enumerable<Object[]> execute(ShardingSphereTable table,
ScanNodeExecutorContext scanContext);
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TranslatableScanNodeExecutorContext.java
similarity index 88%
rename from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
rename to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TranslatableScanNodeExecutorContext.java
index bfb5b423544..7b4679b1452 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TableScanExecutorContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/executor/TranslatableScanNodeExecutorContext.java
@@ -20,20 +20,17 @@ package
org.apache.shardingsphere.infra.federation.optimizer.executor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.calcite.DataContext;
-import org.apache.calcite.rex.RexNode;
-
-import java.util.List;
/**
* Table scan executor context.
*/
@RequiredArgsConstructor
@Getter
-public final class TableScanExecutorContext {
+public final class TranslatableScanNodeExecutorContext implements
ScanNodeExecutorContext {
private final DataContext root;
- private final List<RexNode> filters;
+ private final String[] filterValues;
private final int[] projects;
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/filter/FilterableTable.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/filter/FilterableTable.java
index 84b4db2df91..49ba3ae9927 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/filter/FilterableTable.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/filter/FilterableTable.java
@@ -28,7 +28,7 @@ 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.federation.optimizer.executor.TableScanExecutorContext;
+import
org.apache.shardingsphere.infra.federation.optimizer.executor.FilterableScanNodeExecutorContext;
import
org.apache.shardingsphere.infra.federation.optimizer.executor.TableScanExecutor;
import
org.apache.shardingsphere.infra.federation.optimizer.metadata.statistic.FederationStatistic;
import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereColumn;
@@ -55,7 +55,7 @@ public final class FilterableTable extends AbstractTable
implements ProjectableF
@Override
public Enumerable<Object[]> scan(final DataContext root, final
List<RexNode> filters, final int[] projects) {
- return executor.execute(table, new TableScanExecutorContext(root,
filters, projects));
+ return executor.execute(table, new
FilterableScanNodeExecutorContext(root, filters, projects));
}
@Override
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/filter/FilterableTable.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/FederationTranslatableTable.java
similarity index 50%
copy from
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/filter/FilterableTable.java
copy to
shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/FederationTranslatableTable.java
index 84b4db2df91..ad1e419c014 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/filter/FilterableTable.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/FederationTranslatableTable.java
@@ -15,32 +15,39 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.federation.optimizer.metadata.filter;
+package
org.apache.shardingsphere.infra.federation.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;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.plan.RelOptTable;
+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.rex.RexNode;
-import org.apache.calcite.schema.ProjectableFilterableTable;
+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.federation.optimizer.executor.TableScanExecutorContext;
+import
org.apache.shardingsphere.infra.federation.optimizer.executor.TranslatableScanNodeExecutorContext;
import
org.apache.shardingsphere.infra.federation.optimizer.executor.TableScanExecutor;
import
org.apache.shardingsphere.infra.federation.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;
+import java.lang.reflect.Type;
/**
- * Filterable table.
+ * Federation Translatable table.
*/
@RequiredArgsConstructor
-public final class FilterableTable extends AbstractTable implements
ProjectableFilterableTable {
+public final class FederationTranslatableTable extends AbstractTable
implements QueryableTable, TranslatableTable {
private final ShardingSphereTable table;
@@ -53,9 +60,59 @@ public final class FilterableTable extends AbstractTable
implements ProjectableF
return createRelDataType(table, 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[]> projectAndFilter(final DataContext root, final
String[] filterValues, final int[] projects) {
+ return executor.execute(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[]> project(final DataContext root, final int[]
projects) {
+ return executor.execute(table, new
TranslatableScanNodeExecutorContext(root, null, projects));
+ }
+
+ @Override
+ public Expression getExpression(final SchemaPlus schema, final String
tableName,
+ final Class clazz) {
+ return Schemas.tableExpression(schema, getElementType(), tableName,
clazz);
+ }
+
+ @Override
+ public Type getElementType() {
+ return Object[].class;
+ }
+
@Override
- public Enumerable<Object[]> scan(final DataContext root, final
List<RexNode> filters, final int[] projects) {
- return executor.execute(table, new TableScanExecutorContext(root,
filters, projects));
+ public <T> Queryable<T> asQueryable(final QueryProvider queryProvider,
+ final SchemaPlus schema, final String
tableName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public RelNode toRel(
+ final RelOptTable.ToRelContext context,
+ final RelOptTable relOptTable) {
+ // Request all fields.
+ final int fieldCount = relOptTable.getRowType().getFieldCount();
+ final int[] fields = identityList(fieldCount);
+ return new TranslatableTableScan(context.getCluster(), relOptTable,
this, fields);
+ }
+
+ @Override
+ public String toString() {
+ return "FederationTranslatableTable";
}
@Override
@@ -63,6 +120,14 @@ public final class FilterableTable extends AbstractTable
implements ProjectableF
return statistic;
}
+ private int[] identityList(final int n) {
+ int[] integers = new int[n];
+ for (int i = 0; i < n; i++) {
+ integers[i] = i;
+ }
+ return integers;
+ }
+
private RelDataType createRelDataType(final ShardingSphereTable table,
final RelDataTypeFactory typeFactory) {
Builder fieldInfoBuilder = typeFactory.builder();
for (ShardingSphereColumn each : table.getColumns().values()) {
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableDatabase.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableDatabase.java
new file mode 100644
index 00000000000..4a1a389c0f1
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableDatabase.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.infra.federation.optimizer.metadata.translatable;
+
+import lombok.Getter;
+import org.apache.calcite.schema.Schema;
+import org.apache.calcite.schema.impl.AbstractSchema;
+import
org.apache.shardingsphere.infra.federation.optimizer.executor.TableScanExecutor;
+import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Translatable database.
+ */
+@Getter
+public final class TranslatableDatabase extends AbstractSchema {
+
+ private final String name;
+
+ private final Map<String, Schema> subSchemaMap;
+
+ public TranslatableDatabase(final ShardingSphereDatabase database, final
TableScanExecutor executor) {
+ name = database.getName();
+ subSchemaMap = createSubSchemaMap(database, executor);
+ }
+
+ private Map<String, Schema> createSubSchemaMap(final
ShardingSphereDatabase database, 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 TranslatableSchema(entry.getKey(),
entry.getValue(), executor));
+ }
+ return result;
+ }
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableFilterRule.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableFilterRule.java
new file mode 100644
index 00000000000..f8a21f90c04
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableFilterRule.java
@@ -0,0 +1,66 @@
+/*
+ * 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.federation.optimizer.metadata.translatable;
+
+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.RexNode;
+import org.apache.calcite.tools.RelBuilderFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Planner rule for pushing filters into table scan.
+ */
+public class TranslatableFilterRule extends RelOptRule {
+
+ public static final TranslatableFilterRule INSTANCE =
+ new TranslatableFilterRule(RelFactories.LOGICAL_BUILDER);
+
+ /**
+ * Creates a TranslatableFilterRule.
+ *
+ * @param relBuilderFactory Builder for relational expressions
+ */
+ public TranslatableFilterRule(final RelBuilderFactory relBuilderFactory) {
+ super(
+ operand(LogicalFilter.class,
+ operand(TranslatableTableScan.class, none())),
+ relBuilderFactory,
+ "TranslatableFilterRule");
+ }
+
+ @Override
+ public void onMatch(final RelOptRuleCall call) {
+ final LogicalFilter filter = call.rel(0);
+ final TranslatableTableScan scan = call.rel(1);
+ RexNode filterNode = filter.getCondition();
+ List filters = new ArrayList();
+ filters.add(filterNode);
+ call.transformTo(
+ new TranslatableTableScan(
+ scan.getCluster(),
+ scan.getTable(),
+ scan.getTranslatableTable(),
+ filters,
+ scan.getFields()));
+ }
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableProjectFilterRule.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableProjectFilterRule.java
new file mode 100644
index 00000000000..5ee40302e98
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableProjectFilterRule.java
@@ -0,0 +1,87 @@
+/*
+ * 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.federation.optimizer.metadata.translatable;
+
+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.rel.logical.LogicalProject;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.tools.RelBuilderFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Planner rule for pushing projections and filters into table scan.
+ */
+public class TranslatableProjectFilterRule extends RelOptRule {
+
+ public static final TranslatableProjectFilterRule INSTANCE =
+ new TranslatableProjectFilterRule(RelFactories.LOGICAL_BUILDER);
+
+ /**
+ * Creates a TranslatableProjectFilterRule.
+ *
+ * @param relBuilderFactory Builder for relational expressions
+ */
+ public TranslatableProjectFilterRule(final RelBuilderFactory
relBuilderFactory) {
+ super(
+ operand(LogicalProject.class,
+ operand(LogicalFilter.class,
+ operand(TranslatableTableScan.class, none()))),
+ relBuilderFactory,
+ "TranslatableProjectFilterRule");
+ }
+
+ @Override
+ public void onMatch(final RelOptRuleCall call) {
+ LogicalProject project = call.rel(0);
+ LogicalFilter filter = call.rel(1);
+ TranslatableTableScan scan = call.rel(2);
+ RexNode filterNode = filter.getCondition();
+ List filters = new ArrayList();
+ filters.add(filterNode);
+ int[] fields = getProjectFields(project.getProjects());
+ if (fields == null) {
+ return;
+ }
+ call.transformTo(
+ new TranslatableTableScan(
+ scan.getCluster(),
+ scan.getTable(),
+ scan.getTranslatableTable(),
+ filters,
+ fields));
+ }
+
+ private int[] getProjectFields(final List<RexNode> exps) {
+ final int[] result = new int[exps.size()];
+ for (int i = 0; i < exps.size(); i++) {
+ final RexNode exp = exps.get(i);
+ if (exp instanceof RexInputRef) {
+ result[i] = ((RexInputRef) exp).getIndex();
+ } else {
+ return null;
+ }
+ }
+ return result;
+ }
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableProjectRule.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableProjectRule.java
new file mode 100644
index 00000000000..a35028fe838
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableProjectRule.java
@@ -0,0 +1,76 @@
+/*
+ * 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.federation.optimizer.metadata.translatable;
+
+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.LogicalProject;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.tools.RelBuilderFactory;
+
+import java.util.List;
+
+/**
+ * Planner rule for pushing projections into table scan.
+ */
+public class TranslatableProjectRule extends RelOptRule {
+
+ public static final TranslatableProjectRule INSTANCE = new
TranslatableProjectRule(RelFactories.LOGICAL_BUILDER);
+
+ /**
+ * Creates a TranslatableProjectRule.
+ *
+ * @param relBuilderFactory Builder for relational expressions
+ */
+ public TranslatableProjectRule(final RelBuilderFactory relBuilderFactory) {
+ super(operand(LogicalProject.class,
operand(TranslatableTableScan.class, none())),
+ relBuilderFactory, "TranslatableProjectRule");
+ }
+
+ @Override
+ public void onMatch(final RelOptRuleCall call) {
+ LogicalProject project = call.rel(0);
+ TranslatableTableScan scan = call.rel(1);
+ int[] fields = getProjectFields(project.getProjects());
+ if (fields == null) {
+ return;
+ }
+ call.transformTo(
+ new TranslatableTableScan(
+ scan.getCluster(),
+ scan.getTable(),
+ scan.getTranslatableTable(),
+ scan.getFilters(),
+ fields));
+ }
+
+ private int[] getProjectFields(final List<RexNode> exps) {
+ final int[] result = new int[exps.size()];
+ for (int i = 0; i < exps.size(); i++) {
+ final RexNode exp = exps.get(i);
+ if (exp instanceof RexInputRef) {
+ result[i] = ((RexInputRef) exp).getIndex();
+ } else {
+ return null;
+ }
+ }
+ return result;
+ }
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableSchema.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableSchema.java
new file mode 100644
index 00000000000..2e059f38769
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableSchema.java
@@ -0,0 +1,54 @@
+/*
+ * 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.federation.optimizer.metadata.translatable;
+
+import lombok.Getter;
+import org.apache.calcite.schema.Table;
+import org.apache.calcite.schema.impl.AbstractSchema;
+import
org.apache.shardingsphere.infra.federation.optimizer.executor.TableScanExecutor;
+import
org.apache.shardingsphere.infra.federation.optimizer.metadata.statistic.FederationStatistic;
+import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
+import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Filterable schema.
+ */
+@Getter
+public final class TranslatableSchema extends AbstractSchema {
+
+ private final String name;
+
+ private final Map<String, Table> tableMap;
+
+ public TranslatableSchema(final String schemaName, final
ShardingSphereSchema schema, final TableScanExecutor executor) {
+ name = schemaName;
+ tableMap = createTableMap(schema, executor);
+ }
+
+ private Map<String, Table> createTableMap(final ShardingSphereSchema
schema, 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 FederationTranslatableTable(each,
executor, new FederationStatistic()));
+ }
+ return result;
+ }
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableTableScan.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableTableScan.java
new file mode 100644
index 00000000000..b46f77e9832
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/metadata/translatable/TranslatableTableScan.java
@@ -0,0 +1,205 @@
+/*
+ * 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.federation.optimizer.metadata.translatable;
+
+import com.google.common.collect.ImmutableList;
+import lombok.Getter;
+import org.apache.calcite.adapter.enumerable.EnumerableConvention;
+import org.apache.calcite.adapter.enumerable.EnumerableRel;
+import org.apache.calcite.adapter.enumerable.EnumerableRelImplementor;
+import org.apache.calcite.adapter.enumerable.PhysType;
+import org.apache.calcite.adapter.enumerable.PhysTypeImpl;
+import org.apache.calcite.linq4j.tree.Blocks;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.Primitive;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCost;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.core.TableScan;
+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.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SqlKind;
+import org.codehaus.groovy.runtime.InvokerHelper;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Relational expression representing a scan.
+ * Like any table scan, it serves as a leaf node of a query tree.
+ */
+@Getter
+public class TranslatableTableScan extends TableScan implements EnumerableRel {
+
+ private final FederationTranslatableTable translatableTable;
+
+ private final int[] fields;
+
+ private final List<RexNode> filters;
+
+ public TranslatableTableScan(final RelOptCluster cluster, final
RelOptTable table,
+ final FederationTranslatableTable
translatableTable, final int[] fields) {
+ super(cluster, cluster.traitSetOf(EnumerableConvention.INSTANCE),
ImmutableList.of(), table);
+ this.translatableTable = translatableTable;
+ this.fields = fields;
+ this.filters = null;
+ assert translatableTable != null;
+ }
+
+ public TranslatableTableScan(final RelOptCluster cluster, final
RelOptTable table,
+ final FederationTranslatableTable
translatableTable, final List<RexNode> filters, final int[] fields) {
+ super(cluster, cluster.traitSetOf(EnumerableConvention.INSTANCE),
ImmutableList.of(), table);
+ this.translatableTable = translatableTable;
+ this.fields = fields;
+ this.filters = filters;
+ assert translatableTable != null;
+ }
+
+ @Override
+ public RelNode copy(final RelTraitSet traitSet, final List<RelNode>
inputs) {
+ assert inputs.isEmpty();
+ return new TranslatableTableScan(getCluster(), table,
translatableTable, fields);
+ }
+
+ @Override
+ public String toString() {
+ if (null != filters) {
+ final String[] filterValues = new String[fields.length];
+ addFilter(filters, filterValues);
+ return "TranslatableTableScan{"
+ + "translatableTable=" + translatableTable
+ + ", fields=" + Arrays.toString(fields)
+ + ", filters=" + Arrays.toString(filterValues)
+ + '}';
+ }
+ return "TranslatableTableScan{"
+ + "translatableTable=" + translatableTable
+ + ", fields=" + Arrays.toString(fields)
+ + '}';
+ }
+
+ @Override
+ public RelWriter explainTerms(final RelWriter pw) {
+ if (null != filters) {
+ final String[] filterValues = new String[fields.length];
+ addFilter(filters, filterValues);
+ return super.explainTerms(pw)
+ .item("fields", Primitive.asList(fields))
+ .item("filters", Primitive.asList(filterValues));
+ }
+ return super.explainTerms(pw)
+ .item("fields", Primitive.asList(fields));
+ }
+
+ @Override
+ public RelDataType deriveRowType() {
+ final List<RelDataTypeField> fieldList =
table.getRowType().getFieldList();
+ final RelDataTypeFactory.Builder builder =
+ getCluster().getTypeFactory().builder();
+ for (int field : fields) {
+ builder.add(fieldList.get(field));
+ }
+ return builder.build();
+ }
+
+ @Override
+ public void register(final RelOptPlanner planner) {
+ planner.addRule(TranslatableProjectFilterRule.INSTANCE);
+ planner.addRule(TranslatableFilterRule.INSTANCE);
+ planner.addRule(TranslatableProjectRule.INSTANCE);
+ }
+
+ @Override
+ public RelOptCost computeSelfCost(final RelOptPlanner planner,
+ final RelMetadataQuery mq) {
+ return super.computeSelfCost(planner, mq)
+ .multiplyBy(((double) fields.length + 2D)
+ / ((double) table.getRowType().getFieldCount() + 2D));
+ }
+
+ /**
+ * Generate code for translatable table scan.
+ *
+ * @param implementor EnumerableRelImplementor
+ * @param pref Prefer
+ * @return generated code
+ */
+ public Result implement(final EnumerableRelImplementor implementor, final
Prefer pref) {
+ PhysType physType =
+ PhysTypeImpl.of(
+ implementor.getTypeFactory(),
+ getRowType(),
+ pref.preferArray());
+
+ if (null != filters) {
+ final String[] filterValues = new String[fields.length];
+ addFilter(filters, filterValues);
+ return implementor.result(
+ physType,
+ Blocks.toBlock(
+
Expressions.call(table.getExpression(FederationTranslatableTable.class),
+ "projectAndFilter",
implementor.getRootExpression(),
+ Expressions.constant(filterValues),
Expressions.constant(fields))));
+ }
+ return implementor.result(
+ physType,
+ Blocks.toBlock(
+
Expressions.call(table.getExpression(FederationTranslatableTable.class),
+ "project", implementor.getRootExpression(),
+ Expressions.constant(fields))));
+ }
+
+ private boolean addFilter(final List<RexNode> filters, final String[]
filterValues) {
+ for (RexNode filter : filters) {
+ if (filter.isA(SqlKind.AND)) {
+ // We cannot refine(remove) the operands of AND,
+ // it will cause o.a.c.i.TableScanNode.createFilterable
filters check failed.
+ ((RexCall) filter).getOperands().forEach(subFilter ->
addFilter(InvokerHelper.asList(subFilter), filterValues));
+ continue;
+ } else if (filter.isA(SqlKind.EQUALS)) {
+ final RexCall call = (RexCall) filter;
+ String tmp = call.toString();
+ RexNode left = call.getOperands().get(0);
+ if (left.isA(SqlKind.CAST)) {
+ left = ((RexCall) left).operands.get(0);
+ }
+ final RexNode right = call.getOperands().get(1);
+ if (!(left instanceof RexInputRef && right instanceof
RexLiteral)) {
+ continue;
+ }
+ final int index = ((RexInputRef) left).getIndex();
+ if (filterValues[index] == null) {
+ filterValues[index] = ((RexLiteral)
right).getValue2().toString();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/planner/QueryOptimizePlannerFactory.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/planner/QueryOptimizePlannerFactory.java
index bb82923d4b4..3e5ba4d590e 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/planner/QueryOptimizePlannerFactory.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/planner/QueryOptimizePlannerFactory.java
@@ -92,6 +92,7 @@ public final class QueryOptimizePlannerFactory {
private static Collection<RelOptRule> getProjectRules() {
Collection<RelOptRule> result = new LinkedList<>();
result.add(AggregateExpandDistinctAggregatesRule.Config.DEFAULT.toRule());
+ // TODO PROJECT_TO_CALC and FILTER_TO_CALC better be removed when
using TranslatableTableScan.
result.add(CoreRules.PROJECT_TO_CALC);
result.add(CoreRules.FILTER_TO_CALC);
result.add(CoreRules.PROJECT_CALC_MERGE);