You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by dw...@apache.org on 2019/06/04 07:57:41 UTC

[flink] branch master updated: [FLINK-12601][table] Wrapping DataStream & DataSet as TableOperations.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0f41719  [FLINK-12601][table] Wrapping DataStream & DataSet as TableOperations.
0f41719 is described below

commit 0f4171956c8005535243781316defb4ef2fbe258
Author: Dawid Wysakowicz <dw...@apache.org>
AuthorDate: Thu May 23 11:09:59 2019 +0200

    [FLINK-12601][table] Wrapping DataStream & DataSet as
    TableOperations.
    
    We do not store the DataStream & DataSet as Calcite's Tables anymore. We
    treat them as inline operations. When converting from TableOperations to
    RelNodes we directly create a special kind of DataStream/SetScan that
    does not access the catalog.
    
    This closes #8521
---
 .../table/operations/DataSetTableOperation.java}   |  51 +++++---
 .../operations/DataStreamTableOperation.java}      |  52 +++++---
 .../table/catalog/TableOperationCatalogView.java   |  66 ++++++++++
 .../table/operations/AggregateTableOperation.java  |  13 +-
 .../table/operations/CalculatedTableOperation.java |  13 +-
 .../table/operations/CatalogTableOperation.java    |  13 +-
 .../table/operations/DistinctTableOperation.java   |   7 +-
 .../table/operations/FilterTableOperation.java     |  12 +-
 .../flink/table/operations/JoinTableOperation.java |  14 ++-
 .../table/operations/ProjectTableOperation.java    |  12 +-
 .../flink/table/operations/SetTableOperation.java  |  25 +++-
 .../flink/table/operations/SortTableOperation.java |  14 ++-
 .../flink/table/operations/TableOperation.java     |  71 ++++++++++-
 ...ableOperation.java => TableOperationUtils.java} |  27 ++--
 .../operations/WindowAggregateTableOperation.java  |  41 ++++++-
 .../flink/table/operations/TableOperationTest.java | 115 +++++++++++++++++
 .../flink/table/catalog/DatabaseCalciteSchema.java |   2 +
 .../catalog/TableOperationCatalogViewTable.java    |  73 +++++++++++
 .../flink/table/plan/TableOperationConverter.java  |  38 ++++++
 .../apache/flink/table/api/BatchTableEnvImpl.scala |  67 ++++------
 .../flink/table/api/StreamTableEnvImpl.scala       |  98 ++++++---------
 .../org/apache/flink/table/api/TableEnvImpl.scala  | 113 ++++++++---------
 .../flink/table/api/java/BatchTableEnvImpl.scala   |  20 +--
 .../flink/table/api/java/StreamTableEnvImpl.scala  |  26 ++--
 .../flink/table/api/scala/BatchTableEnvImpl.scala  |  18 +--
 .../flink/table/api/scala/StreamTableEnvImpl.scala |  34 +++---
 .../flink/table/calcite/FlinkRelBuilder.scala      |  10 ++
 .../flink/table/calcite/FlinkTypeFactory.scala     |  12 +-
 .../table/operations/PlannerTableOperation.java    |   7 +-
 .../flink/table/plan/nodes/dataset/BatchScan.scala |  12 +-
 .../table/plan/nodes/dataset/DataSetScan.scala     |  36 ++++--
 .../plan/nodes/datastream/DataStreamScan.scala     |  38 ++++--
 ...bleScan.scala => FlinkLogicalDataSetScan.scala} |  61 ++++-----
 ...Scan.scala => FlinkLogicalDataStreamScan.scala} |  59 ++++-----
 .../flink/table/plan/rules/FlinkRuleSets.scala     |   6 +-
 .../table/plan/rules/dataSet/DataSetScanRule.scala |  31 ++---
 .../plan/rules/datastream/DataStreamScanRule.scala |  30 ++---
 .../LogicalCorrelateToTemporalTableJoinRule.scala  |   9 +-
 .../flink/table/plan/schema/DataSetTable.scala     |  29 -----
 .../flink/table/plan/schema/DataStreamTable.scala  |  29 -----
 .../flink/table/plan/schema/InlineTable.scala      | 117 ------------------
 .../apache/flink/table/plan/schema/RelTable.scala  |  46 -------
 .../flink/table/plan/stats/FlinkStatistic.scala    |   3 +-
 .../apache/flink/table/api/TableSourceTest.scala   |  25 ++--
 .../api/batch/BatchTableEnvironmentTest.scala      |   6 +-
 .../apache/flink/table/api/batch/ExplainTest.scala |  68 ++++++++---
 .../flink/table/api/batch/sql/AggregateTest.scala  |  20 +--
 .../flink/table/api/batch/sql/CalcTest.scala       |  12 +-
 .../flink/table/api/batch/sql/CorrelateTest.scala  |  44 +++----
 .../api/batch/sql/DistinctAggregateTest.scala      |  50 ++++----
 .../table/api/batch/sql/GroupWindowTest.scala      |  40 +++---
 .../table/api/batch/sql/GroupingSetsTest.scala     |  24 ++--
 .../flink/table/api/batch/sql/JoinTest.scala       |  72 +++++------
 .../table/api/batch/sql/SetOperatorsTest.scala     |  36 +++---
 .../table/api/batch/sql/SingleRowJoinTest.scala    |  64 +++++-----
 .../table/api/batch/table/AggregateTest.scala      |   8 +-
 .../flink/table/api/batch/table/CalcTest.scala     |  28 ++---
 .../api/batch/table/ColumnFunctionsTest.scala      |   2 +-
 .../table/api/batch/table/CorrelateTest.scala      |  12 +-
 .../table/api/batch/table/GroupWindowTest.scala    |  38 +++---
 .../flink/table/api/batch/table/JoinTest.scala     |  40 +++---
 .../table/api/batch/table/SetOperatorsTest.scala   |  30 ++---
 .../stringexpr/CorrelateStringExpressionTest.scala |  16 ++-
 .../batch/table/stringexpr/SetOperatorsTest.scala  |   6 +-
 .../flink/table/api/stream/ExplainTest.scala       |  29 ++++-
 .../api/stream/StreamTableEnvironmentTest.scala    |   6 +-
 .../flink/table/api/stream/sql/AggregateTest.scala |   4 +-
 .../flink/table/api/stream/sql/CorrelateTest.scala |  48 ++++----
 .../api/stream/sql/DistinctAggregateTest.scala     |  14 +--
 .../table/api/stream/sql/GroupWindowTest.scala     |  16 +--
 .../flink/table/api/stream/sql/JoinTest.scala      | 136 +++++++++++----------
 .../table/api/stream/sql/MatchRecognizeTest.scala  |   9 +-
 .../table/api/stream/sql/OverWindowTest.scala      |  40 +++---
 .../table/api/stream/sql/SetOperatorsTest.scala    |  36 +++---
 .../flink/table/api/stream/sql/SortTest.scala      |   6 +-
 .../api/stream/sql/TemporalTableJoinTest.scala     | 122 ++++++++++++++++--
 .../flink/table/api/stream/sql/UnionTest.scala     |  12 +-
 .../table/api/stream/table/AggregateTest.scala     |  30 ++---
 .../flink/table/api/stream/table/CalcTest.scala    |  33 ++---
 .../api/stream/table/ColumnFunctionsTest.scala     |  32 ++---
 .../table/api/stream/table/CorrelateTest.scala     |  25 ++--
 .../table/GroupWindowTableAggregateTest.scala      |  38 +++---
 .../table/api/stream/table/GroupWindowTest.scala   |  54 ++++----
 .../flink/table/api/stream/table/JoinTest.scala    |  68 +++++------
 .../table/api/stream/table/OverWindowTest.scala    |  34 +++---
 .../table/api/stream/table/SetOperatorsTest.scala  |  22 ++--
 .../api/stream/table/TableAggregateTest.scala      |  12 +-
 .../table/api/stream/table/TableSourceTest.scala   |  29 +++--
 .../api/stream/table/TemporalTableJoinTest.scala   | 103 ++++++++--------
 .../stringexpr/CorrelateStringExpressionTest.scala |  23 +++-
 .../table/match/PatternTranslatorTestBase.scala    |   1 +
 .../table/plan/ExpressionReductionRulesTest.scala  |  51 ++++----
 .../flink/table/plan/NormalizationRulesTest.scala  |  12 +-
 .../flink/table/plan/QueryDecorrelationTest.scala  |  32 +++--
 .../table/plan/TimeIndicatorConversionTest.scala   |  44 +++----
 .../runtime/stream/table/TableSourceITCase.scala   |  25 ++++
 .../apache/flink/table/utils/TableTestBase.scala   |  35 +++---
 .../src/test/scala/resources/testFilter0.out       |   4 +-
 .../src/test/scala/resources/testFilter1.out       |   4 +-
 .../src/test/scala/resources/testFilterStream0.out |   4 +-
 .../src/test/scala/resources/testJoin0.out         |   8 +-
 .../src/test/scala/resources/testJoin1.out         |   8 +-
 .../src/test/scala/resources/testUnion0.out        |   8 +-
 .../src/test/scala/resources/testUnion1.out        |   8 +-
 .../src/test/scala/resources/testUnionStream0.out  |   8 +-
 105 files changed, 1950 insertions(+), 1494 deletions(-)

diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java b/flink-table/flink-table-api-java-bridge/src/main/java/org/apache/flink/table/operations/DataSetTableOperation.java
similarity index 52%
copy from flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java
copy to flink-table/flink-table-api-java-bridge/src/main/java/org/apache/flink/table/operations/DataSetTableOperation.java
index 7c5019d..85e1a26 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java
+++ b/flink-table/flink-table-api-java-bridge/src/main/java/org/apache/flink/table/operations/DataSetTableOperation.java
@@ -19,39 +19,44 @@
 package org.apache.flink.table.operations;
 
 import org.apache.flink.annotation.Internal;
-import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.DataSet;
 import org.apache.flink.table.api.TableSchema;
-import org.apache.flink.table.calcite.FlinkTypeFactory;
-
-import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.type.RelDataType;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
- * Wrapper for valid logical plans generated by Planner.
+ * Describes a relational operation that reads from a {@link DataSet}.
+ *
+ * <p>This operation may expose only part, or change the order of the fields available in a
+ * {@link org.apache.flink.api.common.typeutils.CompositeType} of the underlying {@link DataSet}.
+ * The {@link DataSetTableOperation#getFieldIndices()} describes the mapping between fields of the
+ * {@link TableSchema} to the {@link org.apache.flink.api.common.typeutils.CompositeType}.
  */
 @Internal
-public class PlannerTableOperation implements TableOperation {
+public class DataSetTableOperation<E> extends TableOperation {
 
-	private final RelNode calciteTree;
+	private final DataSet<E> dataSet;
+	private final int[] fieldIndices;
 	private final TableSchema tableSchema;
 
-	public PlannerTableOperation(RelNode calciteTree) {
-		this.calciteTree = calciteTree;
-
-		RelDataType rowType = calciteTree.getRowType();
-		String[] fieldNames = rowType.getFieldNames().toArray(new String[0]);
-		TypeInformation[] fieldTypes = rowType.getFieldList()
-			.stream()
-			.map(field -> FlinkTypeFactory.toTypeInfo(field.getType())).toArray(TypeInformation[]::new);
+	public DataSetTableOperation(
+			DataSet<E> dataSet,
+			int[] fieldIndices,
+			TableSchema tableSchema) {
+		this.dataSet = dataSet;
+		this.tableSchema = tableSchema;
+		this.fieldIndices = fieldIndices;
+	}
 
-		this.tableSchema = new TableSchema(fieldNames, fieldTypes);
+	public DataSet<E> getDataSet() {
+		return dataSet;
 	}
 
-	public RelNode getCalciteTree() {
-		return calciteTree;
+	public int[] getFieldIndices() {
+		return fieldIndices;
 	}
 
 	@Override
@@ -60,6 +65,14 @@ public class PlannerTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("fields", tableSchema.getFieldNames());
+
+		return formatWithChildren("DataSet", args);
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.emptyList();
 	}
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java b/flink-table/flink-table-api-java-bridge/src/main/java/org/apache/flink/table/operations/DataStreamTableOperation.java
similarity index 50%
copy from flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java
copy to flink-table/flink-table-api-java-bridge/src/main/java/org/apache/flink/table/operations/DataStreamTableOperation.java
index 7c5019d..2e50208 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java
+++ b/flink-table/flink-table-api-java-bridge/src/main/java/org/apache/flink/table/operations/DataStreamTableOperation.java
@@ -19,39 +19,44 @@
 package org.apache.flink.table.operations;
 
 import org.apache.flink.annotation.Internal;
-import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.streaming.api.datastream.DataStream;
 import org.apache.flink.table.api.TableSchema;
-import org.apache.flink.table.calcite.FlinkTypeFactory;
-
-import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.type.RelDataType;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
- * Wrapper for valid logical plans generated by Planner.
+ * Describes a relational operation that reads from a {@link DataStream}.
+ *
+ * <p>This operation may expose only part, or change the order of the fields available in a
+ * {@link org.apache.flink.api.common.typeutils.CompositeType} of the underlying {@link DataStream}.
+ * The {@link DataStreamTableOperation#getFieldIndices()} describes the mapping between fields of the
+ * {@link TableSchema} to the {@link org.apache.flink.api.common.typeutils.CompositeType}.
  */
 @Internal
-public class PlannerTableOperation implements TableOperation {
+public class DataStreamTableOperation<E> extends TableOperation {
 
-	private final RelNode calciteTree;
+	private final DataStream<E> dataStream;
+	private final int[] fieldIndices;
 	private final TableSchema tableSchema;
 
-	public PlannerTableOperation(RelNode calciteTree) {
-		this.calciteTree = calciteTree;
-
-		RelDataType rowType = calciteTree.getRowType();
-		String[] fieldNames = rowType.getFieldNames().toArray(new String[0]);
-		TypeInformation[] fieldTypes = rowType.getFieldList()
-			.stream()
-			.map(field -> FlinkTypeFactory.toTypeInfo(field.getType())).toArray(TypeInformation[]::new);
+	public DataStreamTableOperation(
+			DataStream<E> dataStream,
+			int[] fieldIndices,
+			TableSchema tableSchema) {
+		this.dataStream = dataStream;
+		this.tableSchema = tableSchema;
+		this.fieldIndices = fieldIndices;
+	}
 
-		this.tableSchema = new TableSchema(fieldNames, fieldTypes);
+	public DataStream<E> getDataStream() {
+		return dataStream;
 	}
 
-	public RelNode getCalciteTree() {
-		return calciteTree;
+	public int[] getFieldIndices() {
+		return fieldIndices;
 	}
 
 	@Override
@@ -60,6 +65,15 @@ public class PlannerTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("id", dataStream.getId());
+		args.put("fields", tableSchema.getFieldNames());
+
+		return formatWithChildren("DataStream", args);
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.emptyList();
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/catalog/TableOperationCatalogView.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/catalog/TableOperationCatalogView.java
new file mode 100644
index 0000000..0e9aafe
--- /dev/null
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/catalog/TableOperationCatalogView.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.flink.table.catalog;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.operations.TableOperation;
+
+import java.util.HashMap;
+import java.util.Optional;
+
+/**
+ * A view created from {@link TableOperation} via operations on {@link org.apache.flink.table.api.Table}.
+ */
+@Internal
+public class TableOperationCatalogView extends AbstractCatalogView {
+	private final TableOperation tableOperation;
+
+	public TableOperationCatalogView(TableOperation tableOperation) {
+		this(tableOperation, "");
+	}
+
+	public TableOperationCatalogView(TableOperation tableOperation, String comment) {
+		super(
+			tableOperation.asSummaryString(),
+			tableOperation.asSummaryString(),
+			tableOperation.getTableSchema(),
+			new HashMap<>(),
+			comment);
+		this.tableOperation = tableOperation;
+	}
+
+	public TableOperation getTableOperation() {
+		return tableOperation;
+	}
+
+	@Override
+	public TableOperationCatalogView copy() {
+		return new TableOperationCatalogView(this.tableOperation, getComment());
+	}
+
+	@Override
+	public Optional<String> getDescription() {
+		return Optional.of(getComment());
+	}
+
+	@Override
+	public Optional<String> getDetailedDescription() {
+		return getDescription();
+	}
+}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/AggregateTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/AggregateTableOperation.java
index a2b2478..c3fa6e2 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/AggregateTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/AggregateTableOperation.java
@@ -23,14 +23,16 @@ import org.apache.flink.table.api.TableSchema;
 import org.apache.flink.table.expressions.Expression;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Relational operation that performs computations on top of subsets of input rows grouped by
  * key.
  */
 @Internal
-public class AggregateTableOperation implements TableOperation {
+public class AggregateTableOperation extends TableOperation {
 
 	private final List<Expression> groupingExpressions;
 	private final List<Expression> aggregateExpressions;
@@ -53,6 +55,15 @@ public class AggregateTableOperation implements TableOperation {
 		return tableSchema;
 	}
 
+	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("group", groupingExpressions);
+		args.put("agg", aggregateExpressions);
+
+		return formatWithChildren("Aggregate", args);
+	}
+
 	public List<Expression> getGroupingExpressions() {
 		return groupingExpressions;
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/CalculatedTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/CalculatedTableOperation.java
index 58097b9..f030214 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/CalculatedTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/CalculatedTableOperation.java
@@ -25,13 +25,15 @@ import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.functions.TableFunction;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Describes a relational operation that was created from applying a {@link TableFunction}.
  */
 @Internal
-public class CalculatedTableOperation<T> implements TableOperation {
+public class CalculatedTableOperation<T> extends TableOperation {
 
 	private final TableFunction<T> tableFunction;
 	private final List<Expression> parameters;
@@ -67,6 +69,15 @@ public class CalculatedTableOperation<T> implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("function", tableFunction);
+		args.put("parameters", parameters);
+
+		return formatWithChildren("CalculatedTable", args);
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.emptyList();
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/CatalogTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/CatalogTableOperation.java
index 3d13d09..daad3b1 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/CatalogTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/CatalogTableOperation.java
@@ -22,13 +22,15 @@ import org.apache.flink.annotation.Internal;
 import org.apache.flink.table.api.TableSchema;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Describes a relational operation that was created from a lookup to a catalog.
  */
 @Internal
-public class CatalogTableOperation implements TableOperation {
+public class CatalogTableOperation extends TableOperation {
 
 	private final List<String> tablePath;
 	private final TableSchema tableSchema;
@@ -48,6 +50,15 @@ public class CatalogTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("path", tablePath);
+		args.put("fields", tableSchema.getFieldNames());
+
+		return formatWithChildren("CatalogTable", args);
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.emptyList();
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/DistinctTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/DistinctTableOperation.java
index fbb1716..5453aff 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/DistinctTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/DistinctTableOperation.java
@@ -28,7 +28,7 @@ import java.util.List;
  * Removes duplicated rows of underlying relational operation.
  */
 @Internal
-public class DistinctTableOperation implements TableOperation {
+public class DistinctTableOperation extends TableOperation {
 
 	private final TableOperation child;
 
@@ -42,6 +42,11 @@ public class DistinctTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		return formatWithChildren("Distinct", Collections.emptyMap());
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.singletonList(child);
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/FilterTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/FilterTableOperation.java
index 651071a..5605d24 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/FilterTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/FilterTableOperation.java
@@ -23,13 +23,15 @@ import org.apache.flink.table.api.TableSchema;
 import org.apache.flink.table.expressions.Expression;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Filters out rows of underlying relational operation that do not match given condition.
  */
 @Internal
-public class FilterTableOperation implements TableOperation {
+public class FilterTableOperation extends TableOperation {
 
 	private final Expression condition;
 	private final TableOperation child;
@@ -49,6 +51,14 @@ public class FilterTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("condition", condition);
+
+		return formatWithChildren("Filter", args);
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.singletonList(child);
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/JoinTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/JoinTableOperation.java
index d4808a7..6f077be2 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/JoinTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/JoinTableOperation.java
@@ -24,13 +24,15 @@ import org.apache.flink.table.api.TableSchema;
 import org.apache.flink.table.expressions.Expression;
 
 import java.util.Arrays;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Table operation that joins two relational operations based on given condition.
  */
 @Internal
-public class JoinTableOperation implements TableOperation {
+public class JoinTableOperation extends TableOperation {
 	private final TableOperation left;
 	private final TableOperation right;
 	private final JoinType joinType;
@@ -106,6 +108,16 @@ public class JoinTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("joinType", joinType);
+		args.put("condition", condition);
+		args.put("correlated", correlated);
+
+		return formatWithChildren("Join", args);
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Arrays.asList(left, right);
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/ProjectTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/ProjectTableOperation.java
index 6b9daff..5d97f45 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/ProjectTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/ProjectTableOperation.java
@@ -23,14 +23,16 @@ import org.apache.flink.table.api.TableSchema;
 import org.apache.flink.table.expressions.Expression;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Table operation that computes new table using given {@link Expression}s
  * from its input relational operation.
  */
 @Internal
-public class ProjectTableOperation implements TableOperation {
+public class ProjectTableOperation extends TableOperation {
 
 	private final List<Expression> projectList;
 	private final TableOperation child;
@@ -55,6 +57,14 @@ public class ProjectTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("projections", projectList);
+
+		return formatWithChildren("Project", args);
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.singletonList(child);
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/SetTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/SetTableOperation.java
index d96d7ef..1bad517 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/SetTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/SetTableOperation.java
@@ -22,14 +22,16 @@ import org.apache.flink.annotation.Internal;
 import org.apache.flink.table.api.TableSchema;
 
 import java.util.Arrays;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * A set operation on two relations. It provides a way to union, intersect or subtract underlying
  * data sets/streams. Both relations must have equal schemas.
  */
 @Internal
-public class SetTableOperation implements TableOperation {
+public class SetTableOperation extends TableOperation {
 
 	private final TableOperation leftOperation;
 	private final TableOperation rightOperation;
@@ -68,6 +70,27 @@ public class SetTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("all", all);
+
+		return formatWithChildren(typeToString(), args);
+	}
+
+	private String typeToString() {
+		switch (type) {
+			case INTERSECT:
+				return "Intersect";
+			case MINUS:
+				return "Minus";
+			case UNION:
+				return "Union";
+			default:
+				throw new IllegalStateException("Unknown set operation type: " + type);
+		}
+	}
+
+	@Override
 	public <T> T accept(TableOperationVisitor<T> visitor) {
 		return visitor.visitSetOperation(this);
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/SortTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/SortTableOperation.java
index f3965cb..7293678 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/SortTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/SortTableOperation.java
@@ -23,14 +23,16 @@ import org.apache.flink.table.api.TableSchema;
 import org.apache.flink.table.expressions.Expression;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Expresses sort operation of rows of the underlying relational operation with given order.
  * It also allows specifying offset and number of rows to fetch from the sorted data set/stream.
  */
 @Internal
-public class SortTableOperation implements TableOperation {
+public class SortTableOperation extends TableOperation {
 
 	private final List<Expression> order;
 	private final TableOperation child;
@@ -72,6 +74,16 @@ public class SortTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("order", order);
+		args.put("offset", offset);
+		args.put("fetch", fetch);
+
+		return formatWithChildren("Sort", args);
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.singletonList(child);
 	}
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperation.java
index 3cf6c26..2cfd313 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperation.java
@@ -21,21 +21,84 @@ package org.apache.flink.table.operations;
 import org.apache.flink.annotation.Internal;
 import org.apache.flink.table.api.Table;
 import org.apache.flink.table.api.TableSchema;
+import org.apache.flink.util.StringUtils;
 
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * Base class for representing the operation structure behind a user-facing {@link Table} API.
  */
 @Internal
-public interface TableOperation {
+public abstract class TableOperation {
 
 	/**
 	 * Resolved schema of this operation.
 	 */
-	TableSchema getTableSchema();
+	public abstract TableSchema getTableSchema();
 
-	List<TableOperation> getChildren();
+	/**
+	 * Returns a string that summarizes this operation for printing to a console. An implementation might
+	 * skip very specific properties.
+	 *
+	 * <p>Use {@link #asSerializableString()} for a operation string that fully serializes
+	 * this instance.
+	 *
+	 * @return summary string of this operation for debugging purposes
+	 */
+	public abstract String asSummaryString();
+
+	/**
+	 * Returns a string that fully serializes this instance. The serialized string can be used for storing
+	 * the query in e.g. a {@link org.apache.flink.table.catalog.Catalog} as a view.
+	 *
+	 * @return detailed string for persisting in a catalog
+	 */
+	public String asSerializableString() {
+		throw new UnsupportedOperationException("TableOperations are not string serializable for now.");
+	}
+
+	public abstract List<TableOperation> getChildren();
+
+	public <T> T accept(TableOperationVisitor<T> visitor) {
+		return visitor.visitOther(this);
+	}
+
+	protected final String formatWithChildren(String operationName, Map<String, Object> parameters) {
+		String description = parameters.entrySet()
+			.stream()
+			.map(entry -> formatParameter(entry.getKey(), entry.getValue()))
+			.collect(Collectors.joining(", "));
+
+		final StringBuilder stringBuilder = new StringBuilder();
+
+		stringBuilder.append(operationName).append(":");
+
+		if (!StringUtils.isNullOrWhitespaceOnly(description)) {
+			stringBuilder.append(" (").append(description).append(")");
+		}
+
+		String childrenDescription = getChildren().stream()
+			.map(child -> TableOperationUtils.indent(child.asSummaryString()))
+			.collect(Collectors.joining());
+
+		return stringBuilder.append(childrenDescription).toString();
+	}
 
-	<T> T accept(TableOperationVisitor<T> visitor);
+	private String formatParameter(String name, Object value) {
+		final StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append(name);
+		stringBuilder.append(": ");
+		if (value.getClass().isArray()) {
+			stringBuilder.append(Arrays.toString((Object[]) value));
+		} else if (value instanceof Collection) {
+			stringBuilder.append(value);
+		} else {
+			stringBuilder.append("[").append(value).append("]");
+		}
+		return stringBuilder.toString();
+	}
 }
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperationUtils.java
similarity index 59%
copy from flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperation.java
copy to flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperationUtils.java
index 3cf6c26..d27a224 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/TableOperationUtils.java
@@ -19,23 +19,28 @@
 package org.apache.flink.table.operations;
 
 import org.apache.flink.annotation.Internal;
-import org.apache.flink.table.api.Table;
-import org.apache.flink.table.api.TableSchema;
-
-import java.util.List;
 
 /**
- * Base class for representing the operation structure behind a user-facing {@link Table} API.
+ * Helper methods for {@link TableOperation}s.
  */
 @Internal
-public interface TableOperation {
+public class TableOperationUtils {
+
+	private static final String OPERATION_INDENT = "    ";
 
 	/**
-	 * Resolved schema of this operation.
+	 * Increases indentation for description of string of child {@link TableOperation}.
+	 * The input can already contain indentation. This will increase all the indentations
+	 * by one level.
+	 *
+	 * @param item result of {@link TableOperation#asSummaryString()}
+	 * @return string with increased indentation
 	 */
-	TableSchema getTableSchema();
-
-	List<TableOperation> getChildren();
+	static String indent(String item) {
+		return "\n" + OPERATION_INDENT +
+			item.replace("\n" + OPERATION_INDENT, "\n" + OPERATION_INDENT + OPERATION_INDENT);
+	}
 
-	<T> T accept(TableOperationVisitor<T> visitor);
+	private TableOperationUtils() {
+	}
 }
diff --git a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/WindowAggregateTableOperation.java b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/WindowAggregateTableOperation.java
index 95c1d33..cbe2f4e 100644
--- a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/WindowAggregateTableOperation.java
+++ b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/operations/WindowAggregateTableOperation.java
@@ -28,7 +28,9 @@ import org.apache.flink.util.StringUtils;
 import javax.annotation.Nullable;
 
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 import static org.apache.flink.table.operations.WindowAggregateTableOperation.ResolvedGroupWindow.WindowType.SESSION;
@@ -42,7 +44,7 @@ import static org.apache.flink.util.Preconditions.checkNotNull;
  * key and group window. It differs from {@link AggregateTableOperation} by the group window.
  */
 @Internal
-public class WindowAggregateTableOperation implements TableOperation {
+public class WindowAggregateTableOperation extends TableOperation {
 
 	private final List<Expression> groupingExpressions;
 	private final List<Expression> aggregateExpressions;
@@ -71,6 +73,17 @@ public class WindowAggregateTableOperation implements TableOperation {
 		return tableSchema;
 	}
 
+	@Override
+	public String asSummaryString() {
+		Map<String, Object> args = new LinkedHashMap<>();
+		args.put("group", groupingExpressions);
+		args.put("agg", aggregateExpressions);
+		args.put("windowProperties", windowPropertiesExpressions);
+		args.put("window", groupWindow.asSummaryString());
+
+		return formatWithChildren("WindowAggregate", args);
+	}
+
 	public List<Expression> getGroupingExpressions() {
 		return groupingExpressions;
 	}
@@ -124,7 +137,8 @@ public class WindowAggregateTableOperation implements TableOperation {
 		 */
 		private ResolvedGroupWindow(
 				WindowType type,
-				String alias, FieldReferenceExpression timeAttribute,
+				String alias,
+				FieldReferenceExpression timeAttribute,
 				@Nullable ValueLiteralExpression size,
 				@Nullable ValueLiteralExpression slide,
 				@Nullable ValueLiteralExpression gap) {
@@ -202,5 +216,28 @@ public class WindowAggregateTableOperation implements TableOperation {
 		public Optional<ValueLiteralExpression> getGap() {
 			return Optional.of(gap);
 		}
+
+		public String asSummaryString() {
+			switch (type) {
+				case SLIDE:
+					return String.format(
+						"SlideWindow(field: [%s], slide: [%s], size: [%s])",
+						timeAttribute,
+						slide,
+						size);
+				case SESSION:
+					return String.format(
+						"SessionWindow(field: [%s], gap: [%s])",
+						timeAttribute,
+						gap);
+				case TUMBLE:
+					return String.format(
+						"TumbleWindow(field: [%s], size: [%s])",
+						timeAttribute,
+						size);
+				default:
+					throw new IllegalStateException("Unknown window type: " + type);
+			}
+		}
 	}
 }
diff --git a/flink-table/flink-table-api-java/src/test/java/org/apache/flink/table/operations/TableOperationTest.java b/flink-table/flink-table-api-java/src/test/java/org/apache/flink/table/operations/TableOperationTest.java
new file mode 100644
index 0000000..deb1273
--- /dev/null
+++ b/flink-table/flink-table-api-java/src/test/java/org/apache/flink/table/operations/TableOperationTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.flink.table.operations;
+
+import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.TableSchema;
+import org.apache.flink.table.expressions.ApiExpressionUtils;
+import org.apache.flink.table.expressions.BuiltInFunctionDefinitions;
+import org.apache.flink.table.expressions.CallExpression;
+import org.apache.flink.table.expressions.FieldReferenceExpression;
+import org.apache.flink.table.typeutils.TimeIntervalTypeInfo;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for describing {@link TableOperation}s.
+ */
+public class TableOperationTest {
+
+	@Test
+	public void testSummaryString() {
+		TableSchema schema = TableSchema.builder().field("a", DataTypes.INT()).build();
+
+		ProjectTableOperation tableOperation = new ProjectTableOperation(
+			Collections.singletonList(new FieldReferenceExpression("a", Types.INT, 0, 0)),
+			new CatalogTableOperation(
+				Arrays.asList("cat1", "db1", "tab1"),
+				schema), schema);
+
+		SetTableOperation unionTableOperation = new SetTableOperation(
+			tableOperation,
+			tableOperation,
+			SetTableOperation.SetTableOperationType.UNION,
+			true);
+
+		assertEquals("Union: (all: [true])\n" +
+			"    Project: (projections: [a])\n" +
+			"        CatalogTable: (path: [cat1, db1, tab1], fields: [a])\n" +
+			"    Project: (projections: [a])\n" +
+			"        CatalogTable: (path: [cat1, db1, tab1], fields: [a])",
+			unionTableOperation.asSummaryString());
+	}
+
+	@Test
+	public void testWindowAggregationSummaryString() {
+		TableSchema schema = TableSchema.builder().field("a", DataTypes.INT()).build();
+		FieldReferenceExpression field = new FieldReferenceExpression("a", Types.INT, 0, 0);
+		WindowAggregateTableOperation tableOperation = new WindowAggregateTableOperation(
+			Collections.singletonList(field),
+			Collections.singletonList(new CallExpression(BuiltInFunctionDefinitions.SUM,
+				Collections.singletonList(field))),
+			Collections.emptyList(),
+			WindowAggregateTableOperation.ResolvedGroupWindow.sessionWindow("w", field, ApiExpressionUtils.valueLiteral(
+				10,
+				TimeIntervalTypeInfo.INTERVAL_MILLIS)),
+			new CatalogTableOperation(
+				Arrays.asList("cat1", "db1", "tab1"),
+				schema),
+			schema
+		);
+
+		DistinctTableOperation distinctTableOperation = new DistinctTableOperation(tableOperation);
+
+		assertEquals(
+			"Distinct:\n" +
+			"    WindowAggregate: (group: [a], agg: [sum(a)], windowProperties: []," +
+				" window: [SessionWindow(field: [a], gap: [10.millis])])\n" +
+				"        CatalogTable: (path: [cat1, db1, tab1], fields: [a])",
+			distinctTableOperation.asSummaryString());
+	}
+
+	@Test
+	public void testIndentation() {
+
+		String input =
+			"firstLevel\n" +
+			"    secondLevel0\n" +
+			"        thirdLevel0\n" +
+			"    secondLevel1\n" +
+			"        thirdLevel1";
+
+		String indentedInput = TableOperationUtils.indent(input);
+
+		assertEquals(
+			"\n" +
+			"    firstLevel\n" +
+			"        secondLevel0\n" +
+			"            thirdLevel0\n" +
+			"        secondLevel1\n" +
+			"            thirdLevel1",
+			indentedInput);
+	}
+}
diff --git a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/catalog/DatabaseCalciteSchema.java b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/catalog/DatabaseCalciteSchema.java
index cb341ed..7d93b3a 100644
--- a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/catalog/DatabaseCalciteSchema.java
+++ b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/catalog/DatabaseCalciteSchema.java
@@ -67,6 +67,8 @@ class DatabaseCalciteSchema implements Schema {
 
 			if (table instanceof CalciteCatalogTable) {
 				return ((CalciteCatalogTable) table).getTable();
+			} else if (table instanceof TableOperationCatalogView) {
+				return TableOperationCatalogViewTable.createCalciteTable(((TableOperationCatalogView) table));
 			} else {
 				throw new TableException("Unsupported table type: " + table);
 			}
diff --git a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/catalog/TableOperationCatalogViewTable.java b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/catalog/TableOperationCatalogViewTable.java
new file mode 100644
index 0000000..baf2efc
--- /dev/null
+++ b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/catalog/TableOperationCatalogViewTable.java
@@ -0,0 +1,73 @@
+/*
+ * 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.flink.table.catalog;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.api.TableSchema;
+import org.apache.flink.table.calcite.FlinkRelBuilder;
+import org.apache.flink.table.calcite.FlinkTypeFactory;
+
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.plan.RelOptUtil;
+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.RelProtoDataType;
+import org.apache.calcite.schema.TranslatableTable;
+import org.apache.calcite.schema.impl.AbstractTable;
+
+/**
+ * A bridge between a Flink's specific {@link TableOperationCatalogView} and a Calcite's
+ * {@link org.apache.calcite.schema.Table}. It implements {@link TranslatableTable} interface. This enables
+ * direct translation from {@link org.apache.flink.table.operations.TableOperation} to {@link RelNode}.
+ *
+ * <p>NOTE: Due to legacy inconsistency in null handling in the {@link TableSchema} the translation might introduce
+ * additional cast to comply with manifested schema in
+ * {@link TableOperationCatalogViewTable#getRowType(RelDataTypeFactory)}.
+ */
+@Internal
+public class TableOperationCatalogViewTable extends AbstractTable implements TranslatableTable {
+	private final TableOperationCatalogView catalogView;
+	private final RelProtoDataType rowType;
+
+	public static TableOperationCatalogViewTable createCalciteTable(TableOperationCatalogView catalogView) {
+		return new TableOperationCatalogViewTable(catalogView, typeFactory -> {
+			TableSchema tableSchema = catalogView.getSchema();
+			return ((FlinkTypeFactory) typeFactory).buildLogicalRowType(tableSchema);
+		});
+	}
+
+	private TableOperationCatalogViewTable(TableOperationCatalogView catalogView, RelProtoDataType rowType) {
+		this.catalogView = catalogView;
+		this.rowType = rowType;
+	}
+
+	@Override
+	public RelNode toRel(RelOptTable.ToRelContext context, RelOptTable relOptTable) {
+		FlinkRelBuilder relBuilder = FlinkRelBuilder.of(context.getCluster(), relOptTable);
+
+		RelNode relNode = relBuilder.tableOperation(catalogView.getTableOperation()).build();
+		return RelOptUtil.createCastRel(relNode, rowType.apply(relBuilder.getTypeFactory()), false);
+	}
+
+	@Override
+	public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+		return rowType.apply(typeFactory);
+	}
+}
diff --git a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/plan/TableOperationConverter.java b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/plan/TableOperationConverter.java
index 565bca7..f3aaac8 100644
--- a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/plan/TableOperationConverter.java
+++ b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/plan/TableOperationConverter.java
@@ -40,6 +40,8 @@ import org.apache.flink.table.operations.AggregateOperationFactory;
 import org.apache.flink.table.operations.AggregateTableOperation;
 import org.apache.flink.table.operations.CalculatedTableOperation;
 import org.apache.flink.table.operations.CatalogTableOperation;
+import org.apache.flink.table.operations.DataSetTableOperation;
+import org.apache.flink.table.operations.DataStreamTableOperation;
 import org.apache.flink.table.operations.DistinctTableOperation;
 import org.apache.flink.table.operations.FilterTableOperation;
 import org.apache.flink.table.operations.JoinTableOperation;
@@ -57,12 +59,17 @@ import org.apache.flink.table.plan.logical.LogicalWindow;
 import org.apache.flink.table.plan.logical.SessionGroupWindow;
 import org.apache.flink.table.plan.logical.SlidingGroupWindow;
 import org.apache.flink.table.plan.logical.TumblingGroupWindow;
+import org.apache.flink.table.plan.nodes.FlinkConventions;
+import org.apache.flink.table.plan.nodes.logical.FlinkLogicalDataSetScan;
+import org.apache.flink.table.plan.nodes.logical.FlinkLogicalDataStreamScan;
 import org.apache.flink.table.plan.schema.FlinkTableFunctionImpl;
+import org.apache.flink.table.plan.schema.RowSchema;
 
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.CorrelationId;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.logical.LogicalTableFunctionScan;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.tools.RelBuilder.AggCall;
 import org.apache.calcite.tools.RelBuilder.GroupKey;
@@ -248,11 +255,42 @@ public class TableOperationConverter extends TableOperationDefaultVisitor<RelNod
 		public RelNode visitOther(TableOperation other) {
 			if (other instanceof PlannerTableOperation) {
 				return ((PlannerTableOperation) other).getCalciteTree();
+			} else if (other instanceof DataStreamTableOperation) {
+				return convertToDataStreamScan((DataStreamTableOperation<?>) other);
+			} else if (other instanceof DataSetTableOperation) {
+				return convertToDataSetScan((DataSetTableOperation<?>) other);
 			}
 
 			throw new TableException("Unknown table operation: " + other);
 		}
 
+		private RelNode convertToDataStreamScan(DataStreamTableOperation<?> tableOperation) {
+			RelDataType logicalRowType = relBuilder.getTypeFactory()
+				.buildLogicalRowType(tableOperation.getTableSchema());
+			RowSchema rowSchema = new RowSchema(logicalRowType);
+
+			return new FlinkLogicalDataStreamScan(
+				relBuilder.getCluster(),
+				relBuilder.getCluster().traitSet().replace(FlinkConventions.LOGICAL()),
+				relBuilder.getRelOptSchema(),
+				tableOperation.getDataStream(),
+				tableOperation.getFieldIndices(),
+				rowSchema);
+		}
+
+		private RelNode convertToDataSetScan(DataSetTableOperation<?> tableOperation) {
+			RelDataType logicalRowType = relBuilder.getTypeFactory()
+				.buildLogicalRowType(tableOperation.getTableSchema());
+
+			return new FlinkLogicalDataSetScan(
+				relBuilder.getCluster(),
+				relBuilder.getCluster().traitSet().replace(FlinkConventions.LOGICAL()),
+				relBuilder.getRelOptSchema(),
+				tableOperation.getDataSet(),
+				tableOperation.getFieldIndices(),
+				logicalRowType);
+		}
+
 		private RexNode convertToRexNode(Expression expression) {
 			return expressionBridge.bridge(expression).toRexNode(relBuilder);
 		}
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/BatchTableEnvImpl.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/BatchTableEnvImpl.scala
index d0ee440..6dad03a 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/BatchTableEnvImpl.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/BatchTableEnvImpl.scala
@@ -35,6 +35,7 @@ import org.apache.flink.table.descriptors.{BatchTableDescriptor, ConnectorDescri
 import org.apache.flink.table.explain.PlanJsonParser
 import org.apache.flink.table.expressions.BuiltInFunctionDefinitions.TIME_ATTRIBUTES
 import org.apache.flink.table.expressions.{CallExpression, Expression}
+import org.apache.flink.table.operations.DataSetTableOperation
 import org.apache.flink.table.plan.nodes.FlinkConventions
 import org.apache.flink.table.plan.nodes.dataset.DataSetRel
 import org.apache.flink.table.plan.rules.FlinkRuleSets
@@ -42,7 +43,7 @@ import org.apache.flink.table.plan.schema._
 import org.apache.flink.table.runtime.MapRunner
 import org.apache.flink.table.sinks._
 import org.apache.flink.table.sources.{BatchTableSource, TableSource}
-import org.apache.flink.table.typeutils.FieldInfoUtils.{getFieldsInfo, validateInputTypeInfo}
+import org.apache.flink.table.typeutils.FieldInfoUtils.{calculateTableSchema, getFieldsInfo, validateInputTypeInfo}
 import org.apache.flink.types.Row
 
 /**
@@ -116,7 +117,7 @@ abstract class BatchTableEnvImpl(
               val enrichedTable = new TableSourceSinkTable(
                 Some(new BatchTableSourceTable(batchTableSource)),
                 table.tableSinkTable)
-              replaceRegisteredTable(name, enrichedTable)
+              replaceRegisteredTableSourceSinkInternal(name, enrichedTable)
           }
 
           // no table is registered
@@ -124,7 +125,7 @@ abstract class BatchTableEnvImpl(
             val newTable = new TableSourceSinkTable(
               Some(new BatchTableSourceTable(batchTableSource)),
               None)
-            registerTableInternal(name, newTable)
+            registerTableSourceSinkInternal(name, newTable)
         }
 
       // not a batch table source
@@ -196,7 +197,7 @@ abstract class BatchTableEnvImpl(
               val enrichedTable = new TableSourceSinkTable(
                 table.tableSourceTable,
                 Some(new TableSinkTable(configuredSink)))
-              replaceRegisteredTable(name, enrichedTable)
+              replaceRegisteredTableSourceSinkInternal(name, enrichedTable)
           }
 
           // no table is registered
@@ -204,7 +205,7 @@ abstract class BatchTableEnvImpl(
             val newTable = new TableSourceSinkTable(
               None,
               Some(new TableSinkTable(configuredSink)))
-            registerTableInternal(name, newTable)
+            registerTableSourceSinkInternal(name, newTable)
         }
 
       // not a batch table sink
@@ -312,51 +313,27 @@ abstract class BatchTableEnvImpl(
 
   def explain(table: Table): String = explain(table: Table, extended = false)
 
-  /**
-    * Registers a [[DataSet]] as a table under a given name in the [[TableEnvImpl]]'s catalog.
-    *
-    * @param name The name under which the table is registered in the catalog.
-    * @param dataSet The [[DataSet]] to register as table in the catalog.
-    * @tparam T the type of the [[DataSet]].
-    */
-  protected def registerDataSetInternal[T](name: String, dataSet: DataSet[T]): Unit = {
-
-    val fieldInfo = getFieldsInfo[T](dataSet.getType)
-    val dataSetTable = new DataSetTable[T](
-      dataSet,
-      fieldInfo.getIndices,
-      fieldInfo.getFieldNames
-    )
-    registerTableInternal(name, dataSetTable)
-  }
-
-  /**
-    * Registers a [[DataSet]] as a table under a given name with field names as specified by
-    * field expressions in the [[TableEnvImpl]]'s catalog.
-    *
-    * @param name The name under which the table is registered in the catalog.
-    * @param dataSet The [[DataSet]] to register as table in the catalog.
-    * @param fields The field expressions to define the field names of the table.
-    * @tparam T The type of the [[DataSet]].
-    */
-  protected def registerDataSetInternal[T](
-      name: String, dataSet: DataSet[T], fields: Array[Expression]): Unit = {
-
+  protected def asDataSetTableOperation[T](dataSet: DataSet[T], fields: Option[Array[Expression]])
+    : DataSetTableOperation[T] = {
     val inputType = dataSet.getType
 
-    val fieldsInfo = getFieldsInfo[T](
-      inputType,
-      fields)
+    val fieldsInfo = fields match {
+      case Some(f) =>
+        if (f.exists(f =>
+          f.isInstanceOf[CallExpression] &&
+            TIME_ATTRIBUTES.contains(f.asInstanceOf[CallExpression].getFunctionDefinition))) {
+          throw new ValidationException(
+            ".rowtime and .proctime time indicators are not allowed in a batch environment.")
+        }
 
-    if (fields.exists(f =>
-      f.isInstanceOf[CallExpression] &&
-        TIME_ATTRIBUTES.contains(f.asInstanceOf[CallExpression].getFunctionDefinition))) {
-      throw new ValidationException(
-        ".rowtime and .proctime time indicators are not allowed in a batch environment.")
+        getFieldsInfo[T](inputType, f)
+      case None => getFieldsInfo[T](inputType)
     }
 
-    val dataSetTable = new DataSetTable[T](dataSet, fieldsInfo.getIndices, fieldsInfo.getFieldNames)
-    registerTableInternal(name, dataSetTable)
+    val tableOperation = new DataSetTableOperation[T](dataSet,
+      fieldsInfo.getIndices,
+      calculateTableSchema(inputType, fieldsInfo.getIndices, fieldsInfo.getFieldNames))
+    tableOperation
   }
 
   /**
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/StreamTableEnvImpl.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/StreamTableEnvImpl.scala
index 40ecada..5c96e7a 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/StreamTableEnvImpl.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/StreamTableEnvImpl.scala
@@ -41,6 +41,7 @@ import org.apache.flink.table.catalog.CatalogManager
 import org.apache.flink.table.descriptors.{ConnectorDescriptor, StreamTableDescriptor}
 import org.apache.flink.table.explain.PlanJsonParser
 import org.apache.flink.table.expressions._
+import org.apache.flink.table.operations.DataStreamTableOperation
 import org.apache.flink.table.plan.nodes.FlinkConventions
 import org.apache.flink.table.plan.nodes.datastream.{DataStreamRel, UpdateAsRetractionTrait}
 import org.apache.flink.table.plan.rules.FlinkRuleSets
@@ -51,8 +52,8 @@ import org.apache.flink.table.runtime.types.{CRow, CRowTypeInfo}
 import org.apache.flink.table.runtime.{CRowMapRunner, OutputRowtimeProcessFunction}
 import org.apache.flink.table.sinks._
 import org.apache.flink.table.sources.{StreamTableSource, TableSource, TableSourceUtil}
+import org.apache.flink.table.typeutils.FieldInfoUtils.{calculateTableSchema, getFieldsInfo, isReferenceByPosition}
 import org.apache.flink.table.typeutils.{TimeIndicatorTypeInfo, TypeCheckUtils}
-import org.apache.flink.table.typeutils.FieldInfoUtils.{getFieldsInfo, isReferenceByPosition}
 
 import _root_.scala.collection.JavaConverters._
 
@@ -136,7 +137,7 @@ abstract class StreamTableEnvImpl(
               val enrichedTable = new TableSourceSinkTable(
                 Some(new StreamTableSourceTable(streamTableSource)),
                 table.tableSinkTable)
-              replaceRegisteredTable(name, enrichedTable)
+              replaceRegisteredTableSourceSinkInternal(name, enrichedTable)
           }
 
           // no table is registered
@@ -144,7 +145,7 @@ abstract class StreamTableEnvImpl(
             val newTable = new TableSourceSinkTable(
               Some(new StreamTableSourceTable(streamTableSource)),
               None)
-            registerTableInternal(name, newTable)
+            registerTableSourceSinkInternal(name, newTable)
         }
 
       // not a stream table source
@@ -215,7 +216,7 @@ abstract class StreamTableEnvImpl(
               val enrichedTable = new TableSourceSinkTable(
                 table.tableSourceTable,
                 Some(new TableSinkTable(configuredSink)))
-              replaceRegisteredTable(name, enrichedTable)
+              replaceRegisteredTableSourceSinkInternal(name, enrichedTable)
           }
 
           // no table is registered
@@ -223,7 +224,7 @@ abstract class StreamTableEnvImpl(
             val newTable = new TableSourceSinkTable(
               None,
               Some(new TableSinkTable(configuredSink)))
-            registerTableInternal(name, newTable)
+            registerTableSourceSinkInternal(name, newTable)
         }
 
       // not a stream table sink
@@ -432,67 +433,48 @@ abstract class StreamTableEnvImpl(
       }
   }
 
-  /**
-    * Registers a [[DataStream]] as a table under a given name in the [[TableEnvImpl]]'s
-    * catalog.
-    *
-    * @param name The name under which the table is registered in the catalog.
-    * @param dataStream The [[DataStream]] to register as table in the catalog.
-    * @tparam T the type of the [[DataStream]].
-    */
-  protected def registerDataStreamInternal[T](
-    name: String,
-    dataStream: DataStream[T]): Unit = {
-
-    val fieldInfo = getFieldsInfo[T](dataStream.getType)
-    val dataStreamTable = new DataStreamTable[T](
-      dataStream,
-      fieldInfo.getIndices,
-      fieldInfo.getFieldNames
-    )
-    registerTableInternal(name, dataStreamTable)
-  }
-
-  /**
-    * Registers a [[DataStream]] as a table under a given name with field names as specified by
-    * field expressions in the [[TableEnvImpl]]'s catalog.
-    *
-    * @param name The name under which the table is registered in the catalog.
-    * @param dataStream The [[DataStream]] to register as table in the catalog.
-    * @param fields The field expressions to define the field names of the table.
-    * @tparam T The type of the [[DataStream]].
-    */
-  protected def registerDataStreamInternal[T](
-      name: String,
+  protected def asTableOperation[T](
       dataStream: DataStream[T],
-      fields: Array[Expression])
-    : Unit = {
-
+      fields: Option[Array[Expression]])
+    : DataStreamTableOperation[T] = {
     val streamType = dataStream.getType
 
     // get field names and types for all non-replaced fields
-    val fieldsInfo = getFieldsInfo[T](streamType, fields)
-
-    // validate and extract time attributes
-    val (rowtime, proctime) = validateAndExtractTimeAttributes(streamType, fields)
+    val (indices, names) = fields match {
+      case Some(f) =>
+        // validate and extract time attributes
+        val fieldsInfo = getFieldsInfo[T](streamType, f)
+        val (rowtime, proctime) = validateAndExtractTimeAttributes(streamType, f)
+
+        // check if event-time is enabled
+        if (rowtime.isDefined &&
+          execEnv.getStreamTimeCharacteristic != TimeCharacteristic.EventTime) {
+          throw new TableException(
+            s"A rowtime attribute requires an EventTime time characteristic in stream environment" +
+              s". But is: ${execEnv.getStreamTimeCharacteristic}")
+        }
 
-    // check if event-time is enabled
-    if (rowtime.isDefined && execEnv.getStreamTimeCharacteristic != TimeCharacteristic.EventTime) {
-      throw new TableException(
-        s"A rowtime attribute requires an EventTime time characteristic in stream environment. " +
-          s"But is: ${execEnv.getStreamTimeCharacteristic}")
+        // adjust field indexes and field names
+        val indexesWithIndicatorFields = adjustFieldIndexes(
+          fieldsInfo.getIndices,
+          rowtime,
+          proctime)
+        val namesWithIndicatorFields = adjustFieldNames(
+          fieldsInfo.getFieldNames,
+          rowtime,
+          proctime)
+
+        (indexesWithIndicatorFields, namesWithIndicatorFields)
+      case None =>
+        val fieldsInfo = getFieldsInfo[T](streamType)
+        (fieldsInfo.getIndices, fieldsInfo.getFieldNames)
     }
 
-    // adjust field indexes and field names
-    val indexesWithIndicatorFields = adjustFieldIndexes(fieldsInfo.getIndices, rowtime, proctime)
-    val namesWithIndicatorFields = adjustFieldNames(fieldsInfo.getFieldNames, rowtime, proctime)
-
-    val dataStreamTable = new DataStreamTable[T](
+    val dataStreamTable = new DataStreamTableOperation(
       dataStream,
-      indexesWithIndicatorFields,
-      namesWithIndicatorFields
-    )
-    registerTableInternal(name, dataStreamTable)
+      indices,
+      calculateTableSchema(streamType, indices, names))
+    dataStreamTable
   }
 
   /**
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/TableEnvImpl.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/TableEnvImpl.scala
index 5dd46cc..7f329db 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/TableEnvImpl.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/TableEnvImpl.scala
@@ -18,7 +18,6 @@
 
 package org.apache.flink.table.api
 
-import _root_.java.lang.reflect.Modifier
 import _root_.java.util.Optional
 import _root_.java.util.concurrent.atomic.AtomicInteger
 
@@ -30,7 +29,6 @@ import org.apache.calcite.plan._
 import org.apache.calcite.plan.hep.{HepMatchOrder, HepPlanner, HepProgram, HepProgramBuilder}
 import org.apache.calcite.rel.RelNode
 import org.apache.calcite.schema.SchemaPlus
-import org.apache.calcite.schema.impl.AbstractTable
 import org.apache.calcite.sql._
 import org.apache.calcite.sql.parser.SqlParser
 import org.apache.calcite.tools._
@@ -47,7 +45,7 @@ import org.apache.flink.table.functions.{AggregateFunction, ScalarFunction, Tabl
 import org.apache.flink.table.operations.{CatalogTableOperation, OperationTreeBuilder, PlannerTableOperation}
 import org.apache.flink.table.plan.nodes.FlinkConventions
 import org.apache.flink.table.plan.rules.FlinkRuleSets
-import org.apache.flink.table.plan.schema.{RelTable, RowSchema, TableSourceSinkTable}
+import org.apache.flink.table.plan.schema.{RowSchema, TableSourceSinkTable}
 import org.apache.flink.table.planner.PlanningConfigurationBuilder
 import org.apache.flink.table.sinks.TableSink
 import org.apache.flink.table.sources.TableSource
@@ -326,12 +324,6 @@ abstract class TableEnvImpl(
     output
   }
 
-  override def fromTableSource(source: TableSource[_]): Table = {
-    val name = createUniqueTableName()
-    registerTableSourceInternal(name, source)
-    scan(name)
-  }
-
   override def registerExternalCatalog(name: String, externalCatalog: ExternalCatalog): Unit = {
     catalogManager.registerExternalCatalog(name, externalCatalog)
   }
@@ -404,24 +396,6 @@ abstract class TableEnvImpl(
       planningConfigurationBuilder.getTypeFactory)
   }
 
-  override def registerTable(name: String, table: Table): Unit = {
-
-    // check that table belongs to this table environment
-    if (table.asInstanceOf[TableImpl].tableEnv != this) {
-      throw new TableException(
-        "Only tables that belong to this TableEnvironment can be registered.")
-    }
-
-    checkValidTableName(name)
-    val tableTable = new RelTable(table.asInstanceOf[TableImpl].getRelNode)
-    registerTableInternal(name, tableTable)
-  }
-
-  override def registerTableSource(name: String, tableSource: TableSource[_]): Unit = {
-    checkValidTableName(name)
-    registerTableSourceInternal(name, tableSource)
-  }
-
   override def registerCatalog(catalogName: String, catalog: Catalog): Unit = {
     catalogManager.registerCatalog(catalogName, catalog)
   }
@@ -446,24 +420,57 @@ abstract class TableEnvImpl(
     catalogManager.setCurrentDatabase(databaseName)
   }
 
-  /**
-    * Registers an internal [[TableSource]] in this [[TableEnvironment]]'s catalog without
-    * name checking. Registered tables can be referenced in SQL queries.
-    *
-    * @param name        The name under which the [[TableSource]] is registered.
-    * @param tableSource The [[TableSource]] to register.
-    */
+  override def registerTable(name: String, table: Table): Unit = {
+
+    // check that table belongs to this table environment
+    if (table.asInstanceOf[TableImpl].tableEnv != this) {
+      throw new TableException(
+        "Only tables that belong to this TableEnvironment can be registered.")
+    }
+
+    checkValidTableName(name)
+
+    val tableTable = new TableOperationCatalogView(table.getTableOperation)
+    registerTableInternal(name, tableTable)
+  }
+
+  override def registerTableSource(name: String, tableSource: TableSource[_]): Unit = {
+    registerTableSourceInternal(name, tableSource)
+  }
+
+  override def fromTableSource(source: TableSource[_]): Table = {
+    val name = createUniqueTableName()
+    registerTableSourceInternal(name, source)
+    scan(name)
+  }
+
+  protected def registerTableInternal(name: String, table: CatalogBaseTable): Unit = {
+    val path = new ObjectPath(defaultDatabaseName, name)
+    JavaScalaConversionUtil.toScala(catalogManager.getCatalog(defaultCatalogName)) match {
+      case Some(catalog) =>
+        catalog.createTable(
+          path,
+          table,
+          false)
+      case None => throw new TableException("The default catalog does not exist.")
+    }
+  }
+
   protected def registerTableSourceInternal(name: String, tableSource: TableSource[_]): Unit
 
-  /**
-    * Replaces a registered Table with another Table under the same name.
-    * We use this method to replace a [[org.apache.flink.table.plan.schema.DataStreamTable]]
-    * with a [[org.apache.calcite.schema.TranslatableTable]].
-    *
-    * @param name Name of the table to replace.
-    * @param table The table that replaces the previous table.
-    */
-  protected def replaceRegisteredTable(name: String, table: AbstractTable): Unit = {
+  protected def registerTableSourceSinkInternal[T1, T2](
+      name: String,
+      table: TableSourceSinkTable[T1, T2])
+    : Unit = {
+    registerTableInternal(
+      name,
+      new CalciteCatalogTable(table, planningConfigurationBuilder.getTypeFactory))
+  }
+
+  protected def replaceRegisteredTableSourceSinkInternal[T1, T2](
+      name: String,
+      table: TableSourceSinkTable[T1, T2])
+    : Unit = {
     val path = new ObjectPath(defaultDatabaseName, name)
     JavaScalaConversionUtil.toScala(catalogManager.getCatalog(defaultCatalogName)) match {
       case Some(catalog) =>
@@ -617,26 +624,6 @@ abstract class TableEnvImpl(
     }
   }
 
-  /**
-    * Registers a Calcite [[AbstractTable]] in the TableEnvironment's default catalog.
-    *
-    * @param name The name under which the table will be registered.
-    * @param table The table to register in the catalog
-    * @throws TableException if another table is registered under the provided name.
-    */
-  @throws[TableException]
-  protected def registerTableInternal(name: String, table: AbstractTable): Unit = {
-    val path = new ObjectPath(defaultDatabaseName, name)
-    JavaScalaConversionUtil.toScala(catalogManager.getCatalog(defaultCatalogName)) match {
-      case Some(catalog) =>
-        catalog.createTable(
-          path,
-          new CalciteCatalogTable(table, planningConfigurationBuilder.getTypeFactory),
-          false)
-      case None => throw new TableException("The default catalog does not exist.")
-    }
-  }
-
   /** Returns a unique table name according to the internal naming pattern. */
   protected def createUniqueTableName(): String
 
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/java/BatchTableEnvImpl.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/java/BatchTableEnvImpl.scala
index ddd2fd9..9d2de41 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/java/BatchTableEnvImpl.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/java/BatchTableEnvImpl.scala
@@ -45,10 +45,7 @@ class BatchTableEnvImpl(
   with org.apache.flink.table.api.java.BatchTableEnvironment {
 
   override def fromDataSet[T](dataSet: DataSet[T]): Table = {
-
-    val name = createUniqueTableName()
-    registerDataSetInternal(name, dataSet)
-    scan(name)
+    new TableImpl(this, asDataSetTableOperation(dataSet, None))
   }
 
   override def fromDataSet[T](dataSet: DataSet[T], fields: String): Table = {
@@ -56,24 +53,15 @@ class BatchTableEnvImpl(
       .parseExpressionList(fields).asScala
       .toArray
 
-    val name = createUniqueTableName()
-    registerDataSetInternal(name, dataSet, exprs)
-    scan(name)
+    new TableImpl(this, asDataSetTableOperation(dataSet, Some(exprs)))
   }
 
   override def registerDataSet[T](name: String, dataSet: DataSet[T]): Unit = {
-
-    checkValidTableName(name)
-    registerDataSetInternal(name, dataSet)
+    registerTable(name, fromDataSet(dataSet))
   }
 
   override def registerDataSet[T](name: String, dataSet: DataSet[T], fields: String): Unit = {
-    val exprs = ExpressionParser
-      .parseExpressionList(fields).asScala
-      .toArray
-
-    checkValidTableName(name)
-    registerDataSetInternal(name, dataSet, exprs)
+    registerTable(name, fromDataSet(dataSet, fields))
   }
 
   override def toDataSet[T](table: Table, clazz: Class[T]): DataSet[T] = {
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/java/StreamTableEnvImpl.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/java/StreamTableEnvImpl.scala
index 235370e..108c201 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/java/StreamTableEnvImpl.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/java/StreamTableEnvImpl.scala
@@ -50,10 +50,7 @@ class StreamTableEnvImpl(
   with org.apache.flink.table.api.java.StreamTableEnvironment {
 
   override def fromDataStream[T](dataStream: DataStream[T]): Table = {
-
-    val name = createUniqueTableName()
-    registerDataStreamInternal(name, dataStream)
-    scan(name)
+    new TableImpl(this, asTableOperation(dataStream, None))
   }
 
   override def fromDataStream[T](dataStream: DataStream[T], fields: String): Table = {
@@ -61,26 +58,19 @@ class StreamTableEnvImpl(
       .parseExpressionList(fields).asScala
       .toArray
 
-    val name = createUniqueTableName()
-    registerDataStreamInternal(name, dataStream, exprs)
-    scan(name)
+    new TableImpl(this, asTableOperation(dataStream, Some(exprs)))
   }
 
   override def registerDataStream[T](name: String, dataStream: DataStream[T]): Unit = {
-
-    checkValidTableName(name)
-    registerDataStreamInternal(name, dataStream)
+    registerTable(name, fromDataStream(dataStream))
   }
 
   override def registerDataStream[T](
-    name: String, dataStream: DataStream[T], fields: String): Unit = {
-
-    val exprs = ExpressionParser
-      .parseExpressionList(fields).asScala
-      .toArray
-
-    checkValidTableName(name)
-    registerDataStreamInternal(name, dataStream, exprs)
+      name: String,
+      dataStream: DataStream[T],
+      fields: String)
+    : Unit = {
+    registerTable(name, fromDataStream(dataStream, fields))
   }
 
   override def toAppendStream[T](table: Table, clazz: Class[T]): DataStream[T] = {
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/scala/BatchTableEnvImpl.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/scala/BatchTableEnvImpl.scala
index 3c2e589..ca74712 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/scala/BatchTableEnvImpl.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/scala/BatchTableEnvImpl.scala
@@ -44,29 +44,19 @@ class BatchTableEnvImpl(
   with org.apache.flink.table.api.scala.BatchTableEnvironment {
 
   override def fromDataSet[T](dataSet: DataSet[T]): Table = {
-
-    val name = createUniqueTableName()
-    registerDataSetInternal(name, dataSet.javaSet)
-    scan(name)
+    new TableImpl(this, asDataSetTableOperation(dataSet.javaSet, None))
   }
 
   override def fromDataSet[T](dataSet: DataSet[T], fields: Expression*): Table = {
-
-    val name = createUniqueTableName()
-    registerDataSetInternal(name, dataSet.javaSet, fields.toArray)
-    scan(name)
+    new TableImpl(this, asDataSetTableOperation(dataSet.javaSet, Some(fields.toArray)))
   }
 
   override def registerDataSet[T](name: String, dataSet: DataSet[T]): Unit = {
-
-    checkValidTableName(name)
-    registerDataSetInternal(name, dataSet.javaSet)
+    registerTable(name, fromDataSet(dataSet))
   }
 
   override def registerDataSet[T](name: String, dataSet: DataSet[T], fields: Expression*): Unit = {
-
-    checkValidTableName(name)
-    registerDataSetInternal(name, dataSet.javaSet, fields.toArray)
+    registerTable(name, fromDataSet(dataSet, fields: _*))
   }
 
   override def toDataSet[T: TypeInformation](table: Table): DataSet[T] = {
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/scala/StreamTableEnvImpl.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/scala/StreamTableEnvImpl.scala
index b1805cf..45bbec2 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/scala/StreamTableEnvImpl.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/api/scala/StreamTableEnvImpl.scala
@@ -17,14 +17,13 @@
  */
 package org.apache.flink.table.api.scala
 
-import org.apache.flink.api.scala._
 import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.table.api.{StreamQueryConfig, Table, TableConfig, TableEnvImpl}
+import org.apache.flink.api.scala._
+import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment, asScalaStream}
+import org.apache.flink.table.api.{StreamQueryConfig, Table, TableConfig, TableImpl}
+import org.apache.flink.table.catalog.CatalogManager
 import org.apache.flink.table.expressions.Expression
 import org.apache.flink.table.functions.{AggregateFunction, TableAggregateFunction, TableFunction}
-import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
-import org.apache.flink.streaming.api.scala.asScalaStream
-import org.apache.flink.table.catalog.CatalogManager
 
 /**
   * The implementation for a Scala [[StreamTableEnvironment]].
@@ -43,30 +42,25 @@ class StreamTableEnvImpl(
   with org.apache.flink.table.api.scala.StreamTableEnvironment {
 
   override def fromDataStream[T](dataStream: DataStream[T]): Table = {
-
-    val name = createUniqueTableName()
-    registerDataStreamInternal(name, dataStream.javaStream)
-    scan(name)
+    val tableOperation = asTableOperation(dataStream.javaStream, None)
+    new TableImpl(this, tableOperation)
   }
 
   override def fromDataStream[T](dataStream: DataStream[T], fields: Expression*): Table = {
-
-    val name = createUniqueTableName()
-    registerDataStreamInternal(name, dataStream.javaStream, fields.toArray)
-    scan(name)
+    val tableOperation = asTableOperation(dataStream.javaStream, Some(fields.toArray))
+    new TableImpl(this, tableOperation)
   }
 
   override def registerDataStream[T](name: String, dataStream: DataStream[T]): Unit = {
-
-    checkValidTableName(name)
-    registerDataStreamInternal(name, dataStream.javaStream)
+    registerTable(name, fromDataStream(dataStream))
   }
 
   override def registerDataStream[T](
-    name: String, dataStream: DataStream[T], fields: Expression*): Unit = {
-
-    checkValidTableName(name)
-    registerDataStreamInternal(name, dataStream.javaStream, fields.toArray)
+      name: String,
+      dataStream: DataStream[T],
+      fields: Expression*)
+    : Unit = {
+    registerTable(name, fromDataStream(dataStream, fields: _*))
   }
 
   override def toAppendStream[T: TypeInformation](table: Table): DataStream[T] = {
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/calcite/FlinkRelBuilder.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/calcite/FlinkRelBuilder.scala
index 704d481..54962f5 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/calcite/FlinkRelBuilder.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/calcite/FlinkRelBuilder.scala
@@ -124,4 +124,14 @@ object FlinkRelBuilder {
     */
   case class NamedWindowProperty(name: String, property: WindowProperty)
 
+  def of(cluster: RelOptCluster, relTable: RelOptTable): FlinkRelBuilder = {
+    val clusterContext = cluster.getPlanner.getContext
+
+    new FlinkRelBuilder(
+      clusterContext,
+      cluster,
+      relTable.getRelOptSchema,
+      clusterContext.unwrap(classOf[ExpressionBridge[PlannerExpression]]))
+  }
+
 }
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/calcite/FlinkTypeFactory.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/calcite/FlinkTypeFactory.scala
index c48967b..f84a908 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/calcite/FlinkTypeFactory.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/calcite/FlinkTypeFactory.scala
@@ -34,7 +34,7 @@ import org.apache.flink.api.common.typeinfo._
 import org.apache.flink.api.common.typeutils.CompositeType
 import org.apache.flink.api.java.typeutils.ValueTypeInfo._
 import org.apache.flink.api.java.typeutils.{MapTypeInfo, MultisetTypeInfo, ObjectArrayTypeInfo, RowTypeInfo}
-import org.apache.flink.table.api.TableException
+import org.apache.flink.table.api.{TableException, TableSchema}
 import org.apache.flink.table.calcite.FlinkTypeFactory.typeInfoToSqlTypeName
 import org.apache.flink.table.plan.schema._
 import org.apache.flink.table.typeutils.TypeCheckUtils.isSimple
@@ -181,6 +181,16 @@ class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImp
   /**
     * Creates a struct type with the input fieldNames and input fieldTypes using FlinkTypeFactory
     *
+    * @param tableSchema schema to convert to Calcite's specific one
+    * @return a struct type with the input fieldNames, input fieldTypes, and system fields
+    */
+  def buildLogicalRowType(tableSchema: TableSchema): RelDataType = {
+    buildLogicalRowType(tableSchema.getFieldNames, tableSchema.getFieldTypes)
+  }
+
+  /**
+    * Creates a struct type with the input fieldNames and input fieldTypes using FlinkTypeFactory
+    *
     * @param fieldNames field names
     * @param fieldTypes field types, every element is Flink's [[TypeInformation]]
     * @return a struct type with the input fieldNames, input fieldTypes, and system fields
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java
index 7c5019d..690e70f 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/operations/PlannerTableOperation.java
@@ -33,7 +33,7 @@ import java.util.List;
  * Wrapper for valid logical plans generated by Planner.
  */
 @Internal
-public class PlannerTableOperation implements TableOperation {
+public class PlannerTableOperation extends TableOperation {
 
 	private final RelNode calciteTree;
 	private final TableSchema tableSchema;
@@ -60,6 +60,11 @@ public class PlannerTableOperation implements TableOperation {
 	}
 
 	@Override
+	public String asSummaryString() {
+		return formatWithChildren("PlannerNode", Collections.emptyMap());
+	}
+
+	@Override
 	public List<TableOperation> getChildren() {
 		return Collections.emptyList();
 	}
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/dataset/BatchScan.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/dataset/BatchScan.scala
index 85152d8..71536d9 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/dataset/BatchScan.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/dataset/BatchScan.scala
@@ -32,9 +32,9 @@ import org.apache.flink.types.Row
 
 trait BatchScan extends CommonScan[Row] with DataSetRel {
 
-  protected def convertToInternalRow(
+  protected def convertToInternalRow[T](
       schema: RowSchema,
-      input: DataSet[Any],
+      input: DataSet[T],
       fieldIdxs: Array[Int],
       config: TableConfig,
       rowtimeExpression: Option[RexNode]): DataSet[Row] = {
@@ -58,7 +58,7 @@ trait BatchScan extends CommonScan[Row] with DataSetRel {
         fieldIdxs,
         rowtimeExpression)
 
-      val runner = new MapRunner[Any, Row](
+      val runner = new MapRunner[T, Row](
         function.name,
         function.code,
         function.returnType)
@@ -75,12 +75,12 @@ trait BatchScan extends CommonScan[Row] with DataSetRel {
 
   private def generateConversionMapper(
       config: TableConfig,
-      inputType: TypeInformation[Any],
+      inputType: TypeInformation[_],
       outputType: TypeInformation[Row],
       conversionOperatorName: String,
       fieldNames: Seq[String],
       inputFieldMapping: Array[Int],
-      rowtimeExpression: Option[RexNode]): GeneratedFunction[MapFunction[Any, Row], Row] = {
+      rowtimeExpression: Option[RexNode]): GeneratedFunction[MapFunction[_, Row], Row] = {
 
     val generator = new FunctionCodeGenerator(
       config,
@@ -102,7 +102,7 @@ trait BatchScan extends CommonScan[Row] with DataSetRel {
 
     generator.generateFunction(
       "DataSetSourceConversion",
-      classOf[MapFunction[Any, Row]],
+      classOf[MapFunction[_, Row]],
       body,
       outputType)
   }
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/dataset/DataSetScan.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/dataset/DataSetScan.scala
index 07c5059..160f27c 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/dataset/DataSetScan.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/dataset/DataSetScan.scala
@@ -19,32 +19,45 @@
 package org.apache.flink.table.plan.nodes.dataset
 
 import org.apache.calcite.plan._
-import org.apache.calcite.rel.RelNode
+import org.apache.calcite.prepare.RelOptTableImpl
 import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.rel.core.TableScan
 import org.apache.calcite.rel.metadata.RelMetadataQuery
+import org.apache.calcite.rel.{RelNode, RelWriter}
 import org.apache.flink.api.java.DataSet
 import org.apache.flink.table.api.{BatchQueryConfig, BatchTableEnvImpl}
-import org.apache.flink.table.plan.schema.{DataSetTable, RowSchema}
+import org.apache.flink.table.plan.schema.RowSchema
 import org.apache.flink.types.Row
 
+import scala.collection.JavaConverters._
+
 /**
   * Flink RelNode which matches along with DataSource.
   * It ensures that types without deterministic field order (e.g. POJOs) are not part of
   * the plan translation.
+  *
+  * This may read only part, or change the order of the fields available in a
+  * [[org.apache.flink.api.common.typeutils.CompositeType]] of the underlying [[DataSet]].
+  * The fieldIdxs describe the indices of the fields in the
+  * [[org.apache.flink.api.common.typeinfo.TypeInformation]]
   */
 class DataSetScan(
     cluster: RelOptCluster,
     traitSet: RelTraitSet,
-    table: RelOptTable,
+    catalog: RelOptSchema,
+    inputDataSet: DataSet[_],
+    fieldIdxs: Array[Int],
     rowRelDataType: RelDataType)
-  extends TableScan(cluster, traitSet, table)
+  extends TableScan(
+    cluster,
+    traitSet,
+    RelOptTableImpl.create(catalog, rowRelDataType, List[String]().asJava, null))
   with BatchScan {
 
-  val dataSetTable: DataSetTable[Any] = getTable.unwrap(classOf[DataSetTable[Any]])
-
   override def deriveRowType(): RelDataType = rowRelDataType
 
+  override def estimateRowCount(mq: RelMetadataQuery): Double = 1000L
+
   override def computeSelfCost(planner: RelOptPlanner, metadata: RelMetadataQuery): RelOptCost = {
     val rowCnt = metadata.getRowCount(this)
     planner.getCostFactory.makeCost(rowCnt, rowCnt, 0)
@@ -54,7 +67,9 @@ class DataSetScan(
     new DataSetScan(
       cluster,
       traitSet,
-      getTable,
+      catalog,
+      inputDataSet,
+      fieldIdxs,
       getRowType
     )
   }
@@ -63,10 +78,11 @@ class DataSetScan(
       tableEnv: BatchTableEnvImpl,
       queryConfig: BatchQueryConfig): DataSet[Row] = {
     val schema = new RowSchema(rowRelDataType)
-    val inputDataSet: DataSet[Any] = dataSetTable.dataSet
-    val fieldIdxs = dataSetTable.fieldIndexes
     val config = tableEnv.getConfig
-    convertToInternalRow(schema, inputDataSet, fieldIdxs, config, None)
+    convertToInternalRow(schema, inputDataSet.asInstanceOf[DataSet[Any]], fieldIdxs, config, None)
   }
 
+  override def explainTerms(pw: RelWriter): RelWriter = pw
+    .item("ref", System.identityHashCode(inputDataSet))
+    .item("fields", String.join(", ", rowRelDataType.getFieldNames))
 }
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/datastream/DataStreamScan.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/datastream/DataStreamScan.scala
index 6587444..9fc6ef7 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/datastream/DataStreamScan.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/datastream/DataStreamScan.scala
@@ -19,40 +19,52 @@
 package org.apache.flink.table.plan.nodes.datastream
 
 import org.apache.calcite.plan._
-import org.apache.calcite.rel.RelNode
+import org.apache.calcite.prepare.RelOptTableImpl
 import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.rel.core.TableScan
+import org.apache.calcite.rel.{RelNode, RelWriter}
 import org.apache.calcite.rex.RexNode
 import org.apache.flink.streaming.api.datastream.DataStream
 import org.apache.flink.table.api.{StreamQueryConfig, StreamTableEnvImpl}
 import org.apache.flink.table.expressions.Cast
 import org.apache.flink.table.plan.schema.RowSchema
-import org.apache.flink.table.plan.schema.DataStreamTable
 import org.apache.flink.table.runtime.types.CRow
 import org.apache.flink.table.typeutils.TimeIndicatorTypeInfo
 
+import scala.collection.JavaConverters._
+
 /**
   * Flink RelNode which matches along with DataStreamSource.
   * It ensures that types without deterministic field order (e.g. POJOs) are not part of
   * the plan translation.
+  *
+  * This may read only part, or change the order of the fields available in a
+  * [[org.apache.flink.api.common.typeutils.CompositeType]] of the underlying [[DataStream]].
+  * The fieldIdxs describe the indices of the fields in the
+  * [[org.apache.flink.api.common.typeinfo.TypeInformation]]
   */
 class DataStreamScan(
     cluster: RelOptCluster,
     traitSet: RelTraitSet,
-    table: RelOptTable,
+    catalog: RelOptSchema,
+    dataStream: DataStream[_],
+    fieldIdxs: Array[Int],
     schema: RowSchema)
-  extends TableScan(cluster, traitSet, table)
+  extends TableScan(
+    cluster,
+    traitSet,
+    RelOptTableImpl.create(catalog, schema.relDataType, List[String]().asJava, null))
   with StreamScan {
 
-  val dataStreamTable: DataStreamTable[Any] = getTable.unwrap(classOf[DataStreamTable[Any]])
-
   override def deriveRowType(): RelDataType = schema.relDataType
 
   override def copy(traitSet: RelTraitSet, inputs: java.util.List[RelNode]): RelNode = {
     new DataStreamScan(
       cluster,
       traitSet,
-      getTable,
+      catalog,
+      dataStream,
+      fieldIdxs,
       schema
     )
   }
@@ -62,8 +74,6 @@ class DataStreamScan(
       queryConfig: StreamQueryConfig): DataStream[CRow] = {
 
     val config = tableEnv.getConfig
-    val inputDataStream: DataStream[Any] = dataStreamTable.dataStream
-    val fieldIdxs = dataStreamTable.fieldIndexes
 
     // get expression to extract timestamp
     val rowtimeExpr: Option[RexNode] =
@@ -79,7 +89,15 @@ class DataStreamScan(
       }
 
     // convert DataStream
-    convertToInternalRow(schema, inputDataStream, fieldIdxs, config, rowtimeExpr)
+    convertToInternalRow(
+      schema,
+      dataStream.asInstanceOf[DataStream[Any]],
+      fieldIdxs,
+      config,
+      rowtimeExpr)
   }
 
+  override def explainTerms(pw: RelWriter): RelWriter =
+    pw.item("id", s"${dataStream.getId}")
+      .item("fields", s"${String.join(", ", schema.relDataType.getFieldNames)}")
 }
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalNativeTableScan.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalDataSetScan.scala
similarity index 52%
copy from flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalNativeTableScan.scala
copy to flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalDataSetScan.scala
index fe4b2b6..16af21d 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalNativeTableScan.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalDataSetScan.scala
@@ -21,56 +21,43 @@ package org.apache.flink.table.plan.nodes.logical
 import java.util
 
 import org.apache.calcite.plan._
-import org.apache.calcite.rel.RelNode
-import org.apache.calcite.rel.convert.ConverterRule
+import org.apache.calcite.prepare.RelOptTableImpl
+import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.rel.core.TableScan
-import org.apache.calcite.rel.logical.LogicalTableScan
 import org.apache.calcite.rel.metadata.RelMetadataQuery
-import org.apache.flink.table.plan.nodes.FlinkConventions
-import org.apache.flink.table.plan.schema.{DataSetTable, DataStreamTable}
+import org.apache.calcite.rel.{RelNode, RelWriter}
+import org.apache.flink.api.java.DataSet
 
-class FlinkLogicalNativeTableScan (
+import scala.collection.JavaConverters._
+
+class FlinkLogicalDataSetScan(
     cluster: RelOptCluster,
     traitSet: RelTraitSet,
-    table: RelOptTable)
-  extends TableScan(cluster, traitSet, table)
+    val catalog: RelOptSchema,
+    val dataSet: DataSet[_],
+    val fieldIdxs: Array[Int],
+    val schema: RelDataType)
+  extends TableScan(
+    cluster,
+    traitSet,
+    RelOptTableImpl.create(catalog, schema, List[String]().asJava, null))
   with FlinkLogicalRel {
 
+
+  override def estimateRowCount(mq: RelMetadataQuery): Double = 1000L
+
+  override def deriveRowType(): RelDataType = schema
+
   override def copy(traitSet: RelTraitSet, inputs: util.List[RelNode]): RelNode = {
-    new FlinkLogicalNativeTableScan(cluster, traitSet, getTable)
+    new FlinkLogicalDataSetScan(cluster, traitSet, catalog, dataSet, fieldIdxs, schema)
   }
 
   override def computeSelfCost(planner: RelOptPlanner, metadata: RelMetadataQuery): RelOptCost = {
     val rowCnt = metadata.getRowCount(this)
     planner.getCostFactory.makeCost(rowCnt, rowCnt, rowCnt * estimateRowSize(getRowType))
   }
-}
-
-class FlinkLogicalNativeTableScanConverter
-  extends ConverterRule(
-    classOf[LogicalTableScan],
-    Convention.NONE,
-    FlinkConventions.LOGICAL,
-    "FlinkLogicalNativeTableScanConverter") {
-
-  override def matches(call: RelOptRuleCall): Boolean = {
-    val scan = call.rel[TableScan](0)
-    val dataSetTable = scan.getTable.unwrap(classOf[DataSetTable[_]])
-    val dataStreamTable = scan.getTable.unwrap(classOf[DataStreamTable[_]])
-    dataSetTable != null || dataStreamTable != null
-  }
-
-  def convert(rel: RelNode): RelNode = {
-    val scan = rel.asInstanceOf[TableScan]
-    val traitSet = rel.getTraitSet.replace(FlinkConventions.LOGICAL)
-    new FlinkLogicalNativeTableScan(
-      rel.getCluster,
-      traitSet,
-      scan.getTable
-    )
-  }
-}
 
-object FlinkLogicalNativeTableScan {
-  val CONVERTER = new FlinkLogicalNativeTableScanConverter
+  override def explainTerms(pw: RelWriter): RelWriter = pw
+    .item("ref", System.identityHashCode(dataSet))
+    .item("fields", String.join(", ", schema.getFieldNames))
 }
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalNativeTableScan.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalDataStreamScan.scala
similarity index 52%
rename from flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalNativeTableScan.scala
rename to flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalDataStreamScan.scala
index fe4b2b6..4d7d815 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalNativeTableScan.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/nodes/logical/FlinkLogicalDataStreamScan.scala
@@ -21,56 +21,41 @@ package org.apache.flink.table.plan.nodes.logical
 import java.util
 
 import org.apache.calcite.plan._
-import org.apache.calcite.rel.RelNode
-import org.apache.calcite.rel.convert.ConverterRule
+import org.apache.calcite.prepare.RelOptTableImpl
+import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.rel.core.TableScan
-import org.apache.calcite.rel.logical.LogicalTableScan
 import org.apache.calcite.rel.metadata.RelMetadataQuery
-import org.apache.flink.table.plan.nodes.FlinkConventions
-import org.apache.flink.table.plan.schema.{DataSetTable, DataStreamTable}
+import org.apache.calcite.rel.{RelNode, RelWriter}
+import org.apache.flink.streaming.api.datastream.DataStream
+import org.apache.flink.table.plan.schema.RowSchema
 
-class FlinkLogicalNativeTableScan (
+import scala.collection.JavaConverters._
+
+class FlinkLogicalDataStreamScan(
     cluster: RelOptCluster,
     traitSet: RelTraitSet,
-    table: RelOptTable)
-  extends TableScan(cluster, traitSet, table)
+    val catalog: RelOptSchema,
+    val dataStream: DataStream[_],
+    val fieldIdxs: Array[Int],
+    val schema: RowSchema)
+  extends TableScan(
+    cluster,
+    traitSet,
+    RelOptTableImpl.create(catalog, schema.relDataType, List[String]().asJava, null))
   with FlinkLogicalRel {
 
+  override def deriveRowType(): RelDataType = schema.relDataType
+
   override def copy(traitSet: RelTraitSet, inputs: util.List[RelNode]): RelNode = {
-    new FlinkLogicalNativeTableScan(cluster, traitSet, getTable)
+    new FlinkLogicalDataStreamScan(cluster, traitSet, catalog, dataStream, fieldIdxs, schema)
   }
 
   override def computeSelfCost(planner: RelOptPlanner, metadata: RelMetadataQuery): RelOptCost = {
     val rowCnt = metadata.getRowCount(this)
     planner.getCostFactory.makeCost(rowCnt, rowCnt, rowCnt * estimateRowSize(getRowType))
   }
-}
-
-class FlinkLogicalNativeTableScanConverter
-  extends ConverterRule(
-    classOf[LogicalTableScan],
-    Convention.NONE,
-    FlinkConventions.LOGICAL,
-    "FlinkLogicalNativeTableScanConverter") {
-
-  override def matches(call: RelOptRuleCall): Boolean = {
-    val scan = call.rel[TableScan](0)
-    val dataSetTable = scan.getTable.unwrap(classOf[DataSetTable[_]])
-    val dataStreamTable = scan.getTable.unwrap(classOf[DataStreamTable[_]])
-    dataSetTable != null || dataStreamTable != null
-  }
-
-  def convert(rel: RelNode): RelNode = {
-    val scan = rel.asInstanceOf[TableScan]
-    val traitSet = rel.getTraitSet.replace(FlinkConventions.LOGICAL)
-    new FlinkLogicalNativeTableScan(
-      rel.getCluster,
-      traitSet,
-      scan.getTable
-    )
-  }
-}
 
-object FlinkLogicalNativeTableScan {
-  val CONVERTER = new FlinkLogicalNativeTableScanConverter
+  override def explainTerms(pw: RelWriter): RelWriter =
+    pw.item("id", s"${dataStream.getId}")
+      .item("fields", s"${String.join(", ", schema.relDataType.getFieldNames)}")
 }
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/FlinkRuleSets.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/FlinkRuleSets.scala
index 6dfa88a..b7701cd 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/FlinkRuleSets.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/FlinkRuleSets.scala
@@ -21,12 +21,11 @@ package org.apache.flink.table.plan.rules
 import org.apache.calcite.rel.core.RelFactories
 import org.apache.calcite.rel.rules._
 import org.apache.calcite.tools.{RuleSet, RuleSets}
-import org.apache.flink.table.plan.nodes.logical
+import org.apache.flink.table.plan.nodes.logical._
 import org.apache.flink.table.plan.rules.common._
-import org.apache.flink.table.plan.rules.logical.{ExtendedAggregateExtractProjectRule, _}
 import org.apache.flink.table.plan.rules.dataSet._
 import org.apache.flink.table.plan.rules.datastream._
-import org.apache.flink.table.plan.nodes.logical._
+import org.apache.flink.table.plan.rules.logical.{ExtendedAggregateExtractProjectRule, _}
 
 object FlinkRuleSets {
 
@@ -139,7 +138,6 @@ object FlinkRuleSets {
     FlinkLogicalValues.CONVERTER,
     FlinkLogicalTableSourceScan.CONVERTER,
     FlinkLogicalTableFunctionScan.CONVERTER,
-    FlinkLogicalNativeTableScan.CONVERTER,
     FlinkLogicalMatch.CONVERTER,
     FlinkLogicalTableAggregate.CONVERTER,
     FlinkLogicalWindowTableAggregate.CONVERTER
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/dataSet/DataSetScanRule.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/dataSet/DataSetScanRule.scala
index 4198819..b3aea29 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/dataSet/DataSetScanRule.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/dataSet/DataSetScanRule.scala
@@ -18,48 +18,35 @@
 
 package org.apache.flink.table.plan.rules.dataSet
 
-import org.apache.calcite.plan.{RelOptRule, RelOptRuleCall, RelTraitSet}
+import org.apache.calcite.plan.RelTraitSet
 import org.apache.calcite.rel.RelNode
 import org.apache.calcite.rel.convert.ConverterRule
 import org.apache.flink.table.plan.nodes.FlinkConventions
 import org.apache.flink.table.plan.nodes.dataset.DataSetScan
-import org.apache.flink.table.plan.schema.DataSetTable
-import org.apache.flink.table.plan.nodes.logical.FlinkLogicalNativeTableScan
+import org.apache.flink.table.plan.nodes.logical.FlinkLogicalDataSetScan
 
 class DataSetScanRule
   extends ConverterRule(
-    classOf[FlinkLogicalNativeTableScan],
+    classOf[FlinkLogicalDataSetScan],
     FlinkConventions.LOGICAL,
     FlinkConventions.DATASET,
     "DataSetScanRule") {
 
-  /**
-   * If the input is not a DataSetTable, we want the TableScanRule to match instead
-   */
-  override def matches(call: RelOptRuleCall): Boolean = {
-    val scan: FlinkLogicalNativeTableScan = call.rel(0).asInstanceOf[FlinkLogicalNativeTableScan]
-    val dataSetTable = scan.getTable.unwrap(classOf[DataSetTable[Any]])
-    dataSetTable match {
-      case _: DataSetTable[Any] =>
-        true
-      case _ =>
-        false
-    }
-  }
-
   def convert(rel: RelNode): RelNode = {
-    val scan: FlinkLogicalNativeTableScan = rel.asInstanceOf[FlinkLogicalNativeTableScan]
+    val scan: FlinkLogicalDataSetScan = rel.asInstanceOf[FlinkLogicalDataSetScan]
     val traitSet: RelTraitSet = rel.getTraitSet.replace(FlinkConventions.DATASET)
 
     new DataSetScan(
       rel.getCluster,
       traitSet,
-      scan.getTable,
-      rel.getRowType
+      scan.catalog,
+      scan.dataSet,
+      scan.fieldIdxs,
+      scan.schema
     )
   }
 }
 
 object DataSetScanRule {
-  val INSTANCE: RelOptRule = new DataSetScanRule
+  val INSTANCE = new DataSetScanRule
 }
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/datastream/DataStreamScanRule.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/datastream/DataStreamScanRule.scala
index d8dda80..44f97fe 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/datastream/DataStreamScanRule.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/datastream/DataStreamScanRule.scala
@@ -18,46 +18,38 @@
 
 package org.apache.flink.table.plan.rules.datastream
 
-import org.apache.calcite.plan.{RelOptRule, RelOptRuleCall, RelTraitSet}
+import org.apache.calcite.plan.RelTraitSet
 import org.apache.calcite.rel.RelNode
 import org.apache.calcite.rel.convert.ConverterRule
 import org.apache.flink.table.plan.nodes.FlinkConventions
 import org.apache.flink.table.plan.nodes.datastream.DataStreamScan
-import org.apache.flink.table.plan.schema.{DataStreamTable, RowSchema}
-import org.apache.flink.table.plan.nodes.logical.FlinkLogicalNativeTableScan
+import org.apache.flink.table.plan.nodes.logical.FlinkLogicalDataStreamScan
 
 class DataStreamScanRule
   extends ConverterRule(
-    classOf[FlinkLogicalNativeTableScan],
+    classOf[FlinkLogicalDataStreamScan],
     FlinkConventions.LOGICAL,
     FlinkConventions.DATASTREAM,
     "DataStreamScanRule")
 {
 
-  override def matches(call: RelOptRuleCall): Boolean = {
-    val scan: FlinkLogicalNativeTableScan = call.rel(0).asInstanceOf[FlinkLogicalNativeTableScan]
-    val dataSetTable = scan.getTable.unwrap(classOf[DataStreamTable[Any]])
-    dataSetTable match {
-      case _: DataStreamTable[Any] =>
-        true
-      case _ =>
-        false
-    }
-  }
-
   def convert(rel: RelNode): RelNode = {
-    val scan: FlinkLogicalNativeTableScan = rel.asInstanceOf[FlinkLogicalNativeTableScan]
+    val scan: FlinkLogicalDataStreamScan = rel.asInstanceOf[FlinkLogicalDataStreamScan]
     val traitSet: RelTraitSet = rel.getTraitSet.replace(FlinkConventions.DATASTREAM)
 
     new DataStreamScan(
       rel.getCluster,
       traitSet,
-      scan.getTable,
-      new RowSchema(rel.getRowType)
+      scan.catalog,
+      scan.dataStream,
+      scan.fieldIdxs,
+      scan.schema
     )
   }
 }
 
 object DataStreamScanRule {
-  val INSTANCE: RelOptRule = new DataStreamScanRule
+  val INSTANCE = new DataStreamScanRule
 }
+
+
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/logical/LogicalCorrelateToTemporalTableJoinRule.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/logical/LogicalCorrelateToTemporalTableJoinRule.scala
index 0b07f47..bfdc29f 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/logical/LogicalCorrelateToTemporalTableJoinRule.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/rules/logical/LogicalCorrelateToTemporalTableJoinRule.scala
@@ -85,14 +85,7 @@ class LogicalCorrelateToTemporalTableJoinRule
           .getUnderlyingHistoryTable
         val rexBuilder = cluster.getRexBuilder
 
-        val expressionBridge = call.getPlanner.getContext
-          .unwrap(classOf[ExpressionBridge[PlannerExpression]])
-
-        val relBuilder = new FlinkRelBuilder(call.getPlanner.getContext,
-          cluster,
-          leftNode.getTable.getRelOptSchema,
-          expressionBridge)
-
+        val relBuilder = FlinkRelBuilder.of(cluster, leftNode.getTable)
         val rightNode: RelNode = relBuilder.tableOperation(underlyingHistoryTable).build()
 
         val rightTimeIndicatorExpression = createRightExpression(
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/DataSetTable.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/DataSetTable.scala
deleted file mode 100644
index 4227498..0000000
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/DataSetTable.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.flink.table.plan.schema
-
-import org.apache.flink.api.java.DataSet
-import org.apache.flink.table.plan.stats.{FlinkStatistic, TableStats}
-
-class DataSetTable[T](
-    val dataSet: DataSet[T],
-    override val fieldIndexes: Array[Int],
-    override val fieldNames: Array[String],
-    override val statistic: FlinkStatistic = FlinkStatistic.of(new TableStats(1000L)))
-  extends InlineTable[T](dataSet.getType, fieldIndexes, fieldNames, statistic)
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/DataStreamTable.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/DataStreamTable.scala
deleted file mode 100644
index 6de962c..0000000
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/DataStreamTable.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.flink.table.plan.schema
-
-import org.apache.flink.streaming.api.datastream.DataStream
-import org.apache.flink.table.plan.stats.FlinkStatistic
-
-class DataStreamTable[T](
-    val dataStream: DataStream[T],
-    override val fieldIndexes: Array[Int],
-    override val fieldNames: Array[String],
-    override val statistic: FlinkStatistic = FlinkStatistic.UNKNOWN)
-  extends InlineTable[T](dataStream.getType, fieldIndexes, fieldNames, statistic)
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/InlineTable.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/InlineTable.scala
deleted file mode 100644
index 84f1d11..0000000
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/InlineTable.scala
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.flink.table.plan.schema
-
-import org.apache.calcite.rel.`type`.{RelDataType, RelDataTypeFactory}
-import org.apache.calcite.schema.Statistic
-import org.apache.calcite.schema.impl.AbstractTable
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.common.typeutils.CompositeType
-import org.apache.flink.table.api.{TableException, Types}
-import org.apache.flink.table.calcite.FlinkTypeFactory
-import org.apache.flink.table.plan.stats.FlinkStatistic
-import org.apache.flink.table.typeutils.TimeIndicatorTypeInfo
-
-abstract class InlineTable[T](
-    val typeInfo: TypeInformation[T],
-    val fieldIndexes: Array[Int],
-    val fieldNames: Array[String],
-    val statistic: FlinkStatistic)
-  extends AbstractTable {
-
-  if (fieldIndexes.length != fieldNames.length) {
-    throw new TableException(
-      s"Number of field names and field indexes must be equal.\n" +
-        s"Number of names is ${fieldNames.length}, number of indexes is ${fieldIndexes.length}.\n" +
-        s"List of column names: ${fieldNames.mkString("[", ", ", "]")}.\n" +
-        s"List of column indexes: ${fieldIndexes.mkString("[", ", ", "]")}.")
-  }
-
-  // check uniqueness of field names
-  if (fieldNames.length != fieldNames.toSet.size) {
-    val duplicateFields = fieldNames
-      // count occurrences of field names
-      .groupBy(identity).mapValues(_.length)
-      // filter for occurrences > 1 and map to field name
-      .filter(g => g._2 > 1).keys
-
-    throw new TableException(
-      s"Field names must be unique.\n" +
-        s"List of duplicate fields: ${duplicateFields.mkString("[", ", ", "]")}.\n" +
-        s"List of all fields: ${fieldNames.mkString("[", ", ", "]")}.")
-  }
-
-  val fieldTypes: Array[TypeInformation[_]] =
-    typeInfo match {
-
-      case ct: CompositeType[_] =>
-        // it is ok to leave out fields
-        if (fieldIndexes.count(_ >= 0) > ct.getArity) {
-          throw new TableException(
-          s"Arity of type (" + ct.getFieldNames.deep + ") " +
-            "must not be greater than number of field names " + fieldNames.deep + ".")
-        }
-        fieldIndexes.map {
-          case TimeIndicatorTypeInfo.ROWTIME_STREAM_MARKER =>
-            TimeIndicatorTypeInfo.ROWTIME_INDICATOR
-          case TimeIndicatorTypeInfo.PROCTIME_STREAM_MARKER =>
-            TimeIndicatorTypeInfo.PROCTIME_INDICATOR
-          case TimeIndicatorTypeInfo.ROWTIME_BATCH_MARKER =>
-            Types.SQL_TIMESTAMP
-          case TimeIndicatorTypeInfo.PROCTIME_BATCH_MARKER =>
-            Types.SQL_TIMESTAMP
-          case i => ct.getTypeAt(i).asInstanceOf[TypeInformation[_]]}
-
-      case t: TypeInformation[_] =>
-        var cnt = 0
-        val types = fieldIndexes.map {
-          case TimeIndicatorTypeInfo.ROWTIME_STREAM_MARKER =>
-            TimeIndicatorTypeInfo.ROWTIME_INDICATOR
-          case TimeIndicatorTypeInfo.PROCTIME_STREAM_MARKER =>
-            TimeIndicatorTypeInfo.PROCTIME_INDICATOR
-          case TimeIndicatorTypeInfo.ROWTIME_BATCH_MARKER =>
-            Types.SQL_TIMESTAMP
-          case TimeIndicatorTypeInfo.PROCTIME_BATCH_MARKER =>
-            Types.SQL_TIMESTAMP
-          case _ =>
-            cnt += 1
-            t.asInstanceOf[TypeInformation[_]]
-        }
-        // ensure that the atomic type is matched at most once.
-        if (cnt > 1) {
-          throw new TableException(
-            "Non-composite input type may have only a single field and its index must be 0.")
-        } else {
-          types
-        }
-    }
-
-  override def getRowType(typeFactory: RelDataTypeFactory): RelDataType = {
-    val flinkTypeFactory = typeFactory.asInstanceOf[FlinkTypeFactory]
-    flinkTypeFactory.buildLogicalRowType(fieldNames, fieldTypes)
-  }
-
-  /**
-    * Returns statistics of current table
-    *
-    * @return statistics of current table
-    */
-  override def getStatistic: Statistic = statistic
-
-}
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/RelTable.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/RelTable.scala
deleted file mode 100644
index 30052a8..0000000
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/schema/RelTable.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.flink.table.plan.schema
-
-import org.apache.calcite.plan.RelOptTable
-import org.apache.calcite.plan.RelOptTable.ToRelContext
-import org.apache.calcite.rel.RelNode
-import org.apache.calcite.rel.`type`.{RelDataType, RelDataTypeFactory}
-import org.apache.calcite.schema.Schema.TableType
-import org.apache.calcite.schema.impl.AbstractTable
-import org.apache.calcite.schema.TranslatableTable
-
-/**
- * A [[org.apache.calcite.schema.Table]] implementation for registering
- * Table API Tables in the Calcite schema to be used by Flink SQL.
- * It implements [[TranslatableTable]] so that its logical scan
- * can be converted to a relational expression.
- *
- * @see [[DataSetTable]]
- */
-class RelTable(relNode: RelNode) extends AbstractTable with TranslatableTable {
-
-  override def getJdbcTableType: TableType = ???
-
-  override def getRowType(typeFactory: RelDataTypeFactory): RelDataType = relNode.getRowType
-
-  override def toRel(context: ToRelContext, relOptTable: RelOptTable): RelNode = {
-    relNode
-  }
-}
diff --git a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/stats/FlinkStatistic.scala b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/stats/FlinkStatistic.scala
index 5469f94..1acc91f 100644
--- a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/stats/FlinkStatistic.scala
+++ b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/plan/stats/FlinkStatistic.scala
@@ -26,10 +26,9 @@ import org.apache.calcite.rel.{RelCollation, RelDistribution, RelReferentialCons
 import org.apache.calcite.schema.Statistic
 import org.apache.calcite.util.ImmutableBitSet
 import org.apache.flink.table.plan.schema.TableSourceTable
-import org.apache.flink.table.plan.schema.InlineTable
 
 /**
-  * The class provides statistics for a [[InlineTable]] or [[TableSourceTable]].
+  * The class provides statistics for a [[TableSourceTable]].
   *
   * @param tableStats The table statistics.
   */
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/TableSourceTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/TableSourceTest.scala
index ee2e749..389ac22 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/TableSourceTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/TableSourceTest.scala
@@ -137,7 +137,7 @@ class TableSourceTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      s"BatchTableSourceScan(table=[[$tableName]], " +
+      s"BatchTableSourceScan(table=[[default_catalog, default_database, $tableName]], " +
         s"fields=[], " +
         s"source=[CsvTableSource(read fields: first)])",
       term("select", "1 AS _c0")
@@ -161,7 +161,8 @@ class TableSourceTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      "BatchTableSourceScan(table=[[filterableTable]], fields=[price, id, amount])",
+      "BatchTableSourceScan(table=[[default_catalog, default_database, filterableTable]], " +
+        "fields=[price, id, amount])",
       term("select", "price", "id", "amount"),
       term("where", "<(*(price, 2), 32)")
     )
@@ -486,13 +487,13 @@ class TableSourceTest extends TableTestBase {
   }
 
   def batchSourceTableNode(sourceName: String, fields: Array[String]): String = {
-    s"BatchTableSourceScan(table=[[$sourceName]], " +
+    s"BatchTableSourceScan(table=[[default_catalog, default_database, $sourceName]], " +
       s"fields=[${fields.mkString(", ")}], " +
       s"source=[CsvTableSource(read fields: ${fields.mkString(", ")})])"
   }
 
   def streamSourceTableNode(sourceName: String, fields: Array[String] ): String = {
-    s"StreamTableSourceScan(table=[[$sourceName]], " +
+    s"StreamTableSourceScan(table=[[default_catalog, default_database, $sourceName]], " +
       s"fields=[${fields.mkString(", ")}], " +
       s"source=[CsvTableSource(read fields: ${fields.mkString(", ")})])"
   }
@@ -500,17 +501,25 @@ class TableSourceTest extends TableTestBase {
   def batchFilterableSourceTableNode(
       sourceName: String,
       fields: Array[String],
-      exp: String): String = {
+      exp: String)
+    : String = {
     "BatchTableSourceScan(" +
-      s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
+      s"table=[[default_catalog, default_database, $sourceName]], fields=[${
+        fields
+          .mkString(", ")
+      }], source=[filter=[$exp]])"
   }
 
   def streamFilterableSourceTableNode(
       sourceName: String,
       fields: Array[String],
-      exp: String): String = {
+      exp: String)
+    : String = {
     "StreamTableSourceScan(" +
-      s"table=[[$sourceName]], fields=[${fields.mkString(", ")}], source=[filter=[$exp]])"
+      s"table=[[default_catalog, default_database, $sourceName]], fields=[${
+        fields
+          .mkString(", ")
+      }], source=[filter=[$exp]])"
   }
 
 }
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/BatchTableEnvironmentTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/BatchTableEnvironmentTest.scala
index dde5569..c8e5aff 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/BatchTableEnvironmentTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/BatchTableEnvironmentTest.scala
@@ -35,7 +35,7 @@ class BatchTableEnvironmentTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select", "a, b, c"),
       term("where", ">(b, 12)"))
 
@@ -49,8 +49,8 @@ class BatchTableEnvironmentTest extends TableTestBase {
       "DataSetJoin",
       binaryNode(
         "DataSetCalc",
-        batchTableNode(0),
-        batchTableNode(1),
+        batchTableNode(table),
+        batchTableNode(table2),
         term("select", "c")),
       term("where", "=(c, d)"),
       term("join", "c, d, e, f"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/ExplainTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/ExplainTest.scala
index d1fa36b..a3f43ad 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/ExplainTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/ExplainTest.scala
@@ -19,7 +19,9 @@
 package org.apache.flink.table.api.batch
 
 import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Table
 import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil.batchTableNode
 import org.apache.flink.test.util.MultipleProgramsTestBase
 import org.junit.Assert.assertEquals
 import org.junit._
@@ -34,14 +36,15 @@ class ExplainTest
     val env = ExecutionEnvironment.getExecutionEnvironment
     val tEnv = BatchTableEnvironment.create(env)
 
-    val table = env.fromElements((1, "hello"))
-      .toTable(tEnv, 'a, 'b)
-      .filter("a % 2 = 0")
+    val scan = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
+    val table = scan.filter("a % 2 = 0")
 
     val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
     val source = scala.io.Source.fromFile(testFilePath +
-      "../../src/test/scala/resources/testFilter0.out").mkString.replaceAll("\\r\\n", "\n")
-    assertEquals(source, result)
+      "../../src/test/scala/resources/testFilter0.out").mkString
+
+    val expected = replaceString(source, scan)
+    assertEquals(expected, result)
   }
 
   @Test
@@ -49,15 +52,16 @@ class ExplainTest
     val env = ExecutionEnvironment.getExecutionEnvironment
     val tEnv = BatchTableEnvironment.create(env)
 
-    val table = env.fromElements((1, "hello"))
-      .toTable(tEnv, 'a, 'b)
-      .filter("a % 2 = 0")
+    val scan = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
+    val table = scan.filter("a % 2 = 0")
 
     val result = tEnv.asInstanceOf[BatchTableEnvImpl]
       .explain(table, extended = true).replaceAll("\\r\\n", "\n")
     val source = scala.io.Source.fromFile(testFilePath +
-      "../../src/test/scala/resources/testFilter1.out").mkString.replaceAll("\\r\\n", "\n")
-    assertEquals(source, result)
+      "../../src/test/scala/resources/testFilter1.out").mkString
+
+    val expected = replaceString(source, scan)
+    assertEquals(expected, result)
   }
 
   @Test
@@ -71,8 +75,10 @@ class ExplainTest
 
     val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
     val source = scala.io.Source.fromFile(testFilePath +
-      "../../src/test/scala/resources/testJoin0.out").mkString.replaceAll("\\r\\n", "\n")
-    assertEquals(source, result)
+      "../../src/test/scala/resources/testJoin0.out").mkString
+
+    val expected = replaceString(source, table1, table2)
+    assertEquals(expected, result)
   }
 
   @Test
@@ -87,8 +93,10 @@ class ExplainTest
     val result = tEnv.asInstanceOf[BatchTableEnvImpl]
       .explain(table, extended = true).replaceAll("\\r\\n", "\n")
     val source = scala.io.Source.fromFile(testFilePath +
-      "../../src/test/scala/resources/testJoin1.out").mkString.replaceAll("\\r\\n", "\n")
-    assertEquals(source, result)
+      "../../src/test/scala/resources/testJoin1.out").mkString
+
+    val expected = replaceString(source, table1, table2)
+    assertEquals(expected, result)
   }
 
   @Test
@@ -102,8 +110,10 @@ class ExplainTest
 
     val result = tEnv.explain(table).replaceAll("\\r\\n", "\n")
     val source = scala.io.Source.fromFile(testFilePath +
-      "../../src/test/scala/resources/testUnion0.out").mkString.replaceAll("\\r\\n", "\n")
-    assertEquals(source, result)
+      "../../src/test/scala/resources/testUnion0.out").mkString
+
+    val expected = replaceString(source, table1, table2)
+    assertEquals(expected, result)
   }
 
   @Test
@@ -118,7 +128,29 @@ class ExplainTest
     val result = tEnv.asInstanceOf[BatchTableEnvImpl]
       .explain(table, extended = true).replaceAll("\\r\\n", "\n")
     val source = scala.io.Source.fromFile(testFilePath +
-      "../../src/test/scala/resources/testUnion1.out").mkString.replaceAll("\\r\\n", "\n")
-    assertEquals(source, result)
+      "../../src/test/scala/resources/testUnion1.out").mkString
+
+    val expected = replaceString(source, table1, table2)
+    assertEquals(expected, result)
+  }
+
+
+  def replaceString(s: String, t1: Table, t2: Table): String = {
+    replaceSourceNode(replaceSourceNode(replaceString(s), t1, 0), t2, 1)
+  }
+
+  def replaceString(s: String, t: Table): String = {
+    replaceSourceNode(replaceString(s), t, 0)
+  }
+
+  private def replaceSourceNode(s: String, t: Table, idx: Int) = {
+    s.replace(
+      s"%logicalSourceNode$idx%", batchTableNode(t)
+        .replace("DataSetScan", "FlinkLogicalDataSetScan"))
+      .replace(s"%sourceNode$idx%", batchTableNode(t))
+  }
+
+  def replaceString(s: String) = {
+    s.replaceAll("\\r\\n", "\n")
   }
 }
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/AggregateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/AggregateTest.scala
index 82d336d..07440fd 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/AggregateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/AggregateTest.scala
@@ -32,13 +32,13 @@ class AggregateTest extends TableTestBase {
   @Test
   def testAggregate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable"
 
     val aggregate = unaryNode(
       "DataSetAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "AVG(a) AS EXPR$0",
         "SUM(b) AS EXPR$1",
@@ -50,13 +50,13 @@ class AggregateTest extends TableTestBase {
   @Test
   def testAggregateWithFilter(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1"
 
     val calcNode = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select", "CAST(1) AS a", "b", "c"),
       term("where", "=(a, 1)")
     )
@@ -75,13 +75,13 @@ class AggregateTest extends TableTestBase {
   @Test
   def testAggregateWithFilterOnNestedFields(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, (Int, Long))]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, (Int, Long))]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT avg(a), sum(b), count(c), sum(c._1) FROM MyTable WHERE a = 1"
 
     val calcNode = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select", "CAST(1) AS a", "b", "c", "c._1 AS $f3"),
       term("where", "=(a, 1)")
     )
@@ -102,13 +102,13 @@ class AggregateTest extends TableTestBase {
   @Test
   def testGroupAggregate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable GROUP BY a"
 
     val aggregate = unaryNode(
         "DataSetAggregate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("groupBy", "a"),
         term("select",
           "a",
@@ -130,13 +130,13 @@ class AggregateTest extends TableTestBase {
   @Test
   def testGroupAggregateWithFilter(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT avg(a), sum(b), count(c) FROM MyTable WHERE a = 1 GROUP BY a"
 
     val calcNode = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select","CAST(1) AS a", "b", "c") ,
       term("where","=(a, 1)")
     )
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/CalcTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/CalcTest.scala
index 382aedd..5f423ad 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/CalcTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/CalcTest.scala
@@ -29,11 +29,11 @@ class CalcTest extends TableTestBase {
   @Test
   def testMultipleFlattening(): Unit = {
     val util = batchTestUtil()
-    util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[((Int, Long), (String, Boolean), String)]("MyTable", 'a, 'b, 'c)
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "a._1 AS _1",
         "a._2 AS _2",
@@ -51,12 +51,12 @@ class CalcTest extends TableTestBase {
   @Test
   def testIn(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val resultStr = (1 to 30).mkString(", ")
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select", "a", "b", "c"),
       term("where", s"IN(b, $resultStr)")
     )
@@ -69,12 +69,12 @@ class CalcTest extends TableTestBase {
   @Test
   def testNotIn(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val resultStr = (1 to 30).mkString(", ")
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select", "a", "b", "c"),
       term("where", s"NOT IN(b, $resultStr)")
     )
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/CorrelateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/CorrelateTest.scala
index 7330825..c776e1b 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/CorrelateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/CorrelateTest.scala
@@ -31,7 +31,7 @@ class CorrelateTest extends TableTestBase {
   def testCrossJoin(): Unit = {
     val util = batchTestUtil()
     val func1 = new TableFunc1
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func1", func1)
 
     val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c)) AS T(s)"
@@ -40,7 +40,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "func1($cor0.c)"),
         term("correlate", s"table(func1($$cor0.c))"),
         term("select", "a", "b", "c", "f0"),
@@ -61,7 +61,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "func1($cor0.c, '$')"),
         term("correlate", s"table(func1($$cor0.c, '$$'))"),
         term("select", "a", "b", "c", "f0"),
@@ -79,7 +79,7 @@ class CorrelateTest extends TableTestBase {
   def testLeftOuterJoinWithLiteralTrue(): Unit = {
     val util = batchTestUtil()
     val func1 = new TableFunc1
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func1", func1)
 
     val sqlQuery = "SELECT c, s FROM MyTable LEFT JOIN LATERAL TABLE(func1(c)) AS T(s) ON TRUE"
@@ -88,7 +88,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "func1($cor0.c)"),
         term("correlate", s"table(func1($$cor0.c))"),
         term("select", "a", "b", "c", "f0"),
@@ -106,8 +106,8 @@ class CorrelateTest extends TableTestBase {
   def testLeftOuterJoinAsSubQuery(): Unit = {
     val util = batchTestUtil()
     val func1 = new TableFunc1
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-    util.addTable[(Int, Long, String)]("MyTable2", 'a2, 'b2, 'c2)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table1 = util.addTable[(Int, Long, String)]("MyTable2", 'a2, 'b2, 'c2)
     util.addFunction("func1", func1)
 
     val sqlQuery =
@@ -120,12 +120,12 @@ class CorrelateTest extends TableTestBase {
 
     val expected = binaryNode(
       "DataSetJoin",
-      batchTableNode(1),
+      batchTableNode(table1),
       unaryNode(
         "DataSetCalc",
         unaryNode(
          "DataSetCorrelate",
-          batchTableNode(0),
+          batchTableNode(table),
           term("invocation", "func1($cor0.c)"),
           term("correlate", "table(func1($cor0.c))"),
           term("select", "a", "b", "c", "f0"),
@@ -146,7 +146,7 @@ class CorrelateTest extends TableTestBase {
   def testCustomType(): Unit = {
     val util = batchTestUtil()
     val func2 = new TableFunc2
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func2", func2)
 
     val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len)"
@@ -155,7 +155,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "func2($cor0.c)"),
         term("correlate", s"table(func2($$cor0.c))"),
         term("select", "a", "b", "c", "f0", "f1"),
@@ -173,7 +173,7 @@ class CorrelateTest extends TableTestBase {
   @Test
   def testHierarchyType(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     val function = new HierarchyTableFunction
     util.addFunction("hierarchy", function)
 
@@ -183,7 +183,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "hierarchy($cor0.c)"),
         term("correlate", s"table(hierarchy($$cor0.c))"),
         term("select", "a", "b", "c", "f0", "f1", "f2"),
@@ -201,7 +201,7 @@ class CorrelateTest extends TableTestBase {
   @Test
   def testPojoType(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     val function = new PojoTableFunc
     util.addFunction("pojo", function)
 
@@ -211,7 +211,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "pojo($cor0.c)"),
         term("correlate", s"table(pojo($$cor0.c))"),
         term("select", "a", "b", "c", "age", "name"),
@@ -230,7 +230,7 @@ class CorrelateTest extends TableTestBase {
   def testFilter(): Unit = {
     val util = batchTestUtil()
     val func2 = new TableFunc2
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func2", func2)
 
     val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len) " +
@@ -240,7 +240,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "func2($cor0.c)"),
         term("correlate", s"table(func2($$cor0.c))"),
         term("select", "a", "b", "c", "f0", "f1"),
@@ -260,7 +260,7 @@ class CorrelateTest extends TableTestBase {
   def testScalarFunction(): Unit = {
     val util = batchTestUtil()
     val func1 = new TableFunc1
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func1", func1)
 
     val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(SUBSTRING(c, 2))) AS T(s)"
@@ -269,7 +269,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "func1(SUBSTRING($cor0.c, 2))"),
         term("correlate", s"table(func1(SUBSTRING($$cor0.c, 2)))"),
         term("select", "a", "b", "c", "f0"),
@@ -287,7 +287,7 @@ class CorrelateTest extends TableTestBase {
   def testTableFunctionWithVariableArguments(): Unit = {
     val util = batchTestUtil()
     val func1 = new JavaVarsArgTableFunc0
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func1", func1)
 
     var sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1('hello', 'world', c)) AS T(s)"
@@ -296,7 +296,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "func1('hello', 'world', $cor0.c)"),
         term("correlate", s"table(func1('hello', 'world', $$cor0.c))"),
         term("select", "a", "b", "c", "f0"),
@@ -319,7 +319,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", "func2('hello', 'world', $cor0.c)"),
         term("correlate", s"table(func2('hello', 'world', $$cor0.c))"),
         term("select", "a", "b", "c", "f0"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/DistinctAggregateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/DistinctAggregateTest.scala
index 7796e22..ff5e560 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/DistinctAggregateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/DistinctAggregateTest.scala
@@ -29,7 +29,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testSingleDistinctAggregate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT COUNT(DISTINCT a) FROM MyTable"
 
@@ -39,7 +39,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataSetDistinct",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a")
         ),
         term("distinct", "a")
@@ -53,7 +53,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testMultiDistinctAggregateOnSameColumn(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT a), MAX(DISTINCT a) FROM MyTable"
 
@@ -63,7 +63,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataSetDistinct",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a")
         ),
         term("distinct", "a")
@@ -77,7 +77,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testSingleDistinctAggregateAndOneOrMultiNonDistinctAggregate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     // case 0x00: DISTINCT on COUNT and Non-DISTINCT on others
     val sqlQuery0 = "SELECT COUNT(DISTINCT a), SUM(b) FROM MyTable"
@@ -88,7 +88,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
         term("groupBy", "a"),
@@ -108,7 +108,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
         term("groupBy", "b"),
@@ -123,7 +123,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testMultiDistinctAggregateOnDifferentColumn(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT b) FROM MyTable"
 
@@ -135,7 +135,7 @@ class DistinctAggregateTest extends TableTestBase {
           "DataSetDistinct",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "a")
           ),
           term("distinct", "a")
@@ -148,7 +148,7 @@ class DistinctAggregateTest extends TableTestBase {
           "DataSetDistinct",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "b")
           ),
           term("distinct", "b")
@@ -166,7 +166,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testMultiDistinctAndNonDistinctAggregateOnDifferentColumn(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT COUNT(DISTINCT a), SUM(DISTINCT b), COUNT(c) FROM MyTable"
 
@@ -180,7 +180,7 @@ class DistinctAggregateTest extends TableTestBase {
             "DataSetAggregate",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "c")
             ),
             term("select", "COUNT(c) AS EXPR$2")
@@ -191,7 +191,7 @@ class DistinctAggregateTest extends TableTestBase {
               "DataSetDistinct",
               unaryNode(
                 "DataSetCalc",
-                batchTableNode(0),
+                batchTableNode(table),
                 term("select", "a")
               ),
               term("distinct", "a")
@@ -208,7 +208,7 @@ class DistinctAggregateTest extends TableTestBase {
             "DataSetDistinct",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "b")
             ),
             term("distinct", "b")
@@ -228,7 +228,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testSingleDistinctAggregateWithGrouping(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT a, COUNT(a), SUM(DISTINCT b) FROM MyTable GROUP BY a"
 
@@ -238,7 +238,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
         term("groupBy", "a", "b"),
@@ -254,7 +254,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testSingleDistinctAggregateWithGroupingAndCountStar(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b) FROM MyTable GROUP BY a"
 
@@ -264,7 +264,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
         term("groupBy", "a", "b"),
@@ -280,7 +280,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testTwoDistinctAggregateWithGroupingAndCountStar(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b), COUNT(DISTINCT b) FROM MyTable GROUP BY a"
 
@@ -292,7 +292,7 @@ class DistinctAggregateTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "a")
           ),
           term("groupBy", "a"),
@@ -304,7 +304,7 @@ class DistinctAggregateTest extends TableTestBase {
             "DataSetDistinct",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "a", "b")
             ),
             term("distinct", "a, b")
@@ -325,7 +325,7 @@ class DistinctAggregateTest extends TableTestBase {
   @Test
   def testTwoDifferentDistinctAggregateWithGroupingAndCountStar(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT a, COUNT(*), SUM(DISTINCT b), COUNT(DISTINCT c) FROM MyTable GROUP BY a"
 
@@ -341,7 +341,7 @@ class DistinctAggregateTest extends TableTestBase {
               "DataSetAggregate",
               unaryNode(
                 "DataSetCalc",
-                batchTableNode(0),
+                batchTableNode(table),
                 term("select", "a")
               ),
               term("groupBy", "a"),
@@ -353,7 +353,7 @@ class DistinctAggregateTest extends TableTestBase {
                 "DataSetDistinct",
                 unaryNode(
                   "DataSetCalc",
-                  batchTableNode(0),
+                  batchTableNode(table),
                   term("select", "a", "b")
                 ),
                 term("distinct", "a, b")
@@ -373,7 +373,7 @@ class DistinctAggregateTest extends TableTestBase {
             "DataSetDistinct",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "a", "c")
             ),
             term("distinct", "a, c")
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/GroupWindowTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/GroupWindowTest.scala
index 7f48442..e3ce577 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/GroupWindowTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/GroupWindowTest.scala
@@ -32,7 +32,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testNonPartitionedTumbleWindow(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+    val table = util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
 
     val sqlQuery =
       "SELECT SUM(a) AS sumA, COUNT(b) AS cntB FROM T GROUP BY TUMBLE(ts, INTERVAL '2' HOUR)"
@@ -42,7 +42,7 @@ class GroupWindowTest extends TableTestBase {
         "DataSetWindowAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "ts, a, b")
         ),
         term("window", "TumblingGroupWindow('w$, 'ts, 7200000.millis)"),
@@ -55,7 +55,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testPartitionedTumbleWindow(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+    val table = util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
 
     val sqlQuery =
       "SELECT " +
@@ -73,7 +73,7 @@ class GroupWindowTest extends TableTestBase {
         "DataSetCalc",
         unaryNode(
           "DataSetWindowAggregate",
-          batchTableNode(0),
+          batchTableNode(table),
           term("groupBy", "c"),
           term("window", "TumblingGroupWindow('w$, 'ts, 240000.millis)"),
           term("select", "c, SUM(a) AS sumA, MIN(b) AS minB, " +
@@ -89,7 +89,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testTumbleWindowWithUdAgg() = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+    val table = util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
 
     val weightedAvg = new WeightedAvgWithMerge
     util.tableEnv.registerFunction("weightedAvg", weightedAvg)
@@ -103,7 +103,7 @@ class GroupWindowTest extends TableTestBase {
         "DataSetWindowAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "ts, b, a")
         ),
         term("window", "TumblingGroupWindow('w$, 'ts, 240000.millis)"),
@@ -116,7 +116,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testNonPartitionedHopWindow(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+    val table = util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
 
     val sqlQuery =
       "SELECT SUM(a) AS sumA, COUNT(b) AS cntB " +
@@ -128,7 +128,7 @@ class GroupWindowTest extends TableTestBase {
         "DataSetWindowAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "ts, a, b")
         ),
         term("window", "SlidingGroupWindow('w$, 'ts, 5400000.millis, 900000.millis)"),
@@ -141,7 +141,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testPartitionedHopWindow(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Long, Timestamp)]("T", 'a, 'b, 'c, 'd, 'ts)
+    val table = util.addTable[(Int, Long, String, Long, Timestamp)]("T", 'a, 'b, 'c, 'd, 'ts)
 
     val sqlQuery =
       "SELECT " +
@@ -159,7 +159,7 @@ class GroupWindowTest extends TableTestBase {
         "DataSetCalc",
         unaryNode(
           "DataSetWindowAggregate",
-          batchTableNode(0),
+          batchTableNode(table),
           term("groupBy", "c, d"),
           term("window", "SlidingGroupWindow('w$, 'ts, 10800000.millis, 3600000.millis)"),
           term("select", "c, d, SUM(a) AS sumA, AVG(b) AS avgB, " +
@@ -175,7 +175,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testNonPartitionedSessionWindow(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+    val table = util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
 
     val sqlQuery =
       "SELECT COUNT(*) AS cnt FROM T GROUP BY SESSION(ts, INTERVAL '30' MINUTE)"
@@ -185,7 +185,7 @@ class GroupWindowTest extends TableTestBase {
         "DataSetWindowAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "ts")
         ),
         term("window", "SessionGroupWindow('w$, 'ts, 1800000.millis)"),
@@ -198,7 +198,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testPartitionedSessionWindow(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Int, Timestamp)]("T", 'a, 'b, 'c, 'd, 'ts)
+    val table = util.addTable[(Int, Long, String, Int, Timestamp)]("T", 'a, 'b, 'c, 'd, 'ts)
 
     val sqlQuery =
       "SELECT " +
@@ -216,7 +216,7 @@ class GroupWindowTest extends TableTestBase {
         "DataSetCalc",
         unaryNode(
           "DataSetWindowAggregate",
-          batchTableNode(0),
+          batchTableNode(table),
           term("groupBy", "c, d"),
           term("window", "SessionGroupWindow('w$, 'ts, 43200000.millis)"),
           term("select", "c, d, SUM(a) AS sumA, MIN(b) AS minB, " +
@@ -232,7 +232,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testWindowEndOnly(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+    val table = util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
 
     val sqlQuery =
       "SELECT " +
@@ -247,7 +247,7 @@ class GroupWindowTest extends TableTestBase {
           "DataSetWindowAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "ts, c")
           ),
           term("groupBy", "c"),
@@ -263,7 +263,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testExpressionOnWindowHavingFunction() = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
+    val table = util.addTable[(Int, Long, String, Timestamp)]("T", 'a, 'b, 'c, 'ts)
 
     val sql =
       "SELECT " +
@@ -282,7 +282,7 @@ class GroupWindowTest extends TableTestBase {
           "DataSetWindowAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "ts, a")
           ),
           term("window", "SlidingGroupWindow('w$, 'ts, 60000.millis, 900000.millis)"),
@@ -305,7 +305,7 @@ class GroupWindowTest extends TableTestBase {
   @Test
   def testDecomposableAggFunctions() = {
     val util = batchTestUtil()
-    util.addTable[(Int, String, Long, Timestamp)]("MyTable", 'a, 'b, 'c, 'rowtime)
+    val table = util.addTable[(Int, String, Long, Timestamp)]("MyTable", 'a, 'b, 'c, 'rowtime)
 
     val sql =
       "SELECT " +
@@ -322,7 +322,7 @@ class GroupWindowTest extends TableTestBase {
           "DataSetWindowAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "rowtime", "c", "*(c, c) AS $f2")
           ),
           term("window", "TumblingGroupWindow('w$, 'rowtime, 900000.millis)"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/GroupingSetsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/GroupingSetsTest.scala
index cfdce10..d110125 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/GroupingSetsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/GroupingSetsTest.scala
@@ -29,7 +29,7 @@ class GroupingSetsTest extends TableTestBase {
   @Test
   def testGroupingSets(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g FROM MyTable " +
       "GROUP BY GROUPING SETS (b, c)"
@@ -42,7 +42,7 @@ class GroupingSetsTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "b", "a")
           ),
           term("groupBy", "b"),
@@ -56,7 +56,7 @@ class GroupingSetsTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "c", "a")
           ),
           term("groupBy", "c"),
@@ -74,7 +74,7 @@ class GroupingSetsTest extends TableTestBase {
   @Test
   def testCube(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g, " +
       "GROUPING(b) as gb, GROUPING(c) as gc, " +
@@ -87,7 +87,7 @@ class GroupingSetsTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetAggregate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("groupBy", "b", "c"),
         term("select", "b", "c", "AVG(a) AS a")
       ),
@@ -101,7 +101,7 @@ class GroupingSetsTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "b", "a")
         ),
         term("groupBy", "b"),
@@ -117,7 +117,7 @@ class GroupingSetsTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "c", "a")
         ),
         term("groupBy", "c"),
@@ -133,7 +133,7 @@ class GroupingSetsTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a")
         ),
         term("select", "AVG(a) AS a")
@@ -169,7 +169,7 @@ class GroupingSetsTest extends TableTestBase {
   @Test
   def testRollup(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, Int)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT b, c, avg(a) as a, GROUP_ID() as g, " +
                    "GROUPING(b) as gb, GROUPING(c) as gc, " +
@@ -181,7 +181,7 @@ class GroupingSetsTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetAggregate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("groupBy", "b", "c"),
         term("select", "b", "c", "AVG(a) AS a")
       ),
@@ -195,7 +195,7 @@ class GroupingSetsTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "b", "a")
         ),
         term("groupBy", "b"),
@@ -211,7 +211,7 @@ class GroupingSetsTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a")
         ),
         term("select", "AVG(a) AS a")
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/JoinTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/JoinTest.scala
index a3a597f..8574fcf 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/JoinTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/JoinTest.scala
@@ -29,8 +29,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testLeftOuterJoinEquiPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t LEFT OUTER JOIN s ON a = z"
     val result = util.tableEnv.sqlQuery(query)
@@ -41,12 +41,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(table1),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -62,8 +62,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testLeftOuterJoinEquiAndLocalPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t LEFT OUTER JOIN s ON a = z AND b < 2"
     val result = util.tableEnv.sqlQuery(query)
@@ -74,12 +74,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b", "<(b, 2) AS $f3")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(table1),
           term("select", "y", "z")
         ),
         term("where", "AND(=(a, z), $f3)"),
@@ -95,8 +95,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testLeftOuterJoinEquiAndNonEquiPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t LEFT OUTER JOIN s ON a = z AND b < x"
     val result = util.tableEnv.sqlQuery(query)
@@ -107,10 +107,10 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
-        batchTableNode(1),
+        batchTableNode(table1),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "LeftOuterJoin")
@@ -124,8 +124,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testRightOuterJoinEquiPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t RIGHT OUTER JOIN s ON a = z"
     val result = util.tableEnv.sqlQuery(query)
@@ -136,12 +136,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(table1),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -157,8 +157,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testRightOuterJoinEquiAndLocalPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, x FROM t RIGHT OUTER JOIN s ON a = z AND x < 2"
     val result = util.tableEnv.sqlQuery(query)
@@ -169,12 +169,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(table1),
           term("select", "x", "z", "<(x, 2) AS $f3")
         ),
         term("where", "AND(=(a, z), $f3)"),
@@ -190,8 +190,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testRightOuterJoinEquiAndNonEquiPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t RIGHT OUTER JOIN s ON a = z AND b < x"
     val result = util.tableEnv.sqlQuery(query)
@@ -202,10 +202,10 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
-        batchTableNode(1),
+        batchTableNode(table1),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "RightOuterJoin")
@@ -219,8 +219,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testFullOuterJoinEquiPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t FULL OUTER JOIN s ON a = z"
     val result = util.tableEnv.sqlQuery(query)
@@ -231,12 +231,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(table1),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -252,8 +252,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testFullOuterJoinEquiAndLocalPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t FULL OUTER JOIN s ON a = z AND b < 2 AND z > 5"
     val result = util.tableEnv.sqlQuery(query)
@@ -264,12 +264,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b", "<(b, 2) AS $f3")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(table1),
           term("select", "y", "z", ">(z, 5) AS $f3")
         ),
         term("where", "AND(=(a, z), $f3, $f30)"),
@@ -285,8 +285,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testFullOuterJoinEquiAndNonEquiPred(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val table = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val table1 = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t FULL OUTER JOIN s ON a = z AND b < x"
     val result = util.tableEnv.sqlQuery(query)
@@ -297,10 +297,10 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a", "b")
         ),
-        batchTableNode(1),
+        batchTableNode(table1),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "FullOuterJoin")
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/SetOperatorsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/SetOperatorsTest.scala
index 16c3174..44879e8 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/SetOperatorsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/SetOperatorsTest.scala
@@ -36,8 +36,8 @@ class SetOperatorsTest extends TableTestBase {
 
     val expected = binaryNode(
       "DataSetMinus",
-      batchTableNode(0),
-      batchTableNode(0),
+      batchTableNode(t),
+      batchTableNode(t),
       term("minus", "a", "b", "c")
     )
 
@@ -49,21 +49,21 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testExists(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Long, Int, String)]("A", 'a_long, 'a_int, 'a_string)
-    util.addTable[(Long, Int, String)]("B", 'b_long, 'b_int, 'b_string)
+    val table = util.addTable[(Long, Int, String)]("A", 'a_long, 'a_int, 'a_string)
+    val table1 = util.addTable[(Long, Int, String)]("B", 'b_long, 'b_int, 'b_string)
 
     val expected = unaryNode(
       "DataSetCalc",
       binaryNode(
         "DataSetJoin",
-        batchTableNode(0),
+        batchTableNode(table),
         unaryNode(
           "DataSetCalc",
           unaryNode(
             "DataSetAggregate",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(1),
+              batchTableNode(table1),
               term("select", "b_long AS b_long3", "true AS $f0"),
               term("where", "IS NOT NULL(b_long)")
             ),
@@ -88,7 +88,7 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testNotIn(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("A", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("A", 'a, 'b, 'c)
 
     val expected = unaryNode(
       "DataSetCalc",
@@ -98,12 +98,12 @@ class SetOperatorsTest extends TableTestBase {
           "DataSetCalc",
           binaryNode(
             "DataSetSingleRowJoin",
-            batchTableNode(0),
+            batchTableNode(table),
             unaryNode(
               "DataSetAggregate",
               unaryNode(
                 "DataSetCalc",
-                batchTableNode(0),
+                batchTableNode(table),
                 term("select", "b"),
                 term("where", "OR(=(b, 6), =(b, 1))")
               ),
@@ -119,7 +119,7 @@ class SetOperatorsTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "b", "true AS $f1"),
             term("where", "OR(=(b, 6), =(b, 1))")
           ),
@@ -143,11 +143,11 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testInWithFields(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, Int, String, Long)]("A", 'a, 'b, 'c, 'd, 'e)
+    val table = util.addTable[(Int, Long, Int, String, Long)]("A", 'a, 'b, 'c, 'd, 'e)
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select", "a", "b", "c", "d", "e"),
       term("where", "OR(=(a, c), =(a, CAST(b)), =(a, 5))")
     )
@@ -176,18 +176,18 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testUnionNullableTypes(): Unit = {
     val util = batchTestUtil()
-    util.addTable[((Int, String), (Int, String), Int)]("A", 'a, 'b, 'c)
+    val table = util.addTable[((Int, String), (Int, String), Int)]("A", 'a, 'b, 'c)
 
     val expected = binaryNode(
       "DataSetUnion",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(table),
         term("select", "a")
       ),
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(table),
         term("select", "CASE(>(c, 0), b, null) AS EXPR$0")
       ),
       term("all", "true"),
@@ -206,18 +206,18 @@ class SetOperatorsTest extends TableTestBase {
     val typeInfo = Types.ROW(
       new GenericTypeInfo(classOf[NonPojo]),
       new GenericTypeInfo(classOf[NonPojo]))
-    util.addJavaTable(typeInfo, "A", "a, b")
+    val table = util.addJavaTable(typeInfo, "A", "a, b")
 
     val expected = binaryNode(
       "DataSetUnion",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(table),
         term("select", "a")
       ),
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(table),
         term("select", "b")
       ),
       term("all", "true"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/SingleRowJoinTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/SingleRowJoinTest.scala
index 37dc3e6..0bd6b20 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/SingleRowJoinTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/sql/SingleRowJoinTest.scala
@@ -29,7 +29,7 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testSingleRowCrossJoin(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Int)]("A", 'a1, 'a2)
+    val table = util.addTable[(Int, Int)]("A", 'a1, 'a2)
 
     val query =
       "SELECT a1, asum " +
@@ -40,14 +40,14 @@ class SingleRowJoinTest extends TableTestBase {
         "DataSetSingleRowJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(table),
           term("select", "a1")
         ),
         unaryNode(
           "DataSetCalc",
           unaryNode(
             "DataSetAggregate",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "SUM(a1) AS $f0", "SUM(a2) AS $f1")
           ),
           term("select", "+($f0, $f1) AS asum")
@@ -63,7 +63,7 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testSingleRowEquiJoin(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, String)]("A", 'a1, 'a2)
+    val table = util.addTable[(Int, String)]("A", 'a1, 'a2)
 
     val query =
       "SELECT a1, a2 " +
@@ -75,12 +75,12 @@ class SingleRowJoinTest extends TableTestBase {
         "DataSetCalc",
         binaryNode(
           "DataSetSingleRowJoin",
-          batchTableNode(0),
+          batchTableNode(table),
           unaryNode(
             "DataSetAggregate",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "a1")
             ),
             term("select", "COUNT(a1) AS cnt")
@@ -98,7 +98,7 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testSingleRowNotEquiJoin(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, String)]("A", 'a1, 'a2)
+    val table = util.addTable[(Int, String)]("A", 'a1, 'a2)
 
     val query =
       "SELECT a1, a2 " +
@@ -110,12 +110,12 @@ class SingleRowJoinTest extends TableTestBase {
         "DataSetCalc",
         binaryNode(
           "DataSetSingleRowJoin",
-          batchTableNode(0),
+          batchTableNode(table),
           unaryNode(
             "DataSetAggregate",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "a1")
             ),
             term("select", "COUNT(a1) AS cnt")
@@ -133,8 +133,8 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testSingleRowJoinWithComplexPredicate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long)]("A", 'a1, 'a2)
-    util.addTable[(Int, Long)]("B", 'b1, 'b2)
+    val table = util.addTable[(Int, Long)]("A", 'a1, 'a2)
+    val table1 = util.addTable[(Int, Long)]("B", 'b1, 'b2)
 
     val query =
       "SELECT a1, a2, b1, b2 " +
@@ -143,10 +143,10 @@ class SingleRowJoinTest extends TableTestBase {
 
     val expected = binaryNode(
       "DataSetSingleRowJoin",
-      batchTableNode(0),
+      batchTableNode(table),
       unaryNode(
         "DataSetAggregate",
-        batchTableNode(1),
+        batchTableNode(table1),
         term("select", "MIN(b1) AS b1", "MAX(b2) AS b2")
       ),
       term("where", "AND(<(a1, b1)", "=(a2, b2))"),
@@ -160,8 +160,8 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testRightSingleLeftJoinEqualPredicate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Long, Int)]("A", 'a1, 'a2)
-    util.addTable[(Int, Int)]("B", 'b1, 'b2)
+    val table = util.addTable[(Long, Int)]("A", 'a1, 'a2)
+    val table1 = util.addTable[(Int, Int)]("B", 'b1, 'b2)
 
     val queryLeftJoin =
       "SELECT a2 " +
@@ -175,7 +175,7 @@ class SingleRowJoinTest extends TableTestBase {
         "DataSetCalc",
         unaryNode(
           "DataSetSingleRowJoin",
-          batchTableNode(0),
+          batchTableNode(table),
           term("where", "=(a1, cnt)"),
           term("join", "a1", "a2", "cnt"),
           term("joinType", "NestedLoopLeftJoin")
@@ -186,7 +186,7 @@ class SingleRowJoinTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(1),
+            batchTableNode(table1),
             term("select", "")),
           term("select", "COUNT(*) AS cnt")
         )
@@ -197,8 +197,8 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testRightSingleLeftJoinNotEqualPredicate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Long, Int)]("A", 'a1, 'a2)
-    util.addTable[(Int, Int)]("B", 'b1, 'b2)
+    val table = util.addTable[(Long, Int)]("A", 'a1, 'a2)
+    val table1 = util.addTable[(Int, Int)]("B", 'b1, 'b2)
 
     val queryLeftJoin =
       "SELECT a2 " +
@@ -212,7 +212,7 @@ class SingleRowJoinTest extends TableTestBase {
         "DataSetCalc",
         unaryNode(
           "DataSetSingleRowJoin",
-          batchTableNode(0),
+          batchTableNode(table),
           term("where", ">(a1, cnt)"),
           term("join", "a1", "a2", "cnt"),
           term("joinType", "NestedLoopLeftJoin")
@@ -223,7 +223,7 @@ class SingleRowJoinTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(1),
+            batchTableNode(table1),
             term("select", "")),
           term("select", "COUNT(*) AS cnt")
         )
@@ -234,8 +234,8 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testLeftSingleRightJoinEqualPredicate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Long, Long)]("A", 'a1, 'a2)
-    util.addTable[(Long, Long)]("B", 'b1, 'b2)
+    val table = util.addTable[(Long, Long)]("A", 'a1, 'a2)
+    val table1 = util.addTable[(Long, Long)]("B", 'b1, 'b2)
 
     val queryRightJoin =
       "SELECT a1 " +
@@ -259,11 +259,11 @@ class SingleRowJoinTest extends TableTestBase {
         "DataSetAggregate",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(table1),
           term("select", "")),
         term("select", "COUNT(*) AS cnt")
       ) + "\n" +
-        batchTableNode(0)
+        batchTableNode(table)
 
     util.verifySql(queryRightJoin, expected)
   }
@@ -271,8 +271,8 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testLeftSingleRightJoinNotEqualPredicate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Long, Long)]("A", 'a1, 'a2)
-    util.addTable[(Long, Long)]("B", 'b1, 'b2)
+    val table = util.addTable[(Long, Long)]("A", 'a1, 'a2)
+    val table1 = util.addTable[(Long, Long)]("B", 'b1, 'b2)
 
     val queryRightJoin =
       "SELECT a1 " +
@@ -297,11 +297,11 @@ class SingleRowJoinTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(1),
+            batchTableNode(table1),
             term("select", "")),
           term("select", "COUNT(*) AS cnt")
         ) + "\n" +
-        batchTableNode(0)
+        batchTableNode(table)
 
     util.verifySql(queryRightJoin, expected)
   }
@@ -309,7 +309,7 @@ class SingleRowJoinTest extends TableTestBase {
   @Test
   def testSingleRowJoinInnerJoin(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Int)]("A", 'a1, 'a2)
+    val table = util.addTable[(Int, Int)]("A", 'a1, 'a2)
     val query =
       "SELECT a2, sum(a1) " +
         "FROM A " +
@@ -323,7 +323,7 @@ class SingleRowJoinTest extends TableTestBase {
           "DataSetSingleRowJoin",
           unaryNode(
             "DataSetAggregate",
-            batchTableNode(0),
+            batchTableNode(table),
             term("groupBy", "a2"),
             term("select", "a2", "SUM(a1) AS EXPR$1")
           ),
@@ -339,7 +339,7 @@ class SingleRowJoinTest extends TableTestBase {
             "DataSetAggregate",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "a1")
             ),
             term("select", "SUM(a1) AS $f0")
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/AggregateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/AggregateTest.scala
index df65481..25a98d8 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/AggregateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/AggregateTest.scala
@@ -41,7 +41,7 @@ class AggregateTest extends TableTestBase {
 
     val calcNode = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(sourceTable),
       term("select", "a", "b", "c"),
       term("where", "=(a, 1)")
     )
@@ -68,7 +68,7 @@ class AggregateTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetAggregate",
-      batchTableNode(0),
+      batchTableNode(sourceTable),
       term("select",
         "AVG(a) AS TMP_0",
         "SUM(b) AS TMP_1",
@@ -87,7 +87,7 @@ class AggregateTest extends TableTestBase {
 
     val calcNode = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(sourceTable),
       // ReduceExpressionsRule will add cast for Project node by force
       // if the input of the Project node has constant expression.
       term("select", "CAST(1) AS a", "b", "c"),
@@ -116,7 +116,7 @@ class AggregateTest extends TableTestBase {
 
     val calcNode = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(sourceTable),
       // ReduceExpressionsRule will add cast for Project node by force
       // if the input of the Project node has constant expression.
       term("select", "CAST(1) AS a", "b", "c", "c._1 AS $f3"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/CalcTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/CalcTest.scala
index c38dd48..ea9880c 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/CalcTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/CalcTest.scala
@@ -38,7 +38,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "a._1 AS a$_1",
         "a._2 AS a$_2",
@@ -61,7 +61,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "a._1 AS a$_1",
         "a._2 AS a$_2",
@@ -85,7 +85,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "giveMeCaseClass$().my AS _c0",
         "giveMeCaseClass$().clazz AS _c1",
@@ -110,7 +110,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(sourceTable),
       term("select", "a", "b")
     )
 
@@ -124,7 +124,7 @@ class CalcTest extends TableTestBase {
     val resultTable1 = sourceTable.select('*)
     val resultTable2 = sourceTable.select('a, 'b, 'c, 'd)
 
-    val expected = batchTableNode(0)
+    val expected = batchTableNode(sourceTable)
 
     util.verifyTable(resultTable1, expected)
     util.verifyTable(resultTable2, expected)
@@ -140,7 +140,7 @@ class CalcTest extends TableTestBase {
       "DataSetAggregate",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(sourceTable),
         term("select", "a", "b")
       ),
       term("select", "SUM(a) AS TMP_0", "MAX(b) AS TMP_1")
@@ -160,7 +160,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(sourceTable),
       term("select", "MyHashCode$(c) AS _c0", "b")
     )
 
@@ -179,7 +179,7 @@ class CalcTest extends TableTestBase {
         "DataSetDistinct",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(sourceTable),
           term("select", "a", "c")
         ),
         term("distinct", "a", "c")
@@ -200,7 +200,7 @@ class CalcTest extends TableTestBase {
       "DataSetDistinct",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(sourceTable),
         term("select", "a", "c")
       ),
       term("distinct", "a", "c")
@@ -222,7 +222,7 @@ class CalcTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(sourceTable),
             term("select", "a", "c")
           ),
           term("groupBy", "c"),
@@ -247,7 +247,7 @@ class CalcTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(sourceTable),
             // As stated in https://issues.apache.org/jira/browse/CALCITE-1584
             // Calcite planner doesn't promise to retain field names.
             term("select", "a", "UPPER(c) AS k")
@@ -274,7 +274,7 @@ class CalcTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(sourceTable),
             // As stated in https://issues.apache.org/jira/browse/CALCITE-1584
             // Calcite planner doesn't promise to retain field names.
             term("select", "a", "MyHashCode$(c) AS k")
@@ -301,7 +301,7 @@ class CalcTest extends TableTestBase {
         "DataSetCalc",
         unaryNode(
           "DataSetAggregate",
-          batchTableNode(0),
+          batchTableNode(sourceTable),
           term("groupBy", "word"),
           term("select", "word", "SUM(frequency) AS TMP_0")
         ),
@@ -323,7 +323,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(sourceTable),
       term("select", "a", "b"),
       term("where", "AND(AND(>(a, 0), <(b, 2)), =(MOD(a, 2), 1))")
     )
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/ColumnFunctionsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/ColumnFunctionsTest.scala
index 786ee84..f325f0c 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/ColumnFunctionsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/ColumnFunctionsTest.scala
@@ -51,7 +51,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataSetSort",
-        batchTableNode(0),
+        batchTableNode(t),
         term("orderBy", "a ASC", "b ASC", "c ASC")
       )
 
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/CorrelateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/CorrelateTest.scala
index 91fa483..9ec49d1 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/CorrelateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/CorrelateTest.scala
@@ -45,7 +45,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "s"),
@@ -66,7 +66,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", s"${function.functionIdentifier}($$2, '$$')"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c, '$$'))"),
         term("select", "a", "b", "c", "s"),
@@ -92,7 +92,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "s"),
@@ -119,7 +119,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(table),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "s"),
@@ -149,7 +149,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(sourceTable),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "d", "e"),
@@ -196,7 +196,7 @@ class CorrelateTest extends TableTestBase {
       "DataSetCalc",
       unaryNode(
         "DataSetCorrelate",
-        batchTableNode(0),
+        batchTableNode(sourceTable),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "d", "e"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/GroupWindowTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/GroupWindowTest.scala
index d040f82..1720a66 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/GroupWindowTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/GroupWindowTest.scala
@@ -46,7 +46,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "TumblingGroupWindow('w, 'long, 2)"),
       term("select", "string", "COUNT(int) AS TMP_0")
@@ -69,7 +69,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "TumblingGroupWindow('w, 'long, 5.millis)"),
       term("select", "string", "myWeightedAvg(long, int) AS TMP_0")
@@ -90,7 +90,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "TumblingGroupWindow('w, 'long, 5.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0")
@@ -113,7 +113,7 @@ class GroupWindowTest extends TableTestBase {
       "DataSetWindowAggregate",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(table),
         term("select", "long", "int")
       ),
       term("window", "TumblingGroupWindow('w, 'long, 5.millis)"),
@@ -137,7 +137,7 @@ class GroupWindowTest extends TableTestBase {
       "DataSetWindowAggregate",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(table),
         term("select", "long", "int")
       ),
       term("window", "TumblingGroupWindow('w, 'long, 2)"),
@@ -159,7 +159,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "TumblingGroupWindow('w, 'ts, 7200000.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0",
@@ -181,7 +181,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "TumblingGroupWindow('w, 'ts, 7200000.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0",
@@ -207,7 +207,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SlidingGroupWindow('w, 'long, 8.millis, 10.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0")
@@ -228,7 +228,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SlidingGroupWindow('w, 'long, 2, 1)"),
       term("select", "string", "COUNT(int) AS TMP_0")
@@ -251,7 +251,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SlidingGroupWindow('w, 'long, 8.millis, 10.millis)"),
       term("select", "string", "myWeightedAvg(long, int) AS TMP_0")
@@ -274,7 +274,7 @@ class GroupWindowTest extends TableTestBase {
       "DataSetWindowAggregate",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(table),
         term("select", "long", "int")
       ),
       term("window", "SlidingGroupWindow('w, 'long, 8.millis, 10.millis)"),
@@ -298,7 +298,7 @@ class GroupWindowTest extends TableTestBase {
       "DataSetWindowAggregate",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(table),
         term("select", "long", "int")
       ),
       term("window", "SlidingGroupWindow('w, 'long, 2, 1)"),
@@ -320,7 +320,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SlidingGroupWindow('w, 'ts, 3600000.millis, 600000.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0",
@@ -342,7 +342,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SlidingGroupWindow('w, 'ts, 3600000.millis, 600000.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0",
@@ -368,7 +368,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SessionGroupWindow('w, 'long, 7.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0")
@@ -391,7 +391,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SessionGroupWindow('w, 'long, 7.millis)"),
       term("select", "string", "myWeightedAvg(long, int) AS TMP_0")
@@ -412,7 +412,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SessionGroupWindow('w, 'ts, 1800000.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0",
@@ -434,7 +434,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetWindowAggregate",
-      batchTableNode(0),
+      batchTableNode(table),
       term("groupBy", "string"),
       term("window", "SessionGroupWindow('w, 'ts, 1800000.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0",
@@ -461,7 +461,7 @@ class GroupWindowTest extends TableTestBase {
           "DataSetWindowAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "rowtime", "c", "*(c, c) AS $f2")
           ),
           term("window", "TumblingGroupWindow('w, 'rowtime, 900000.millis)"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/JoinTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/JoinTest.scala
index ce62252..1dcb803 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/JoinTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/JoinTest.scala
@@ -42,12 +42,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(s),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -74,12 +74,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(s),
           term("select", "y", "z")
         ),
         term("where", "AND(=(a, z), <(b, 2))"),
@@ -106,10 +106,10 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
-        batchTableNode(1),
+        batchTableNode(s),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "LeftOuterJoin")
@@ -134,12 +134,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(s),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -166,12 +166,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(s),
           term("select", "x", "z")
         ),
         term("where", "AND(=(a, z), <(x, 2))"),
@@ -198,10 +198,10 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
-        batchTableNode(1),
+        batchTableNode(s),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "RightOuterJoin")
@@ -226,12 +226,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(s),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -258,12 +258,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(s),
           term("select", "y", "z")
         ),
         term("where", "AND(=(a, z), <(b, 2))"),
@@ -290,10 +290,10 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t),
           term("select", "a", "b")
         ),
-        batchTableNode(1),
+        batchTableNode(s),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "FullOuterJoin")
@@ -321,12 +321,12 @@ class JoinTest extends TableTestBase {
         "DataSetJoin",
         unaryNode(
           "DataSetCalc",
-          batchTableNode(0),
+          batchTableNode(t1),
           term("select", "b", "c")
         ),
         unaryNode(
           "DataSetCalc",
-          batchTableNode(1),
+          batchTableNode(t2),
           term("select", "e", "f")
         ),
         term("where", "=(b, e)"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/SetOperatorsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/SetOperatorsTest.scala
index f0f1ca3..c093033 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/SetOperatorsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/SetOperatorsTest.scala
@@ -43,12 +43,12 @@ class SetOperatorsTest extends TableTestBase {
       "DataSetCalc",
       binaryNode(
         "DataSetJoin",
-        batchTableNode(0),
+        batchTableNode(t),
         unaryNode(
           "DataSetDistinct",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(t),
             term("select", "a AS a1"),
             term("where", "=(b, 'two')")
           ),
@@ -73,7 +73,7 @@ class SetOperatorsTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(t),
       term("select", "IN(b, 1972-02-22 07:12:00.333) AS b2")
     )
 
@@ -93,12 +93,12 @@ class SetOperatorsTest extends TableTestBase {
       "DataSetUnion",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(t),
         term("select", "a")
       ),
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(t),
         term("select", "CASE(>(c, 0), b, null) AS _c0")
       ),
       term("all", "true"),
@@ -122,12 +122,12 @@ class SetOperatorsTest extends TableTestBase {
       "DataSetUnion",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(t),
         term("select", "a")
       ),
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(t),
         term("select", "b")
       ),
       term("all", "true"),
@@ -156,13 +156,13 @@ class SetOperatorsTest extends TableTestBase {
           "DataSetUnion",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(left),
             term("select", "a", "b", "c"),
             term("where", ">(a, 0)")
           ),
           unaryNode(
             "DataSetCalc",
-            batchTableNode(1),
+            batchTableNode(right),
             term("select", "a", "b", "c"),
             term("where", ">(a, 0)")
           ),
@@ -197,13 +197,13 @@ class SetOperatorsTest extends TableTestBase {
           "DataSetMinus",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(left),
             term("select", "a", "b", "c"),
             term("where", ">(a, 0)")
           ),
           unaryNode(
             "DataSetCalc",
-            batchTableNode(1),
+            batchTableNode(right),
             term("select", "a", "b", "c"),
             term("where", ">(a, 0)")
           ),
@@ -232,12 +232,12 @@ class SetOperatorsTest extends TableTestBase {
       "DataSetUnion",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(left),
         term("select", "b", "c")
       ),
       unaryNode(
         "DataSetCalc",
-        batchTableNode(1),
+        batchTableNode(right),
         term("select", "b", "c")
       ),
       term("all", "true"),
@@ -262,12 +262,12 @@ class SetOperatorsTest extends TableTestBase {
       "DataSetMinus",
       unaryNode(
         "DataSetCalc",
-        batchTableNode(0),
+        batchTableNode(left),
         term("select", "b", "c")
       ),
       unaryNode(
         "DataSetCalc",
-        batchTableNode(1),
+        batchTableNode(right),
         term("select", "b", "c")
       ),
       term("minus", "b", "c")
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CorrelateStringExpressionTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CorrelateStringExpressionTest.scala
index 4d4abaa..c5bdf3c 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CorrelateStringExpressionTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/CorrelateStringExpressionTest.scala
@@ -19,13 +19,14 @@
 package org.apache.flink.table.api.batch.table.stringexpr
 
 import org.apache.flink.api.java.typeutils.RowTypeInfo
+import org.apache.flink.api.java.{DataSet => JDataSet}
 import org.apache.flink.api.scala._
+import org.apache.flink.table.api.Types
 import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.{Table, Types}
 import org.apache.flink.table.utils.{PojoTableFunc, TableFunc2, _}
-import org.apache.flink.table.utils._
 import org.apache.flink.types.Row
 import org.junit.Test
+import org.mockito.Mockito.{mock, when}
 
 class CorrelateStringExpressionTest extends TableTestBase {
 
@@ -34,8 +35,15 @@ class CorrelateStringExpressionTest extends TableTestBase {
     val util = batchTestUtil()
 
     val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
-    val sTab = util.addTable[(Int, Long, String)]("Table1", 'a, 'b, 'c)
-    val jTab = util.addJavaTable[Row](typeInfo, "Table2", "a, b, c")
+
+    val jDs = mock(classOf[JDataSet[Row]])
+    when(jDs.getType).thenReturn(typeInfo)
+
+    val sDs = mock(classOf[DataSet[Row]])
+    when(sDs.javaSet).thenReturn(jDs)
+
+    val jTab = util.javaTableEnv.fromDataSet(jDs, "a, b, c")
+    val sTab = util.tableEnv.fromDataSet(sDs, 'a, 'b, 'c)
 
     // test cross join
     val func1 = new TableFunc1
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/SetOperatorsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/SetOperatorsTest.scala
index f134dd9..c753187 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/SetOperatorsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/batch/table/stringexpr/SetOperatorsTest.scala
@@ -40,12 +40,12 @@ class SetOperatorsTest extends TableTestBase {
       "DataSetCalc",
       binaryNode(
         "DataSetJoin",
-        batchTableNode(0),
+        batchTableNode(t),
         unaryNode(
           "DataSetDistinct",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(t),
             term("select", "a AS a1"),
             term("where", "=(b, 'two')")
           ),
@@ -70,7 +70,7 @@ class SetOperatorsTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(t),
       term("select", "IN(b, CAST('1972-02-22 07:12:00.333')) AS b2")
     )
 
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/ExplainTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/ExplainTest.scala
index 9c3defe..ec3d0d7 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/ExplainTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/ExplainTest.scala
@@ -20,7 +20,9 @@ package org.apache.flink.table.api.stream
 
 import org.apache.flink.api.scala._
 import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
+import org.apache.flink.table.api.Table
 import org.apache.flink.table.api.scala._
+import org.apache.flink.table.utils.TableTestUtil.streamTableNode
 import org.apache.flink.test.util.AbstractTestBase
 import org.junit.Assert.assertEquals
 import org.junit._
@@ -34,15 +36,14 @@ class ExplainTest extends AbstractTestBase {
     val env = StreamExecutionEnvironment.getExecutionEnvironment
     val tEnv = StreamTableEnvironment.create(env)
 
-    val table = env.fromElements((1, "hello"))
-      .toTable(tEnv, 'a, 'b)
-      .filter("a % 2 = 0")
+    val scan = env.fromElements((1, "hello")).toTable(tEnv, 'a, 'b)
+    val table = scan.filter("a % 2 = 0")
 
     val result = replaceString(tEnv.explain(table))
 
     val source = scala.io.Source.fromFile(testFilePath +
       "../../src/test/scala/resources/testFilterStream0.out").mkString
-    val expect = replaceString(source)
+    val expect = replaceString(source, scan)
     assertEquals(expect, result)
   }
 
@@ -59,11 +60,27 @@ class ExplainTest extends AbstractTestBase {
 
     val source = scala.io.Source.fromFile(testFilePath +
       "../../src/test/scala/resources/testUnionStream0.out").mkString
-    val expect = replaceString(source)
+    val expect = replaceString(source, table1, table2)
     assertEquals(expect, result)
   }
 
-  def replaceString(s: String): String = {
+  def replaceString(s: String, t1: Table, t2: Table): String = {
+    replaceSourceNode(replaceSourceNode(replaceString(s), t1, 0), t2, 1)
+  }
+
+  def replaceString(s: String, t: Table): String = {
+    replaceSourceNode(replaceString(s), t, 0)
+  }
+
+  private def replaceSourceNode(s: String, t: Table, idx: Int) = {
+    replaceString(s)
+      .replace(
+        s"%logicalSourceNode$idx%", streamTableNode(t)
+          .replace("DataStreamScan", "FlinkLogicalDataStreamScan"))
+      .replace(s"%sourceNode$idx%", streamTableNode(t))
+  }
+
+  def replaceString(s: String) = {
     /* Stage {id} is ignored, because id keeps incrementing in test class
      * while StreamExecutionEnvironment is up
      */
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentTest.scala
index 9f192de..b4d3726 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/StreamTableEnvironmentTest.scala
@@ -47,7 +47,7 @@ class StreamTableEnvironmentTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select", "a, b, c"),
       term("where", ">(b, 12)"))
 
@@ -60,8 +60,8 @@ class StreamTableEnvironmentTest extends TableTestBase {
 
     val expected2 = binaryNode(
       "DataStreamUnion",
-      streamTableNode(1),
-      streamTableNode(0),
+      streamTableNode(table2),
+      streamTableNode(table),
       term("all", "true"),
       term("union all", "d, e, f"))
 
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/AggregateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/AggregateTest.scala
index 9cd5fd6..1a45587 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/AggregateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/AggregateTest.scala
@@ -35,7 +35,7 @@ import org.junit.Test
 class AggregateTest extends TableTestBase {
 
   private val streamUtil: StreamTableTestUtil = streamTestUtil()
-  streamUtil.addTable[(Int, String, Long)](
+  private val table = streamUtil.addTable[(Int, String, Long)](
     "MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
 
   @Test
@@ -49,7 +49,7 @@ class AggregateTest extends TableTestBase {
           "DataStreamGroupAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "b", "a")
           ),
           term("groupBy", "b"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/CorrelateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/CorrelateTest.scala
index f179ae6..89ccb76 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/CorrelateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/CorrelateTest.scala
@@ -33,7 +33,7 @@ class CorrelateTest extends TableTestBase {
   def testCrossJoin(): Unit = {
     val util = streamTestUtil()
     val func1 = new TableFunc1
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func1", func1)
 
     val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(c)) AS T(s)"
@@ -42,7 +42,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "func1($cor0.c)"),
         term("correlate", s"table(func1($$cor0.c))"),
         term("select", "a", "b", "c", "f0"),
@@ -63,7 +63,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "func1($cor0.c, '$')"),
         term("correlate", s"table(func1($$cor0.c, '$$'))"),
         term("select", "a", "b", "c", "f0"),
@@ -81,7 +81,7 @@ class CorrelateTest extends TableTestBase {
   def testLeftOuterJoinWithLiteralTrue(): Unit = {
     val util = streamTestUtil()
     val func1 = new TableFunc1
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func1", func1)
 
     val sqlQuery = "SELECT c, s FROM MyTable LEFT JOIN LATERAL TABLE(func1(c)) AS T(s) ON TRUE"
@@ -90,7 +90,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "func1($cor0.c)"),
         term("correlate", s"table(func1($$cor0.c))"),
         term("select", "a", "b", "c", "f0"),
@@ -108,8 +108,8 @@ class CorrelateTest extends TableTestBase {
   def testLeftOuterJoinAsSubQuery(): Unit = {
     val util = streamTestUtil()
     val func1 = new TableFunc1
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-    util.addTable[(Int, Long, String)]("MyTable2", 'a2, 'b2, 'c2)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table1 = util.addTable[(Int, Long, String)]("MyTable2", 'a2, 'b2, 'c2)
     util.addFunction("func1", func1)
 
     val sqlQuery =
@@ -122,12 +122,12 @@ class CorrelateTest extends TableTestBase {
 
     val expected = binaryNode(
       "DataStreamJoin",
-      streamTableNode(1),
+      streamTableNode(table1),
       unaryNode(
         "DataStreamCalc",
         unaryNode(
           "DataStreamCorrelate",
-          streamTableNode(0),
+          streamTableNode(table),
           term("invocation", "func1($cor0.c)"),
           term("correlate", "table(func1($cor0.c))"),
           term("select", "a", "b", "c", "f0"),
@@ -148,7 +148,7 @@ class CorrelateTest extends TableTestBase {
   def testCustomType(): Unit = {
     val util = streamTestUtil()
     val func2 = new TableFunc2
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func2", func2)
 
     val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len)"
@@ -157,7 +157,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "func2($cor0.c)"),
         term("correlate", s"table(func2($$cor0.c))"),
         term("select", "a", "b", "c", "f0", "f1"),
@@ -175,7 +175,7 @@ class CorrelateTest extends TableTestBase {
   @Test
   def testHierarchyType(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     val function = new HierarchyTableFunction
     util.addFunction("hierarchy", function)
 
@@ -185,7 +185,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "hierarchy($cor0.c)"),
         term("correlate", s"table(hierarchy($$cor0.c))"),
         term("select", "a", "b", "c", "f0", "f1", "f2"),
@@ -203,7 +203,7 @@ class CorrelateTest extends TableTestBase {
   @Test
   def testPojoType(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     val function = new PojoTableFunc
     util.addFunction("pojo", function)
 
@@ -213,7 +213,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "pojo($cor0.c)"),
         term("correlate", s"table(pojo($$cor0.c))"),
         term("select", "a", "b", "c", "age", "name"),
@@ -232,7 +232,7 @@ class CorrelateTest extends TableTestBase {
   def testRowType(): Unit = {
     val util = streamTestUtil()
     val rowType = Types.ROW(Types.INT, Types.BOOLEAN, Types.ROW(Types.INT, Types.INT, Types.INT))
-    util.addTable[Row]("MyTable", 'a, 'b, 'c)(rowType)
+    val table = util.addTable[Row]("MyTable", 'a, 'b, 'c)(rowType)
     val function = new TableFunc5
     util.addFunction("tableFunc5", function)
 
@@ -242,7 +242,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "tableFunc5($cor0.c)"),
         term("correlate", "table(tableFunc5($cor0.c))"),
         term("select", "a", "b", "c", "f0", "f1", "f2"),
@@ -265,7 +265,7 @@ class CorrelateTest extends TableTestBase {
   def testFilter(): Unit = {
     val util = streamTestUtil()
     val func2 = new TableFunc2
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func2", func2)
 
     val sqlQuery = "SELECT c, name, len FROM MyTable, LATERAL TABLE(func2(c)) AS T(name, len) " +
@@ -275,7 +275,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "func2($cor0.c)"),
         term("correlate", s"table(func2($$cor0.c))"),
         term("select", "a", "b", "c", "f0", "f1"),
@@ -295,7 +295,7 @@ class CorrelateTest extends TableTestBase {
   def testScalarFunction(): Unit = {
     val util = streamTestUtil()
     val func1 = new TableFunc1
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func1", func1)
 
     val sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1(SUBSTRING(c, 2))) AS T(s)"
@@ -304,7 +304,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "func1(SUBSTRING($cor0.c, 2))"),
         term("correlate", s"table(func1(SUBSTRING($$cor0.c, 2)))"),
         term("select", "a", "b", "c", "f0"),
@@ -322,7 +322,7 @@ class CorrelateTest extends TableTestBase {
   def testTableFunctionWithVariableArguments(): Unit = {
     val util = streamTestUtil()
     val func1 = new JavaVarsArgTableFunc0
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
     util.addFunction("func1", func1)
 
     var sqlQuery = "SELECT c, s FROM MyTable, LATERAL TABLE(func1('hello', 'world', c)) AS T(s)"
@@ -331,7 +331,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "func1('hello', 'world', $cor0.c)"),
         term("correlate", s"table(func1('hello', 'world', $$cor0.c))"),
         term("select", "a", "b", "c", "f0"),
@@ -354,7 +354,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", "func2('hello', 'world', $cor0.c)"),
         term("correlate", s"table(func2('hello', 'world', $$cor0.c))"),
         term("select", "a", "b", "c", "f0"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/DistinctAggregateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/DistinctAggregateTest.scala
index 20e5beb..0333531 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/DistinctAggregateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/DistinctAggregateTest.scala
@@ -26,7 +26,7 @@ import org.junit.{Ignore, Test}
 
 class DistinctAggregateTest extends TableTestBase {
   private val streamUtil: StreamTableTestUtil = streamTestUtil()
-  streamUtil.addTable[(Int, String, Long)](
+  private val table = streamUtil.addTable[(Int, String, Long)](
     "MyTable",
     'a, 'b, 'c,
     'proctime.proctime, 'rowtime.rowtime)
@@ -40,7 +40,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a, b, c")
         ),
         term("groupBy", "a, b, c"),
@@ -61,7 +61,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a")
         ),
         term("groupBy", "a"),
@@ -82,7 +82,7 @@ class DistinctAggregateTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "c", "a", "b")
         ),
         term("groupBy", "c"),
@@ -103,7 +103,7 @@ class DistinctAggregateTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "rowtime", "a")
       ),
       term("window", "TumblingGroupWindow('w$, 'rowtime, 900000.millis)"),
@@ -125,7 +125,7 @@ class DistinctAggregateTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "rowtime", "a")
       ),
       term("window", "SlidingGroupWindow('w$, 'rowtime, 3600000.millis, 900000.millis)"),
@@ -148,7 +148,7 @@ class DistinctAggregateTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "a", "rowtime", "c")
       ),
       term("groupBy", "a"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/GroupWindowTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/GroupWindowTest.scala
index b2e6139..42e2a76 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/GroupWindowTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/GroupWindowTest.scala
@@ -27,7 +27,7 @@ import org.junit.Test
 
 class GroupWindowTest extends TableTestBase {
   private val streamUtil: StreamTableTestUtil = streamTestUtil()
-  streamUtil.addTable[(Int, String, Long)](
+  private val table = streamUtil.addTable[(Int, String, Long)](
     "MyTable", 'a, 'b, 'c, 'proctime.proctime, 'rowtime.rowtime)
 
   @Test
@@ -48,7 +48,7 @@ class GroupWindowTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "rowtime", "c", "a")
           ),
           term("window", "TumblingGroupWindow('w$, 'rowtime, 900000.millis)"),
@@ -82,7 +82,7 @@ class GroupWindowTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "proctime", "c", "a")
           ),
           term("window", "SlidingGroupWindow('w$, 'proctime, 3600000.millis, 900000.millis)"),
@@ -117,7 +117,7 @@ class GroupWindowTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "proctime", "c", "a")
           ),
           term("window", "SessionGroupWindow('w$, 'proctime, 900000.millis)"),
@@ -149,7 +149,7 @@ class GroupWindowTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "rowtime")
           ),
           term("window", "TumblingGroupWindow('w$, 'rowtime, 900000.millis)"),
@@ -185,7 +185,7 @@ class GroupWindowTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "rowtime, a")
           ),
           term("window", "SlidingGroupWindow('w$, 'rowtime, 60000.millis, 900000.millis)"),
@@ -233,7 +233,7 @@ class GroupWindowTest extends TableTestBase {
               "DataStreamGroupWindowAggregate",
               unaryNode(
                 "DataStreamCalc",
-                streamTableNode(0),
+                streamTableNode(table),
                 term("select", "rowtime, a")
               ),
               term("window", "TumblingGroupWindow('w$, 'rowtime, 2.millis)"),
@@ -277,7 +277,7 @@ class GroupWindowTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "rowtime", "c", "*(c, c) AS $f2")
           ),
           term("window", "TumblingGroupWindow('w$, 'rowtime, 900000.millis)"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/JoinTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/JoinTest.scala
index be3da6d..f9a1621 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/JoinTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/JoinTest.scala
@@ -33,8 +33,18 @@ import org.junit.Test
   */
 class JoinTest extends TableTestBase {
   private val streamUtil: StreamTableTestUtil = streamTestUtil()
-  streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c.rowtime, 'proctime.proctime)
-  streamUtil.addTable[(Int, String, Long)]("MyTable2", 'a, 'b, 'c.rowtime, 'proctime.proctime)
+  private val table = streamUtil.addTable[(Int, String, Long)](
+    "MyTable",
+    'a,
+    'b,
+    'c.rowtime,
+    'proctime.proctime)
+  private val table1 = streamUtil.addTable[(Int, String, Long)](
+    "MyTable2",
+    'a,
+    'b,
+    'c.rowtime,
+    'proctime.proctime)
 
   // Tests for inner join
   @Test
@@ -55,12 +65,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "proctime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "proctime")
           ),
           term("where",
@@ -93,12 +103,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "c")
           ),
           term("where",
@@ -131,12 +141,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "proctime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "proctime")
           ),
           term("where",
@@ -169,12 +179,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "c")
           ),
           term("where",
@@ -203,11 +213,11 @@ class JoinTest extends TableTestBase {
       unaryNode("DataStreamCalc",
         binaryNode("DataStreamWindowJoin",
           unaryNode("DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "proctime")
           ),
           unaryNode("DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "proctime")
           ),
           term("where", "AND(=(a, a0), =(PROCTIME(proctime), PROCTIME(proctime0)))"),
@@ -233,11 +243,11 @@ class JoinTest extends TableTestBase {
       unaryNode("DataStreamCalc",
         binaryNode("DataStreamWindowJoin",
           unaryNode("DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c")
           ),
           unaryNode("DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "c")
           ),
           term("where", "AND(=(a, a0), =(CAST(c), CAST(c0)))"),
@@ -254,13 +264,11 @@ class JoinTest extends TableTestBase {
     val streamUtil: StreamTableTestUtil = streamTestUtil()
 
     val t1 = streamUtil.addTable[(Int, Long, String)]("Table1", 'a, 'b, 'c, 'proctime.proctime)
-      .select('a, 'b, 'c, 'proctime, nullOf(Types.LONG) as 'nullField)
-
     val t2 = streamUtil.addTable[(Int, Long, String)]("Table2", 'a, 'b, 'c, 'proctime.proctime)
-      .select('a, 'b, 'c, 'proctime, 12L as 'nullField)
 
-    streamUtil.tableEnv.registerTable("T1", t1)
-    streamUtil.tableEnv.registerTable("T2", t2)
+    streamUtil.tableEnv
+      .registerTable("T1", t1.select('a, 'b, 'c, 'proctime, nullOf(Types.LONG) as 'nullField))
+    streamUtil.tableEnv.registerTable("T2", t2.select('a, 'b, 'c, 'proctime, 12L as 'nullField))
 
     val sqlQuery =
       """
@@ -275,12 +283,12 @@ class JoinTest extends TableTestBase {
       unaryNode("DataStreamCalc",
         binaryNode("DataStreamWindowJoin",
           unaryNode("DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(t1),
             term("select", "a", "c", "proctime", "null AS nullField")
           ),
           unaryNode("DataStreamCalc",
-            streamTableNode(1),
-            term("select", "a", "c", "proctime", "12 AS nullField")
+            streamTableNode(t2),
+            term("select", "a", "c", "proctime", "CAST(12) AS nullField")
           ),
           term("where", "AND(=(a, a0), =(nullField, nullField0), >=(PROCTIME(proctime), " +
             "-(PROCTIME(proctime0), 5000)), <=(PROCTIME(proctime), +(PROCTIME(proctime0), 5000)))"),
@@ -313,12 +321,12 @@ class JoinTest extends TableTestBase {
             "DataStreamWindowJoin",
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(0),
+              streamTableNode(table),
               term("select", "a", "b", "c")
             ),
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(1),
+              streamTableNode(table1),
               term("select", "a", "b", "c")
             ),
             term("where",
@@ -358,12 +366,12 @@ class JoinTest extends TableTestBase {
             "DataStreamWindowJoin",
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(0),
+              streamTableNode(table),
               term("select", "a", "b", "c")
             ),
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(1),
+              streamTableNode(table1),
               term("select", "a", "b", "c")
             ),
             term("where",
@@ -401,12 +409,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "proctime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "proctime")
           ),
           term("where",
@@ -439,12 +447,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "c")
           ),
           term("where",
@@ -478,12 +486,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "proctime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "proctime")
           ),
           term("where",
@@ -516,12 +524,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "c")
           ),
           term("where",
@@ -555,12 +563,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "proctime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "proctime")
           ),
           term("where",
@@ -593,12 +601,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "c")
           ),
           term("where",
@@ -633,12 +641,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "c")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(table1),
             term("select", "a", "b", "c")
           ),
           term("where",
@@ -791,8 +799,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testLeftOuterJoinEquiPred(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val left = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val right = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t LEFT OUTER JOIN s ON a = z"
     val result = util.tableEnv.sqlQuery(query)
@@ -803,12 +811,12 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(left),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(right),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -824,8 +832,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testLeftOuterJoinEquiAndLocalPred(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val left = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val right = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t LEFT OUTER JOIN s ON a = z AND b < 2"
     val result = util.tableEnv.sqlQuery(query)
@@ -836,12 +844,12 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(left),
           term("select", "a", "b", "<(b, 2) AS $f3")
         ),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(right),
           term("select", "y", "z")
         ),
         term("where", "AND(=(a, z), $f3)"),
@@ -857,8 +865,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testLeftOuterJoinEquiAndNonEquiPred(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val left = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val right = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t LEFT OUTER JOIN s ON a = z AND b < x"
     val result = util.tableEnv.sqlQuery(query)
@@ -869,10 +877,10 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(left),
           term("select", "a", "b")
         ),
-        streamTableNode(1),
+        streamTableNode(right),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "LeftOuterJoin")
@@ -886,8 +894,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testRightOuterJoinEquiPred(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val left = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val right = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t RIGHT OUTER JOIN s ON a = z"
     val result = util.tableEnv.sqlQuery(query)
@@ -898,12 +906,12 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(left),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(right),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -919,8 +927,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testRightOuterJoinEquiAndLocalPred(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val left = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val right = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, x FROM t RIGHT OUTER JOIN s ON a = z AND x < 2"
     val result = util.tableEnv.sqlQuery(query)
@@ -931,12 +939,12 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(left),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(right),
           term("select", "x", "z", "<(x, 2) AS $f3")
         ),
         term("where", "AND(=(a, z), $f3)"),
@@ -952,8 +960,8 @@ class JoinTest extends TableTestBase {
   @Test
   def testRightOuterJoinEquiAndNonEquiPred(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
-    util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
+    val left = util.addTable[(Int, Long, String)]("t", 'a, 'b, 'c)
+    val right = util.addTable[(Long, String, Int)]("s", 'x, 'y, 'z)
 
     val query = "SELECT b, y FROM t RIGHT OUTER JOIN s ON a = z AND b < x"
     val result = util.tableEnv.sqlQuery(query)
@@ -964,10 +972,10 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(left),
           term("select", "a", "b")
         ),
-        streamTableNode(1),
+        streamTableNode(right),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "RightOuterJoin")
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/MatchRecognizeTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/MatchRecognizeTest.scala
index 98a8d08..9088bd0 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/MatchRecognizeTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/MatchRecognizeTest.scala
@@ -26,7 +26,12 @@ import org.junit.Test
 
 class MatchRecognizeTest extends TableTestBase {
   private val streamUtil: StreamTableTestUtil = streamTestUtil()
-  streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c.rowtime, 'proctime.proctime)
+  private val table = streamUtil.addTable[(Int, String, Long)](
+    "MyTable",
+    'a,
+    'b,
+    'c.rowtime,
+    'proctime.proctime)
 
   @Test
   def testSimpleWithDefaults(): Unit = {
@@ -45,7 +50,7 @@ class MatchRecognizeTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamMatch",
-      streamTableNode(0),
+      streamTableNode(table),
       term("orderBy", "proctime ASC"),
       term("measures", "FINAL(A.a) AS aa"),
       term("rowsPerMatch", "ONE ROW PER MATCH"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/OverWindowTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/OverWindowTest.scala
index 9dbc2f2..0efcb1e 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/OverWindowTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/OverWindowTest.scala
@@ -26,7 +26,7 @@ import org.junit.Test
 
 class OverWindowTest extends TableTestBase {
   private val streamUtil: StreamTableTestUtil = streamTestUtil()
-  streamUtil.addTable[(Int, String, Long)](
+  private val table = streamUtil.addTable[(Int, String, Long)](
     "MyTable",
     'a, 'b, 'c,
     'proctime.proctime, 'rowtime.rowtime)
@@ -62,7 +62,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "c", "proctime")
           ),
           term("partitionBy", "b"),
@@ -103,7 +103,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("partitionBy", "c"),
@@ -143,7 +143,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("partitionBy", "c"),
@@ -180,7 +180,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("partitionBy", "a"),
@@ -225,7 +225,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("orderBy", "proctime"),
@@ -260,7 +260,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("orderBy", "proctime"),
@@ -304,7 +304,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("partitionBy", "c"),
@@ -337,7 +337,7 @@ class OverWindowTest extends TableTestBase {
         "DataStreamCalc",
         unaryNode(
           "DataStreamOverAggregate",
-          streamTableNode(0),
+          streamTableNode(table),
           term("partitionBy", "c"),
           term("orderBy", "proctime"),
           term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
@@ -371,7 +371,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("orderBy", "proctime"),
@@ -403,7 +403,7 @@ class OverWindowTest extends TableTestBase {
         "DataStreamCalc",
         unaryNode(
           "DataStreamOverAggregate",
-          streamTableNode(0),
+          streamTableNode(table),
           term("orderBy", "proctime"),
           term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
           term("select", "a", "b", "c", "proctime", "rowtime", "COUNT(a) AS w0$o0")
@@ -428,7 +428,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("partitionBy", "c"),
@@ -456,7 +456,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("partitionBy", "c"),
@@ -484,7 +484,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("orderBy", "rowtime"),
@@ -511,7 +511,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("orderBy", "rowtime"),
@@ -545,7 +545,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("partitionBy", "c"),
@@ -573,7 +573,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("partitionBy", "c"),
@@ -614,7 +614,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("orderBy", "rowtime"),
@@ -641,7 +641,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("orderBy", "rowtime"),
@@ -690,7 +690,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("partitionBy", "a"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/SetOperatorsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/SetOperatorsTest.scala
index e5ee7e9..fcce9a7 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/SetOperatorsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/SetOperatorsTest.scala
@@ -28,12 +28,12 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testInOnLiterals(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val resultStr = (1 to 30).mkString(", ")
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select", "a", "b", "c"),
       term("where", s"IN(b, $resultStr)")
     )
@@ -46,12 +46,12 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testNotInOnLiterals(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val resultStr = (1 to 30).mkString(", ")
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select", "a", "b", "c"),
       term("where", s"NOT IN(b, $resultStr)")
     )
@@ -64,8 +64,8 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testInUncorrelated(): Unit = {
     val streamUtil = streamTestUtil()
-    streamUtil.addTable[(Int, Long, String)]("tableA", 'a, 'b, 'c)
-    streamUtil.addTable[(Int, String)]("tableB", 'x, 'y)
+    val table = streamUtil.addTable[(Int, Long, String)]("tableA", 'a, 'b, 'c)
+    val table1 = streamUtil.addTable[(Int, String)]("tableB", 'x, 'y)
 
     val sqlQuery =
       s"""
@@ -78,12 +78,12 @@ class SetOperatorsTest extends TableTestBase {
         "DataStreamCalc",
         binaryNode(
           "DataStreamJoin",
-          streamTableNode(0),
+          streamTableNode(table),
           unaryNode(
             "DataStreamGroupAggregate",
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(1),
+              streamTableNode(table1),
               term("select", "x")
             ),
             term("groupBy", "x"),
@@ -102,8 +102,8 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testInUncorrelatedWithConditionAndAgg(): Unit = {
     val streamUtil = streamTestUtil()
-    streamUtil.addTable[(Int, Long, String)]("tableA", 'a, 'b, 'c)
-    streamUtil.addTable[(Int, String)]("tableB", 'x, 'y)
+    val table = streamUtil.addTable[(Int, Long, String)]("tableA", 'a, 'b, 'c)
+    val table1 = streamUtil.addTable[(Int, String)]("tableB", 'x, 'y)
 
     val sqlQuery =
       s"""
@@ -116,7 +116,7 @@ class SetOperatorsTest extends TableTestBase {
         "DataStreamCalc",
         binaryNode(
           "DataStreamJoin",
-          streamTableNode(0),
+          streamTableNode(table),
           unaryNode(
             "DataStreamGroupAggregate",
             unaryNode(
@@ -125,7 +125,7 @@ class SetOperatorsTest extends TableTestBase {
                 "DataStreamGroupAggregate",
                 unaryNode(
                   "DataStreamCalc",
-                  streamTableNode(1),
+                  streamTableNode(table1),
                   term("select", "x", "y"),
                   term("where", "LIKE(y, '%Hanoi%')")
                 ),
@@ -150,9 +150,9 @@ class SetOperatorsTest extends TableTestBase {
   @Test
   def testInWithMultiUncorrelatedCondition(): Unit = {
     val streamUtil = streamTestUtil()
-    streamUtil.addTable[(Int, Long, String)]("tableA", 'a, 'b, 'c)
-    streamUtil.addTable[(Int, String)]("tableB", 'x, 'y)
-    streamUtil.addTable[(Long, Int)]("tableC", 'w, 'z)
+    val table = streamUtil.addTable[(Int, Long, String)]("tableA", 'a, 'b, 'c)
+    val table1 = streamUtil.addTable[(Int, String)]("tableB", 'x, 'y)
+    val table2 = streamUtil.addTable[(Long, Int)]("tableC", 'w, 'z)
 
     val sqlQuery =
       s"""
@@ -170,12 +170,12 @@ class SetOperatorsTest extends TableTestBase {
             "DataStreamCalc",
             binaryNode(
               "DataStreamJoin",
-              streamTableNode(0),
+              streamTableNode(table),
               unaryNode(
                 "DataStreamGroupAggregate",
                 unaryNode(
                   "DataStreamCalc",
-                  streamTableNode(1),
+                  streamTableNode(table1),
                   term("select", "x")
                 ),
                 term("groupBy", "x"),
@@ -191,7 +191,7 @@ class SetOperatorsTest extends TableTestBase {
             "DataStreamGroupAggregate",
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(2),
+              streamTableNode(table2),
               term("select", "w")
             ),
             term("groupBy", "w"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/SortTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/SortTest.scala
index 087ae7d..b8ad376 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/SortTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/SortTest.scala
@@ -27,7 +27,7 @@ import org.junit.Test
 class SortTest extends TableTestBase {
 
   private val streamUtil: StreamTableTestUtil = streamTestUtil()
-  streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c,
+  private val table = streamUtil.addTable[(Int, String, Long)]("MyTable", 'a, 'b, 'c,
       'proctime.proctime, 'rowtime.rowtime)
   
   @Test
@@ -39,7 +39,7 @@ class SortTest extends TableTestBase {
       unaryNode(
         "DataStreamCalc",
         unaryNode("DataStreamSort",
-          streamTableNode(0),
+          streamTableNode(table),
           term("orderBy", "proctime ASC", "c ASC")),
         term("select", "a", "PROCTIME(proctime) AS proctime", "c"))
 
@@ -55,7 +55,7 @@ class SortTest extends TableTestBase {
       unaryNode(
         "DataStreamCalc",
         unaryNode("DataStreamSort",
-          streamTableNode(0),
+          streamTableNode(table),
           term("orderBy", "rowtime ASC, c ASC")),
         term("select", "a", "rowtime", "c"))
        
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/TemporalTableJoinTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/TemporalTableJoinTest.scala
index 27c40bb..c758660 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/TemporalTableJoinTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/TemporalTableJoinTest.scala
@@ -22,7 +22,8 @@ import java.sql.Timestamp
 import org.apache.flink.api.scala._
 import org.apache.flink.table.api.TableException
 import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.stream.table.TemporalTableJoinTest._
+import org.apache.flink.table.plan.logical.rel.LogicalTemporalTableJoin.TEMPORAL_JOIN_CONDITION
+import org.apache.flink.table.utils.TableTestUtil.{binaryNode, streamTableNode, term, unaryNode}
 import org.apache.flink.table.utils._
 import org.hamcrest.Matchers.startsWith
 import org.junit.Test
@@ -57,7 +58,7 @@ class TemporalTableJoinTest extends TableTestBase {
       "o_amount * rate as rate " +
       "FROM Orders AS o, " +
       "LATERAL TABLE (Rates(o.o_rowtime)) AS r " +
-      "WHERE currency = o_currency";
+      "WHERE currency = o_currency"
 
     util.verifySql(sqlQuery, getExpectedSimpleJoinPlan())
   }
@@ -68,7 +69,7 @@ class TemporalTableJoinTest extends TableTestBase {
       "o_amount * rate as rate " +
       "FROM ProctimeOrders AS o, " +
       "LATERAL TABLE (ProctimeRates(o.o_proctime)) AS r " +
-      "WHERE currency = o_currency";
+      "WHERE currency = o_currency"
 
     util.verifySql(sqlQuery, getExpectedSimpleProctimeJoinPlan())
   }
@@ -81,8 +82,8 @@ class TemporalTableJoinTest extends TableTestBase {
   @Test
   def testComplexJoin(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(String, Int)]("Table3", 't3_comment, 't3_secondary_key)
-    util.addTable[(Timestamp, String, Long, String, Int)](
+    val thirdTable = util.addTable[(String, Int)]("Table3", 't3_comment, 't3_secondary_key)
+    val orders = util.addTable[(Timestamp, String, Long, String, Int)](
       "Orders", 'o_rowtime.rowtime, 'o_comment, 'o_amount, 'o_currency, 'o_secondary_key)
 
     val ratesHistory = util.addTable[(Timestamp, String, String, Int, Int)](
@@ -101,9 +102,49 @@ class TemporalTableJoinTest extends TableTestBase {
         "LATERAL TABLE (Rates(o_rowtime)) AS r " +
         "WHERE currency = o_currency OR secondary_key = o_secondary_key), " +
         "Table3 " +
-      "WHERE t3_secondary_key = secondary_key";
-
-    util.verifySql(sqlQuery, getExpectedComplexJoinPlan())
+      "WHERE t3_secondary_key = secondary_key"
+
+    util.verifySql(sqlQuery, binaryNode(
+      "DataStreamJoin",
+      unaryNode(
+        "DataStreamCalc",
+        binaryNode(
+          "DataStreamTemporalTableJoin",
+          unaryNode(
+            "DataStreamCalc",
+            streamTableNode(orders),
+            term("select", "o_rowtime, o_amount, o_currency, o_secondary_key")
+          ),
+          unaryNode(
+            "DataStreamCalc",
+            streamTableNode(ratesHistory),
+            term("select", "rowtime, currency, rate, secondary_key"),
+            term("where", ">(rate, 110)")
+          ),
+          term(
+            "where",
+            "AND(" +
+              s"${TEMPORAL_JOIN_CONDITION.getName}(o_rowtime, rowtime, currency), " +
+              "OR(=(currency, o_currency), =(secondary_key, o_secondary_key)))"),
+          term(
+            "join",
+            "o_rowtime",
+            "o_amount",
+            "o_currency",
+            "o_secondary_key",
+            "rowtime",
+            "currency",
+            "rate",
+            "secondary_key"),
+          term("joinType", "InnerJoin")
+        ),
+        term("select", "*(o_amount, rate) AS rate", "secondary_key")
+      ),
+      streamTableNode(thirdTable),
+      term("where", "=(t3_secondary_key, secondary_key)"),
+      term("join", "rate, secondary_key, t3_comment, t3_secondary_key"),
+      term("joinType", "InnerJoin")
+    ))
   }
 
   @Test
@@ -115,7 +156,7 @@ class TemporalTableJoinTest extends TableTestBase {
       "o_amount * rate as rate " +
       "FROM Orders AS o, " +
       "LATERAL TABLE (Rates(TIMESTAMP '2016-06-27 10:10:42.123')) AS r " +
-      "WHERE currency = o_currency";
+      "WHERE currency = o_currency"
 
     util.printSql(sqlQuery)
   }
@@ -125,8 +166,69 @@ class TemporalTableJoinTest extends TableTestBase {
     expectedException.expect(classOf[TableException])
     expectedException.expectMessage(startsWith("Cannot generate a valid execution plan"))
 
-    val sqlQuery = "SELECT * FROM LATERAL TABLE (Rates(TIMESTAMP '2016-06-27 10:10:42.123'))";
+    val sqlQuery = "SELECT * FROM LATERAL TABLE (Rates(TIMESTAMP '2016-06-27 10:10:42.123'))"
 
     util.printSql(sqlQuery)
   }
+
+  def getExpectedSimpleJoinPlan(): String = {
+    unaryNode(
+      "DataStreamCalc",
+      binaryNode(
+        "DataStreamTemporalTableJoin",
+        streamTableNode(orders),
+        streamTableNode(ratesHistory),
+        term("where",
+          "AND(" +
+            s"${TEMPORAL_JOIN_CONDITION.getName}(o_rowtime, rowtime, currency), " +
+            "=(currency, o_currency))"),
+        term("join", "o_amount", "o_currency", "o_rowtime", "currency", "rate", "rowtime"),
+        term("joinType", "InnerJoin")
+      ),
+      term("select", "*(o_amount, rate) AS rate")
+    )
+  }
+
+  def getExpectedSimpleProctimeJoinPlan(): String = {
+    unaryNode(
+      "DataStreamCalc",
+      binaryNode(
+        "DataStreamTemporalTableJoin",
+        streamTableNode(proctimeOrders),
+        unaryNode(
+          "DataStreamCalc",
+          streamTableNode(proctimeRatesHistory),
+          term("select", "currency, rate")),
+        term("where",
+          "AND(" +
+            s"${TEMPORAL_JOIN_CONDITION.getName}(o_proctime, currency), " +
+            "=(currency, o_currency))"),
+        term("join", "o_amount", "o_currency", "o_proctime", "currency", "rate"),
+        term("joinType", "InnerJoin")
+      ),
+      term("select", "*(o_amount, rate) AS rate")
+    )
+  }
+
+  def getExpectedTemporalTableFunctionOnTopOfQueryPlan(): String = {
+    unaryNode(
+      "DataStreamCalc",
+      binaryNode(
+        "DataStreamTemporalTableJoin",
+        streamTableNode(orders),
+        unaryNode(
+          "DataStreamCalc",
+          streamTableNode(ratesHistory),
+          term("select", "currency", "*(rate, 2) AS rate", "rowtime"),
+          term("where", ">(rate, 100)")),
+        term("where",
+          "AND(" +
+            s"${TEMPORAL_JOIN_CONDITION.getName}(o_rowtime, rowtime, currency), " +
+            "=(currency, o_currency))"),
+        term("join", "o_amount", "o_currency", "o_rowtime", "currency", "rate", "rowtime"),
+        term("joinType", "InnerJoin")
+      ),
+      term("select", "*(o_amount, rate) AS rate")
+    )
+  }
 }
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/UnionTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/UnionTest.scala
index b8bd222..306a316 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/UnionTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/sql/UnionTest.scala
@@ -32,18 +32,18 @@ class UnionTest extends TableTestBase {
   @Test
   def testUnionAllNullableCompositeType() = {
     val streamUtil = streamTestUtil()
-    streamUtil.addTable[((Int, String), (Int, String), Int)]("A", 'a, 'b, 'c)
+    val table = streamUtil.addTable[((Int, String), (Int, String), Int)]("A", 'a, 'b, 'c)
 
     val expected = binaryNode(
       "DataStreamUnion",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "a")
       ),
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "CASE(>(c, 0), b, null) AS EXPR$0")
       ),
       term("all", "true"),
@@ -62,18 +62,18 @@ class UnionTest extends TableTestBase {
     val typeInfo = Types.ROW(
       new GenericTypeInfo(classOf[NonPojo]),
       new GenericTypeInfo(classOf[NonPojo]))
-    streamUtil.addJavaTable(typeInfo, "A", "a, b")
+    val table = streamUtil.addJavaTable(typeInfo, "A", "a, b")
 
     val expected = binaryNode(
       "DataStreamUnion",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "a")
       ),
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "b")
       ),
       term("all", "true"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/AggregateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/AggregateTest.scala
index 626306f..70652af 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/AggregateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/AggregateTest.scala
@@ -43,7 +43,7 @@ class AggregateTest extends TableTestBase {
         "DataStreamCalc",
         unaryNode(
           "DataStreamGroupAggregate",
-          streamTableNode(0),
+          streamTableNode(table),
           term("groupBy", "b"),
           term("select", "b", "SUM(DISTINCT a) AS TMP_0", "COUNT(DISTINCT c) AS TMP_1")
         ),
@@ -67,7 +67,7 @@ class AggregateTest extends TableTestBase {
         "DataStreamCalc",
         unaryNode(
           "DataStreamGroupAggregate",
-          streamTableNode(0),
+          streamTableNode(table),
           term("groupBy", "c"),
           term(
             "select",
@@ -96,7 +96,7 @@ class AggregateTest extends TableTestBase {
           "DataStreamGroupAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b")
           ),
           term("groupBy", "b"),
@@ -124,7 +124,7 @@ class AggregateTest extends TableTestBase {
           "DataStreamGroupAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "4 AS four", "b")
           ),
           term("groupBy", "a", "four"),
@@ -152,7 +152,7 @@ class AggregateTest extends TableTestBase {
           "DataStreamGroupAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "b", "4 AS four", "a")
           ),
           term("groupBy", "b", "four"),
@@ -180,7 +180,7 @@ class AggregateTest extends TableTestBase {
           "DataStreamGroupAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "MOD(b, 3) AS d", "c")
           ),
           term("groupBy", "d"),
@@ -206,7 +206,7 @@ class AggregateTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b"),
           term("where", "=(b, 2)")
         ),
@@ -230,7 +230,7 @@ class AggregateTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "b", "CAST(a) AS a0")
         ),
         term("groupBy", "b"),
@@ -254,7 +254,7 @@ class AggregateTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "a", "rowtime")
       ),
       term("window", "TumblingGroupWindow('w, 'rowtime, 900000.millis)"),
@@ -278,7 +278,7 @@ class AggregateTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "a", "rowtime")
       ),
       term("window", "SlidingGroupWindow('w, 'rowtime, 3600000.millis, 900000.millis)"),
@@ -303,7 +303,7 @@ class AggregateTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "a", "c", "rowtime")
       ),
       term("groupBy", "a"),
@@ -333,7 +333,7 @@ class AggregateTest extends TableTestBase {
           "DataStreamGroupAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b")
           ),
           term("groupBy", "b"),
@@ -363,7 +363,7 @@ class AggregateTest extends TableTestBase {
           "DataStreamGroupAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b")
           ),
           term("groupBy", "b"),
@@ -390,7 +390,7 @@ class AggregateTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b")
         ),
         term("groupBy", "b"),
@@ -418,7 +418,7 @@ class AggregateTest extends TableTestBase {
           "DataStreamGroupAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b")
           ),
           term("groupBy", "b"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/CalcTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/CalcTest.scala
index 3d068d6..6c7487c 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/CalcTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/CalcTest.scala
@@ -48,7 +48,7 @@ class CalcTest extends TableTestBase {
         "DataStreamGroupWindowAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(sourceTable),
           term("select", "a", "rowtime", "UPPER(c) AS $f5")
         ),
         term("window", "TumblingGroupWindow('w, 'rowtime, 5.millis)"),
@@ -74,7 +74,7 @@ class CalcTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(sourceTable),
             term("select", "a", "b", "rowtime", "UPPER(c) AS $f5")
           ),
           term("groupBy", "b"),
@@ -98,7 +98,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term("select", "a", "b"),
       term("where", "AND(AND(>(a, 0), <(b, 2)), =(MOD(a, 2), 1))")
     )
@@ -115,7 +115,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term("select", "a", "b", "c"),
       term("where", s"AND(IN(b, ${(1 to 30).mkString(", ")}), =(c, 'xx'))")
     )
@@ -132,7 +132,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term("select", "a", "b", "c"),
       term("where", s"OR(NOT IN(b, ${(1 to 30).mkString(", ")}), <>(c, 'xx'))")
     )
@@ -153,7 +153,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term(
         "select", "a", "b", "c", "CONCAT(c, '_kid_last') AS kid", "+(a, 2) AS _c4, b AS b2",
         "'literal_value' AS _c6")
@@ -169,7 +169,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term("select", "a AS a2", "b AS b2")
     )
     util.verifyTable(resultTable, expected)
@@ -183,7 +183,7 @@ class CalcTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term("select", "c")
     )
     util.verifyTable(resultTable, expected)
@@ -193,12 +193,12 @@ class CalcTest extends TableTestBase {
   def testSimpleMap(): Unit = {
     val util = streamTestUtil()
 
-    val resultTable = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-      .map(Func23('a, 'b, 'c))
+    val sourceTable = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val resultTable = sourceTable.map(Func23('a, 'b, 'c))
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term("select", "Func23$(a, b, c).f0 AS _c0, Func23$(a, b, c).f1 AS _c1, " +
         "Func23$(a, b, c).f2 AS _c2, Func23$(a, b, c).f3 AS _c3")
     )
@@ -210,12 +210,12 @@ class CalcTest extends TableTestBase {
   def testScalarResult(): Unit = {
     val util = streamTestUtil()
 
-    val resultTable = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
-      .map(Func1('a))
+    val sourceTable = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val resultTable = sourceTable.map(Func1('a))
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term("select", "Func1$(a) AS _c0")
     )
 
@@ -226,13 +226,14 @@ class CalcTest extends TableTestBase {
   def testMultiMap(): Unit = {
     val util = streamTestUtil()
 
-    val resultTable = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val sourceTable = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val resultTable = sourceTable
       .map(Func23('a, 'b, 'c))
       .map(Func24('_c0, '_c1, '_c2, '_c3))
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(sourceTable),
       term("select",
            "Func24$(Func23$(a, b, c).f0, Func23$(a, b, c).f1, " +
              "Func23$(a, b, c).f2, Func23$(a, b, c).f3).f0 AS _c0, " +
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/ColumnFunctionsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/ColumnFunctionsTest.scala
index bfde639..cc41f4a 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/ColumnFunctionsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/ColumnFunctionsTest.scala
@@ -33,7 +33,7 @@ import org.junit.Test
   */
 class ColumnFunctionsTest extends TableTestBase {
 
-  val util = new StreamTableTestUtil()
+  val util = streamTestUtil()
 
   private def verifyAll(tab1: Table, tab2: Table, expected: String): Unit = {
     util.verifyTable(tab1, expected)
@@ -52,7 +52,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "TestFunc$(double, long) AS _c0")
       )
 
@@ -69,7 +69,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "b", "c", "a", "e", "f", "d")
       )
 
@@ -86,7 +86,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "a", "b", "c", "f")
       )
 
@@ -108,7 +108,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "e", "f")
       )
 
@@ -125,7 +125,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "CONCAT(string1, string2) AS _c0")
       )
 
@@ -143,8 +143,8 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       binaryNode(
         "DataStreamJoin",
-        streamTableNode(0),
-        streamTableNode(1),
+        streamTableNode(t1),
+        streamTableNode(t2),
         term("where", "=(int1, int2)"),
         term("join", "int1", "long1", "string1", "int2", "long2", "string2"),
         term("joinType", "InnerJoin")
@@ -165,7 +165,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(t),
         term("invocation",
           "org$apache$flink$table$utils$TableFunc0$497a630d2a145bca99673bcd05a53d2b($2)"),
         term("correlate", "table(TableFunc0(string))"),
@@ -190,7 +190,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "int", "long", "string1", "string2"),
         term("where", "=(CONCAT(string1, string2), 'a')")
       )
@@ -215,7 +215,7 @@ class ColumnFunctionsTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "a", "b", "c")
         ),
         term("groupBy", "a", "b"),
@@ -246,7 +246,7 @@ class ColumnFunctionsTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(t),
             term("select", "a", "CAST(b) AS b", "c")
           ),
           term("groupBy", "a", "b"),
@@ -295,7 +295,7 @@ class ColumnFunctionsTest extends TableTestBase {
         "DataStreamCalc",
         unaryNode(
           "DataStreamOverAggregate",
-          streamTableNode(0),
+          streamTableNode(table),
           term("partitionBy", "c"),
           term("orderBy", "proctime"),
           term("rows", "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"),
@@ -318,7 +318,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "a", "b", "c", "TestFunc$(a, b) AS d")
       )
 
@@ -335,7 +335,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "a AS d", "b")
       )
 
@@ -352,7 +352,7 @@ class ColumnFunctionsTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "c")
       )
 
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/CorrelateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/CorrelateTest.scala
index 1d3ae67..31a197d 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/CorrelateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/CorrelateTest.scala
@@ -45,7 +45,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "s"),
@@ -66,7 +66,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", s"${function.functionIdentifier}($$2, '$$')"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c, '$$'))"),
         term("select", "a", "b", "c", "s"),
@@ -92,7 +92,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "s"),
@@ -120,7 +120,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation",
              s"${function.functionIdentifier}(${scalarFunc.functionIdentifier}($$2))"),
         term("correlate", s"table(${function.getClass.getSimpleName}(Func13(c)))"),
@@ -146,7 +146,7 @@ class CorrelateTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCorrelate",
-      streamTableNode(0),
+      streamTableNode(table),
       term("invocation", s"${function.functionIdentifier}($$2)"),
       term("correlate", "table(HierarchyTableFunction(c))"),
       term("select", "a", "b", "c", "name", "adult", "len"),
@@ -169,7 +169,7 @@ class CorrelateTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCorrelate",
-      streamTableNode(0),
+      streamTableNode(table),
       term("invocation", s"${function.functionIdentifier}($$2)"),
       term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
       term("select", "a", "b", "c", "age", "name"),
@@ -197,7 +197,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "name", "len"),
@@ -223,7 +223,7 @@ class CorrelateTest extends TableTestBase {
 
     val expected = unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("invocation",  s"${function.functionIdentifier}(SUBSTRING($$2, 2, CHAR_LENGTH($$2)))"),
         term("correlate",
              s"table(${function.getClass.getSimpleName}(SUBSTRING(c, 2, CHAR_LENGTH(c))))"),
@@ -253,7 +253,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(sourceTable),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "d", "e"),
@@ -299,7 +299,7 @@ class CorrelateTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(sourceTable),
         term("invocation", s"${function.functionIdentifier}($$2)"),
         term("correlate", s"table(${function.getClass.getSimpleName}(c))"),
         term("select", "a", "b", "c", "d", "e"),
@@ -320,14 +320,15 @@ class CorrelateTest extends TableTestBase {
     val util = streamTestUtil()
 
     val func2 = new TableFunc2
-    val resultTable = util.addTable[(Int, Long, String)]("MyTable", 'f1, 'f2, 'f3)
+    val sourceTable = util.addTable[(Int, Long, String)]("MyTable", 'f1, 'f2, 'f3)
+    val resultTable = sourceTable
       .flatMap(func2('f3))
 
     val expected = unaryNode(
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(sourceTable),
         term("invocation", s"${func2.functionIdentifier}($$2)"),
         term("correlate", "table(TableFunc2(f3))"),
         term("select", "f1", "f2", "f3", "f0", "f1_0"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTableAggregateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTableAggregateTest.scala
index 37796c0..fc09465 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTableAggregateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTableAggregateTest.scala
@@ -53,7 +53,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
             "DataStreamGroupWindowTableAggregate",
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(0),
+              streamTableNode(table),
               term("select", "a", "b", "c", "e")
             ),
             term("groupBy", "c"),
@@ -86,7 +86,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
           "DataStreamGroupWindowTableAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "e", "MOD(b, 5) AS bb")
           ),
           term("groupBy", "bb"),
@@ -111,7 +111,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "c", "e")
         ),
         term("groupBy", "c"),
@@ -135,7 +135,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "c", "d")
         ),
         term("groupBy", "c"),
@@ -161,7 +161,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
           "DataStreamGroupWindowTableAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "c", "e")
           ),
           term("groupBy", "c"),
@@ -187,7 +187,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "c", "e")
         ),
         term("groupBy", "c"),
@@ -211,7 +211,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "c", "d")
         ),
         term("groupBy", "c"),
@@ -235,7 +235,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "c", "d")
         ),
         term("groupBy", "c"),
@@ -259,7 +259,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "e")
         ),
         term("window", "TumblingGroupWindow('w, 'e, 50.millis)"),
@@ -282,7 +282,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "e")
         ),
         term("window", "TumblingGroupWindow('w, 'e, 2)"),
@@ -305,7 +305,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "d")
         ),
         term("window", "TumblingGroupWindow('w, 'd, 5.millis)"),
@@ -329,7 +329,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "e")
         ),
         term("window", "SlidingGroupWindow('w, 'e, 50.millis, 50.millis)"),
@@ -352,7 +352,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "e")
         ),
         term("window", "SlidingGroupWindow('w, 'e, 2, 1)"),
@@ -375,7 +375,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "d")
         ),
         term("window", "SlidingGroupWindow('w, 'd, 8.millis, 10.millis)"),
@@ -398,7 +398,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "d")
         ),
         term("window", "SlidingGroupWindow('w, 'd, 8.millis, 10.millis)"),
@@ -421,7 +421,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
         "DataStreamGroupWindowTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "b", "d")
         ),
         term("window", "SessionGroupWindow('w, 'd, 7.millis)"),
@@ -446,7 +446,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
           "DataStreamGroupWindowTableAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "c", "d")
           ),
           term("groupBy", "c"),
@@ -475,7 +475,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
           "DataStreamGroupWindowTableAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "c", "d")
           ),
           term("groupBy", "c"),
@@ -504,7 +504,7 @@ class GroupWindowTableAggregateTest extends TableTestBase {
           "DataStreamGroupWindowTableAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "c", "d")
           ),
           term("groupBy", "c"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTest.scala
index d1aade2..4cef488 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/GroupWindowTest.scala
@@ -49,7 +49,7 @@ class GroupWindowTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "int", "string", "proctime")
           ),
           term("groupBy", "string"),
@@ -78,7 +78,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "string", "proctime")
       ),
       term("groupBy", "string"),
@@ -103,7 +103,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "string", "proctime")
       ),
       term("groupBy", "string"),
@@ -126,7 +126,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamGroupWindowAggregate",
-      streamTableNode(0),
+      streamTableNode(table),
       term("groupBy", "string"),
       term("window", "TumblingGroupWindow('w, 'long, 5.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0")
@@ -149,7 +149,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamGroupWindowAggregate",
-      streamTableNode(0),
+      streamTableNode(table),
       term("groupBy", "string"),
       term("window", "TumblingGroupWindow('w, 'rowtime, 5.millis)"),
       term("select", "string", "myWeightedAvg(long, int) AS TMP_0")
@@ -172,7 +172,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "string", "proctime")
       ),
       term("groupBy", "string"),
@@ -197,7 +197,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "string", "proctime")
       ),
       term("groupBy", "string"),
@@ -222,7 +222,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "string", "rowtime")
       ),
       term("groupBy", "string"),
@@ -246,7 +246,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamGroupWindowAggregate",
-      streamTableNode(0),
+      streamTableNode(table),
       term("groupBy", "string"),
       term("window", "SlidingGroupWindow('w, 'long, 8.millis, 10.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0")
@@ -269,7 +269,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamGroupWindowAggregate",
-      streamTableNode(0),
+      streamTableNode(table),
       term("groupBy", "string"),
       term("window", "SlidingGroupWindow('w, 'rowtime, 8.millis, 10.millis)"),
       term("select", "string", "myWeightedAvg(long, int) AS TMP_0")
@@ -290,7 +290,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamGroupWindowAggregate",
-      streamTableNode(0),
+      streamTableNode(table),
       term("groupBy", "string"),
       term("window", "SessionGroupWindow('w, 'long, 7.millis)"),
       term("select", "string", "COUNT(int) AS TMP_0")
@@ -313,7 +313,7 @@ class GroupWindowTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamGroupWindowAggregate",
-      streamTableNode(0),
+      streamTableNode(table),
       term("groupBy", "string"),
       term("window", "SessionGroupWindow('w, 'rowtime, 7.millis)"),
       term("select", "string", "myWeightedAvg(long, int) AS TMP_0")
@@ -336,7 +336,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "string", "proctime")
       ),
       term("groupBy", "string"),
@@ -361,7 +361,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "proctime")
       ),
       term("window", "TumblingGroupWindow('w, 'proctime, 2)"),
@@ -385,7 +385,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "rowtime")
       ),
       term("window", "TumblingGroupWindow('w, 'rowtime, 5.millis)"),
@@ -410,7 +410,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "long")
       ),
       term("window", "TumblingGroupWindow('w, 'long, 5.millis)"),
@@ -434,7 +434,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "proctime")
       ),
       term("window", "SlidingGroupWindow('w, 'proctime, 50.millis, 50.millis)"),
@@ -458,7 +458,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "proctime")
       ),
       term("window", "SlidingGroupWindow('w, 'proctime, 2, 1)"),
@@ -482,7 +482,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "rowtime")
       ),
       term("window", "SlidingGroupWindow('w, 'rowtime, 8.millis, 10.millis)"),
@@ -507,7 +507,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "long", "int")
       ),
       term("window", "SlidingGroupWindow('w, 'long, 8.millis, 10.millis)"),
@@ -531,7 +531,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "long", "int")
       ),
       term("window", "SessionGroupWindow('w, 'long, 7.millis)"),
@@ -555,7 +555,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "string", "rowtime")
       ),
       term("groupBy", "string"),
@@ -593,7 +593,7 @@ class GroupWindowTest extends TableTestBase {
         "DataStreamCalc",
         unaryNode(
           "DataStreamGroupWindowAggregate",
-          streamTableNode(0),
+          streamTableNode(table),
           term("groupBy", "string, int2, int3"),
           term("window", "SlidingGroupWindow('w, 'proctime, 2, 1)"),
           term(
@@ -623,7 +623,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamGroupWindowAggregate",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(table),
         term("select", "int", "string", "rowtime")
       ),
       term("groupBy", "string"),
@@ -652,7 +652,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamGroupWindowAggregate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("groupBy", "string"),
         term("window", "SessionGroupWindow('w, 'long, 3.millis)"),
         term("select",
@@ -682,7 +682,7 @@ class GroupWindowTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamGroupWindowAggregate",
-        streamTableNode(0),
+        streamTableNode(table),
         term("groupBy", "string"),
         term("window", "TumblingGroupWindow('w, 'long, 5.millis)"),
         term("select",
@@ -721,7 +721,7 @@ class GroupWindowTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "rowtime", "c", "*(c, c) AS $f2")
           ),
           term("window", "TumblingGroupWindow('w, 'rowtime, 900000.millis)"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/JoinTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/JoinTest.scala
index 138497c..ab60d00 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/JoinTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/JoinTest.scala
@@ -49,12 +49,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lrtime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rrtime")
           ),
           term("where", "AND(=(a, d), >=(CAST(lrtime), -(CAST(rrtime), 300000))," +
@@ -84,12 +84,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lptime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rptime")
           ),
           term("where", "AND(=(a, d), >=(PROCTIME(lptime), -(PROCTIME(rptime), 1000)), " +
@@ -119,12 +119,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lptime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rptime")
           ),
           term("where", "AND(=(a, d), =(PROCTIME(lptime), PROCTIME(rptime)))"),
@@ -151,8 +151,8 @@ class JoinTest extends TableTestBase {
     val expected =
       binaryNode(
         "DataStreamWindowJoin",
-        streamTableNode(0),
-        streamTableNode(1),
+        streamTableNode(left),
+        streamTableNode(right),
         term("where",
           "AND(=(a, d), >=(CAST(lrtime), -(CAST(rrtime), 300000)), " +
             "<(CAST(lrtime), CAST(rrtime)), >(CAST(lrtime), f))"),
@@ -182,12 +182,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lrtime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rrtime")
           ),
           term("where", "AND(=(a, d), >=(CAST(lrtime), -(CAST(rrtime), 300000))," +
@@ -217,12 +217,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lptime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rptime")
           ),
           term("where", "AND(=(a, d), >=(PROCTIME(lptime), -(PROCTIME(rptime), 1000)), " +
@@ -255,12 +255,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lrtime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rrtime")
           ),
           term("where", "AND(=(a, d), >=(CAST(lrtime), -(CAST(rrtime), 300000))," +
@@ -290,12 +290,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lptime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rptime")
           ),
           term("where", "AND(=(a, d), >=(PROCTIME(lptime), -(PROCTIME(rptime), 1000)), " +
@@ -328,12 +328,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lrtime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rrtime")
           ),
           term("where", "AND(=(a, d), >=(CAST(lrtime), -(CAST(rrtime), 300000))," +
@@ -363,12 +363,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lptime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rptime")
           ),
           term("where", "AND(=(a, d), >=(PROCTIME(lptime), -(PROCTIME(rptime), 1000)), " +
@@ -399,12 +399,12 @@ class JoinTest extends TableTestBase {
           "DataStreamWindowJoin",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(left),
             term("select", "a", "lrtime")
           ),
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(1),
+            streamTableNode(right),
             term("select", "d", "e", "rrtime")
           ),
           term("where", "AND(=(a, d), >=(CAST(lrtime), -(CAST(rrtime), 300000))," +
@@ -433,12 +433,12 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(s),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -465,12 +465,12 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(s),
           term("select", "y", "z")
         ),
         term("where", "AND(=(a, z), <(b, 2))"),
@@ -497,10 +497,10 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "a", "b")
         ),
-        streamTableNode(1),
+        streamTableNode(s),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "LeftOuterJoin")
@@ -525,12 +525,12 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(s),
           term("select", "y", "z")
         ),
         term("where", "=(a, z)"),
@@ -557,12 +557,12 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "a", "b")
         ),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(s),
           term("select", "x", "z")
         ),
         term("where", "AND(=(a, z), <(x, 2))"),
@@ -589,10 +589,10 @@ class JoinTest extends TableTestBase {
         "DataStreamJoin",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "a", "b")
         ),
-        streamTableNode(1),
+        streamTableNode(s),
         term("where", "AND(=(a, z), <(b, x))"),
         term("join", "a", "b", "x", "y", "z"),
         term("joinType", "RightOuterJoin")
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/OverWindowTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/OverWindowTest.scala
index c411124..9e47d2a 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/OverWindowTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/OverWindowTest.scala
@@ -52,7 +52,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             // RexSimplify didn't simplify "CAST(1):BIGINT NOT NULL", see [CALCITE-2862]
             term("select", "a", "b", "c", "proctime", "1 AS $4")
           ),
@@ -89,7 +89,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "c", "proctime")
           ),
           term("partitionBy", "b"),
@@ -118,7 +118,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("partitionBy", "a"),
@@ -151,7 +151,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("orderBy", "proctime"),
@@ -177,7 +177,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("orderBy", "proctime"),
@@ -211,7 +211,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("partitionBy", "c"),
@@ -253,7 +253,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("partitionBy", "c"),
@@ -283,7 +283,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("orderBy", "proctime"),
@@ -322,7 +322,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "proctime")
           ),
           term("orderBy", "proctime"),
@@ -351,7 +351,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "c", "rowtime")
           ),
           term("partitionBy", "b"),
@@ -383,7 +383,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("partitionBy", "a"),
@@ -417,7 +417,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("orderBy", "rowtime"),
@@ -443,7 +443,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("orderBy", "rowtime"),
@@ -478,7 +478,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("partitionBy", "c"),
@@ -521,7 +521,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("partitionBy", "c"),
@@ -551,7 +551,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("orderBy", "rowtime"),
@@ -590,7 +590,7 @@ class OverWindowTest extends TableTestBase {
           "DataStreamOverAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "c", "rowtime")
           ),
           term("orderBy", "rowtime"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/SetOperatorsTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/SetOperatorsTest.scala
index dfbaf40..656147e 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/SetOperatorsTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/SetOperatorsTest.scala
@@ -45,13 +45,13 @@ class SetOperatorsTest extends TableTestBase {
             "DataStreamUnion",
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(0),
+              streamTableNode(left),
               term("select", "a", "b", "c"),
               term("where", ">(a, 0)")
             ),
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(1),
+              streamTableNode(right),
               term("select", "a", "b", "c"),
               term("where", ">(a, 0)")
             ),
@@ -81,12 +81,12 @@ class SetOperatorsTest extends TableTestBase {
       "DataStreamUnion",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(left),
         term("select", "b", "c")
       ),
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(1),
+        streamTableNode(right),
         term("select", "b", "c")
       ),
       term("all", "true"),
@@ -109,12 +109,12 @@ class SetOperatorsTest extends TableTestBase {
         "DataStreamCalc",
         binaryNode(
           "DataStreamJoin",
-          streamTableNode(0),
+          streamTableNode(tableA),
           unaryNode(
             "DataStreamGroupAggregate",
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(1),
+              streamTableNode(tableB),
               term("select", "x")
             ),
             term("groupBy", "x"),
@@ -144,7 +144,7 @@ class SetOperatorsTest extends TableTestBase {
         "DataStreamCalc",
         binaryNode(
           "DataStreamJoin",
-          streamTableNode(0),
+          streamTableNode(tableA),
           unaryNode(
             "DataStreamGroupAggregate",
             unaryNode(
@@ -153,7 +153,7 @@ class SetOperatorsTest extends TableTestBase {
                 "DataStreamGroupAggregate",
                 unaryNode(
                   "DataStreamCalc",
-                  streamTableNode(1),
+                  streamTableNode(tableB),
                   term("select", "x", "y"),
                   term("where", "LIKE(y, '%Hanoi%')")
                 ),
@@ -194,12 +194,12 @@ class SetOperatorsTest extends TableTestBase {
             "DataStreamCalc",
             binaryNode(
               "DataStreamJoin",
-              streamTableNode(0),
+              streamTableNode(tableA),
               unaryNode(
                 "DataStreamGroupAggregate",
                 unaryNode(
                   "DataStreamCalc",
-                  streamTableNode(1),
+                  streamTableNode(tableB),
                   term("select", "x")
                 ),
                 term("groupBy", "x"),
@@ -215,7 +215,7 @@ class SetOperatorsTest extends TableTestBase {
             "DataStreamGroupAggregate",
             unaryNode(
               "DataStreamCalc",
-              streamTableNode(2),
+              streamTableNode(tableC),
               term("select", "w")
             ),
             term("groupBy", "w"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TableAggregateTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TableAggregateTest.scala
index 938d2c5..5c44eab 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TableAggregateTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TableAggregateTest.scala
@@ -49,7 +49,7 @@ class TableAggregateTest extends TableTestBase {
           "DataStreamGroupTableAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b", "MOD(b, 5) AS bb")
           ),
           term("groupBy", "bb"),
@@ -74,7 +74,7 @@ class TableAggregateTest extends TableTestBase {
           "DataStreamGroupTableAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "a", "b")
           ),
           term("select", "EmptyTableAggFunc(a, b) AS (f0, f1)")
@@ -96,7 +96,7 @@ class TableAggregateTest extends TableTestBase {
         "DataStreamGroupTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "CAST(d) AS d", "PROCTIME(e) AS e")
         ),
         term("select", "EmptyTableAggFunc(d, e) AS (f0, f1)")
@@ -116,7 +116,7 @@ class TableAggregateTest extends TableTestBase {
         "DataStreamGroupTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "b")
         ),
         term("select", "EmptyTableAggFunc(b) AS (f0, f1)")
@@ -138,7 +138,7 @@ class TableAggregateTest extends TableTestBase {
           "DataStreamGroupTableAggregate",
           unaryNode(
             "DataStreamCalc",
-            streamTableNode(0),
+            streamTableNode(table),
             term("select", "b")
           ),
           term("select", "EmptyTableAggFunc(b) AS (f0, f1)")
@@ -167,7 +167,7 @@ class TableAggregateTest extends TableTestBase {
         "DataStreamGroupTableAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(table),
           term("select", "a", "c")
         ),
         term("groupBy", "c"),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TableSourceTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TableSourceTest.scala
index c6ba354..1b84081 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TableSourceTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TableSourceTest.scala
@@ -47,7 +47,8 @@ class TableSourceTest extends TableTestBase {
 
     val t = util.tableEnv.scan("rowTimeT").select("rowtime, id, name, val")
 
-    val expected = "StreamTableSourceScan(table=[[rowTimeT]], fields=[rowtime, id, name, val], " +
+    val expected = "StreamTableSourceScan(table=[[default_catalog, default_database, rowTimeT]], " +
+      "fields=[rowtime, id, name, val], " +
       "source=[TestTableSourceWithTime(id, rowtime, val, name)])"
     util.verifyTable(t, expected)
   }
@@ -70,7 +71,8 @@ class TableSourceTest extends TableTestBase {
 
     val t = util.tableEnv.scan("rowTimeT").select("rowtime, id, name, val")
 
-    val expected = "StreamTableSourceScan(table=[[rowTimeT]], fields=[rowtime, id, name, val], " +
+    val expected = "StreamTableSourceScan(table=[[default_catalog, default_database, rowTimeT]], " +
+      "fields=[rowtime, id, name, val], " +
       "source=[TestTableSourceWithTime(id, rowtime, val, name)])"
     util.verifyTable(t, expected)
   }
@@ -104,7 +106,8 @@ class TableSourceTest extends TableTestBase {
           "DataStreamGroupWindowAggregate",
           unaryNode(
             "DataStreamCalc",
-            "StreamTableSourceScan(table=[[rowTimeT]], fields=[rowtime, val, name], " +
+            "StreamTableSourceScan(table=[[default_catalog, default_database, rowTimeT]], " +
+              "fields=[rowtime, val, name], " +
               "source=[TestTableSourceWithTime(id, rowtime, val, name)])",
             term("select", "rowtime", "val", "name"),
             term("where", ">(val, 100)")
@@ -138,7 +141,8 @@ class TableSourceTest extends TableTestBase {
     val expected =
       unaryNode(
         "DataStreamCalc",
-        "StreamTableSourceScan(table=[[procTimeT]], fields=[id, proctime, val, name], " +
+        "StreamTableSourceScan(table=[[default_catalog, default_database, procTimeT]], " +
+          "fields=[id, proctime, val, name], " +
           "source=[TestTableSourceWithTime(id, proctime, val, name)])",
         term("select", "PROCTIME(proctime) AS proctime", "id", "name", "val")
       )
@@ -170,7 +174,8 @@ class TableSourceTest extends TableTestBase {
         "DataStreamCalc",
         unaryNode(
           "DataStreamOverAggregate",
-          "StreamTableSourceScan(table=[[procTimeT]], fields=[id, proctime, val, name], " +
+          "StreamTableSourceScan(table=[[default_catalog, default_database, procTimeT]], " +
+            "fields=[id, proctime, val, name], " +
             "source=[TestTableSourceWithTime(id, proctime, val, name)])",
           term("partitionBy", "id"),
           term("orderBy", "proctime"),
@@ -200,7 +205,7 @@ class TableSourceTest extends TableTestBase {
 
     val t = util.tableEnv.scan("T").select('name, 'val, 'id)
 
-    val expected = "StreamTableSourceScan(table=[[T]], " +
+    val expected = "StreamTableSourceScan(table=[[default_catalog, default_database, T]], " +
       "fields=[name, val, id], " +
       "source=[TestSource(physical fields: name, val, id)])"
     util.verifyTable(t, expected)
@@ -225,7 +230,7 @@ class TableSourceTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      "StreamTableSourceScan(table=[[T]], " +
+      "StreamTableSourceScan(table=[[default_catalog, default_database, T]], " +
         "fields=[ptime, name, val, id], " +
         "source=[TestSource(physical fields: name, val, id)])",
       term("select", "PROCTIME(ptime) AS ptime", "name", "val", "id")
@@ -249,7 +254,7 @@ class TableSourceTest extends TableTestBase {
 
     val t = util.tableEnv.scan("T").select('name, 'val, 'rtime, 'id)
 
-    val expected = "StreamTableSourceScan(table=[[T]], " +
+    val expected = "StreamTableSourceScan(table=[[default_catalog, default_database, T]], " +
       "fields=[name, val, rtime, id], " +
       "source=[TestSource(physical fields: name, val, rtime, id)])"
     util.verifyTable(t, expected)
@@ -271,7 +276,7 @@ class TableSourceTest extends TableTestBase {
 
     val t = util.tableEnv.scan("T").select('ptime)
 
-    val expected = "StreamTableSourceScan(table=[[T]], " +
+    val expected = "StreamTableSourceScan(table=[[default_catalog, default_database, T]], " +
       "fields=[ptime], " +
       "source=[TestSource(physical fields: )])"
     util.verifyTable(t, expected)
@@ -293,7 +298,7 @@ class TableSourceTest extends TableTestBase {
 
     val t = util.tableEnv.scan("T").select('rtime)
 
-    val expected = "StreamTableSourceScan(table=[[T]], " +
+    val expected = "StreamTableSourceScan(table=[[default_catalog, default_database, T]], " +
       "fields=[rtime], " +
       "source=[TestSource(physical fields: rtime)])"
     util.verifyTable(t, expected)
@@ -317,7 +322,7 @@ class TableSourceTest extends TableTestBase {
 
     val t = util.tableEnv.scan("T").select('name, 'rtime, 'val)
 
-    val expected = "StreamTableSourceScan(table=[[T]], " +
+    val expected = "StreamTableSourceScan(table=[[default_catalog, default_database, T]], " +
       "fields=[name, rtime, val], " +
       "source=[TestSource(physical fields: remapped-p-name, remapped-p-rtime, remapped-p-val)])"
     util.verifyTable(t, expected)
@@ -364,7 +369,7 @@ class TableSourceTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      "StreamTableSourceScan(table=[[T]], " +
+      "StreamTableSourceScan(table=[[default_catalog, default_database, T]], " +
         "fields=[id, deepNested, nested], " +
         "source=[TestSource(read nested fields: " +
           "id.*, deepNested.nested2.num, deepNested.nested2.flag, " +
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TemporalTableJoinTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TemporalTableJoinTest.scala
index 37ded5e..7665192 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TemporalTableJoinTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/TemporalTableJoinTest.scala
@@ -22,17 +22,15 @@ import java.sql.Timestamp
 
 import org.apache.flink.api.scala._
 import org.apache.flink.table.api.scala._
-import org.apache.flink.table.api.stream.table.TemporalTableJoinTest._
 import org.apache.flink.table.api.{TableSchema, Types, ValidationException}
 import org.apache.flink.table.expressions.{Expression, FieldReferenceExpression}
 import org.apache.flink.table.functions.{TemporalTableFunction, TemporalTableFunctionImpl}
 import org.apache.flink.table.plan.logical.rel.LogicalTemporalTableJoin._
-import org.apache.flink.table.typeutils.TimeIndicatorTypeInfo
 import org.apache.flink.table.typeutils.TimeIndicatorTypeInfo.{PROCTIME_INDICATOR, ROWTIME_INDICATOR}
 import org.apache.flink.table.utils.TableTestUtil._
 import org.apache.flink.table.utils._
 import org.hamcrest.Matchers.{equalTo, startsWith}
-import org.junit.Assert.{assertArrayEquals, assertEquals, assertThat, assertTrue}
+import org.junit.Assert.{assertEquals, assertThat}
 import org.junit.Test
 
 class TemporalTableJoinTest extends TableTestBase {
@@ -106,7 +104,47 @@ class TemporalTableJoinTest extends TableTestBase {
       .select('o_amount * 'rate, 'secondary_key).as('rate, 'secondary_key)
       .join(thirdTable, 't3_secondary_key === 'secondary_key)
 
-    util.verifyTable(result, getExpectedComplexJoinPlan())
+    util.verifyTable(result, binaryNode(
+      "DataStreamJoin",
+      unaryNode(
+        "DataStreamCalc",
+        binaryNode(
+          "DataStreamTemporalTableJoin",
+          unaryNode(
+            "DataStreamCalc",
+            streamTableNode(orders),
+            term("select", "o_rowtime, o_amount, o_currency, o_secondary_key")
+          ),
+          unaryNode(
+            "DataStreamCalc",
+            streamTableNode(ratesHistory),
+            term("select", "rowtime, currency, rate, secondary_key"),
+            term("where", ">(rate, 110)")
+          ),
+          term(
+            "where",
+            "AND(" +
+              s"${TEMPORAL_JOIN_CONDITION.getName}(o_rowtime, rowtime, currency), " +
+              "OR(=(currency, o_currency), =(secondary_key, o_secondary_key)))"),
+          term(
+            "join",
+            "o_rowtime",
+            "o_amount",
+            "o_currency",
+            "o_secondary_key",
+            "rowtime",
+            "currency",
+            "rate",
+            "secondary_key"),
+          term("joinType", "InnerJoin")
+        ),
+        term("select", "*(o_amount, rate) AS rate", "secondary_key")
+      ),
+      streamTableNode(thirdTable),
+      term("where", "=(t3_secondary_key, secondary_key)"),
+      term("join", "rate, secondary_key, t3_comment, t3_secondary_key"),
+      term("joinType", "InnerJoin")
+    ))
   }
 
   @Test
@@ -176,16 +214,14 @@ class TemporalTableJoinTest extends TableTestBase {
       expectedSchema.toRowType,
       rates.getResultType)
   }
-}
 
-object TemporalTableJoinTest {
   def getExpectedSimpleJoinPlan(): String = {
     unaryNode(
       "DataStreamCalc",
       binaryNode(
         "DataStreamTemporalTableJoin",
-        streamTableNode(0),
-        streamTableNode(1),
+        streamTableNode(orders),
+        streamTableNode(ratesHistory),
         term("where",
           "AND(" +
             s"${TEMPORAL_JOIN_CONDITION.getName}(o_rowtime, rowtime, currency), " +
@@ -202,10 +238,10 @@ object TemporalTableJoinTest {
       "DataStreamCalc",
       binaryNode(
         "DataStreamTemporalTableJoin",
-        streamTableNode(2),
+        streamTableNode(proctimeOrders),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(3),
+          streamTableNode(proctimeRatesHistory),
           term("select", "currency, rate")),
         term("where",
           "AND(" +
@@ -218,57 +254,15 @@ object TemporalTableJoinTest {
     )
   }
 
-  def getExpectedComplexJoinPlan(): String = {
-    binaryNode(
-      "DataStreamJoin",
-      unaryNode(
-        "DataStreamCalc",
-        binaryNode(
-          "DataStreamTemporalTableJoin",
-          unaryNode(
-            "DataStreamCalc",
-            streamTableNode(1),
-            term("select", "o_rowtime, o_amount, o_currency, o_secondary_key")
-          ),
-          unaryNode(
-            "DataStreamCalc",
-            streamTableNode(2),
-            term("select", "rowtime, currency, rate, secondary_key"),
-            term("where", ">(rate, 110)")
-          ),
-          term("where",
-            "AND(" +
-              s"${TEMPORAL_JOIN_CONDITION.getName}(o_rowtime, rowtime, currency), " +
-              "OR(=(currency, o_currency), =(secondary_key, o_secondary_key)))"),
-          term("join",
-            "o_rowtime",
-            "o_amount",
-            "o_currency",
-            "o_secondary_key",
-            "rowtime",
-            "currency",
-            "rate",
-            "secondary_key"),
-          term("joinType", "InnerJoin")
-        ),
-        term("select", "*(o_amount, rate) AS rate", "secondary_key")
-      ),
-      streamTableNode(0),
-      term("where", "=(t3_secondary_key, secondary_key)"),
-      term("join", "rate, secondary_key, t3_comment, t3_secondary_key"),
-      term("joinType", "InnerJoin")
-    )
-  }
-
   def getExpectedTemporalTableFunctionOnTopOfQueryPlan(): String = {
     unaryNode(
       "DataStreamCalc",
       binaryNode(
         "DataStreamTemporalTableJoin",
-        streamTableNode(0),
+        streamTableNode(orders),
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(1),
+          streamTableNode(ratesHistory),
           term("select", "currency", "*(rate, 2) AS rate", "rowtime"),
           term("where", ">(rate, 100)")),
         term("where",
@@ -282,3 +276,4 @@ object TemporalTableJoinTest {
     )
   }
 }
+
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CorrelateStringExpressionTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CorrelateStringExpressionTest.scala
index 993ac5c..e2068e7 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CorrelateStringExpressionTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/api/stream/table/stringexpr/CorrelateStringExpressionTest.scala
@@ -25,6 +25,9 @@ import org.apache.flink.table.api.scala._
 import org.apache.flink.table.utils._
 import org.apache.flink.types.Row
 import org.junit.Test
+import org.mockito.Mockito.{mock, when}
+import org.apache.flink.streaming.api.datastream.{DataStream => JDataStream}
+import org.apache.flink.streaming.api.scala.DataStream
 
 class CorrelateStringExpressionTest extends TableTestBase {
 
@@ -32,9 +35,15 @@ class CorrelateStringExpressionTest extends TableTestBase {
   def testCorrelateJoinsWithJoinLateral(): Unit = {
 
     val util = streamTestUtil()
-    val sTab = util.addTable[(Int, Long, String)]('a, 'b, 'c)
     val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
-    val jTab = util.addJavaTable[Row](typeInfo,"MyTab","a, b, c")
+    val jDs = mock(classOf[JDataStream[Row]])
+    when(jDs.getType).thenReturn(typeInfo)
+
+    val sDs = mock(classOf[DataStream[Row]])
+    when(sDs.javaStream).thenReturn(jDs)
+
+    val jTab = util.javaTableEnv.fromDataStream(jDs, "a, b, c")
+    val sTab = util.tableEnv.fromDataStream(sDs, 'a, 'b, 'c)
 
     // test cross join
     val func1 = new TableFunc1
@@ -95,9 +104,15 @@ class CorrelateStringExpressionTest extends TableTestBase {
   def testFlatMap(): Unit = {
 
     val util = streamTestUtil()
-    val sTab = util.addTable[(Int, Long, String)]('a, 'b, 'c)
     val typeInfo = new RowTypeInfo(Seq(Types.INT, Types.LONG, Types.STRING): _*)
-    val jTab = util.addJavaTable[Row](typeInfo,"MyTab","a, b, c")
+    val jDs = mock(classOf[JDataStream[Row]])
+    when(jDs.getType).thenReturn(typeInfo)
+
+    val sDs = mock(classOf[DataStream[Row]])
+    when(sDs.javaStream).thenReturn(jDs)
+
+    val jTab = util.javaTableEnv.fromDataStream(jDs, "a, b, c")
+    val sTab = util.tableEnv.fromDataStream(sDs, 'a, 'b, 'c)
 
     // test flatMap
     val func1 = new TableFunc1
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/match/PatternTranslatorTestBase.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/match/PatternTranslatorTestBase.scala
index 106fc79..464c3b4 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/match/PatternTranslatorTestBase.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/match/PatternTranslatorTestBase.scala
@@ -54,6 +54,7 @@ abstract class PatternTranslatorTestBase extends TestLogger{
     val jDataStreamMock = mock(classOf[JDataStream[Row]])
     when(dataStreamMock.javaStream).thenReturn(jDataStreamMock)
     when(jDataStreamMock.getType).thenReturn(typeInfo)
+    when(jDataStreamMock.getId).thenReturn(0)
 
     val env = StreamExecutionEnvironment.getExecutionEnvironment
     val tEnv = StreamTableEnvironment.create(env).asInstanceOf[StreamTableEnvImpl]
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/ExpressionReductionRulesTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/ExpressionReductionRulesTest.scala
index ce4de14..5c0d729 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/ExpressionReductionRulesTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/ExpressionReductionRulesTest.scala
@@ -31,7 +31,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
   @Test
   def testReduceCalcExpressionForBatchSQL(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT " +
       "(3+4)+a, " +
@@ -51,7 +51,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "+(7, a) AS EXPR$0",
         "+(b, 3) AS EXPR$1",
@@ -76,7 +76,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
   @Test
   def testReduceProjectExpressionForBatchSQL(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT " +
       "(3+4)+a, " +
@@ -96,7 +96,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "+(7, a) AS EXPR$0",
         "+(b, 3) AS EXPR$1",
@@ -120,7 +120,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
   @Test
   def testReduceFilterExpressionForBatchSQL(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT " +
       "*" +
@@ -128,7 +128,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select", "a", "b", "c"),
       term("where", ">(a, 8)")
     )
@@ -155,7 +155,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "13 AS _c0",
         "'b' AS _c1",
@@ -191,7 +191,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select",
         "13 AS _c0",
         "'b' AS _c1",
@@ -218,7 +218,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataSetCalc",
-      batchTableNode(0),
+      batchTableNode(table),
       term("select", "a", "b", "c"),
       term("where", ">(a, 8)")
     )
@@ -229,7 +229,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
   @Test
   def testReduceCalcExpressionForStreamSQL(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT " +
       "(3+4)+a, " +
@@ -249,7 +249,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select",
         "+(7, a) AS EXPR$0",
         "+(b, 3) AS EXPR$1",
@@ -274,7 +274,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
   @Test
   def testReduceProjectExpressionForStreamSQL(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT " +
       "(3+4)+a, " +
@@ -294,7 +294,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select",
         "+(7, a) AS EXPR$0",
         "+(b, 3) AS EXPR$1",
@@ -318,7 +318,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
   @Test
   def testReduceFilterExpressionForStreamSQL(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT " +
       "*" +
@@ -326,7 +326,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select", "a", "b", "c"),
       term("where", ">(a, 8)")
     )
@@ -353,7 +353,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select",
         "13 AS _c0",
         "'b' AS _c1",
@@ -389,7 +389,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select",
         "13 AS _c0",
         "'b' AS _c1",
@@ -416,7 +416,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select", "a", "b", "c"),
       term("where", ">(a, 8)")
     )
@@ -428,7 +428,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
   def testNestedTablesReductionStream(): Unit = {
     val util = streamTestUtil()
 
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val newTable = util.tableEnv.sqlQuery("SELECT 1 + 1 + a AS a FROM MyTable")
 
@@ -437,7 +437,10 @@ class ExpressionReductionRulesTest extends TableTestBase {
     val sqlQuery = "SELECT a FROM NewTable"
 
     // 1+1 should be normalized to 2
-    val expected = unaryNode("DataStreamCalc", streamTableNode(0), term("select", "+(2, a) AS a"))
+    val expected = unaryNode(
+      "DataStreamCalc",
+      streamTableNode(table),
+      term("select", "+(2, a) AS a"))
 
     util.verifySql(sqlQuery, expected)
   }
@@ -446,7 +449,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
   def testNestedTablesReductionBatch(): Unit = {
     val util = batchTestUtil()
 
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val table = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val newTable = util.tableEnv.sqlQuery("SELECT 1 + 1 + a AS a FROM MyTable")
 
@@ -455,7 +458,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
     val sqlQuery = "SELECT a FROM NewTable"
 
     // 1+1 should be normalized to 2
-    val expected = unaryNode("DataSetCalc", batchTableNode(0), term("select", "+(2, a) AS a"))
+    val expected = unaryNode("DataSetCalc", batchTableNode(table), term("select", "+(2, a) AS a"))
 
     util.verifySql(sqlQuery, expected)
   }
@@ -472,7 +475,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
       .where("d.isNull")
       .select('a, 'b, 'c)
 
-    val expected: String = streamTableNode(0)
+    val expected: String = streamTableNode(table)
 
     util.verifyTable(result, expected)
   }
@@ -489,7 +492,7 @@ class ExpressionReductionRulesTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(table),
       term("select", "a", "b", "c"),
       term("where", s"IS NULL(NonDeterministicNullFunc$$())")
     )
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/NormalizationRulesTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/NormalizationRulesTest.scala
index 8278a69..910b719 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/NormalizationRulesTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/NormalizationRulesTest.scala
@@ -42,18 +42,20 @@ class NormalizationRulesTest extends TableTestBase {
         .build()
     util.tableEnv.getConfig.setPlannerConfig(cc)
 
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val t = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT " +
       "COUNT(DISTINCT a)" +
       "FROM MyTable group by b"
 
+    val streamNode = batchTableNode(t).replace("DataSetScan", "FlinkLogicalDataSetScan")
+
     // expect double aggregate
     val expected = unaryNode("LogicalProject",
       unaryNode("LogicalAggregate",
         unaryNode("LogicalAggregate",
           unaryNode("LogicalProject",
-            values("LogicalTableScan", term("table", "[_DataSetTable_0]")),
+            streamNode,
             term("b", "$1"), term("a", "$0")),
           term("group", "{0, 1}")),
         term("group", "{0}"), term("EXPR$0", "COUNT($1)")
@@ -76,19 +78,21 @@ class NormalizationRulesTest extends TableTestBase {
         .build()
     util.tableEnv.getConfig.setPlannerConfig(cc)
 
-    util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
+    val t = util.addTable[(Int, Long, String)]("MyTable", 'a, 'b, 'c)
 
     val sqlQuery = "SELECT " +
       "COUNT(DISTINCT a)" +
       "FROM MyTable group by b"
 
+    val streamNode = streamTableNode(t).replace("DataStreamScan", "FlinkLogicalDataStreamScan")
+
     // expect double aggregate
     val expected = unaryNode(
       "LogicalProject",
       unaryNode("LogicalAggregate",
         unaryNode("LogicalAggregate",
           unaryNode("LogicalProject",
-            values("LogicalTableScan", term("table", "[_DataStreamTable_0]")),
+            streamNode,
             term("b", "$1"), term("a", "$0")),
           term("group", "{0, 1}")),
         term("group", "{0}"), term("EXPR$0", "COUNT($1)")
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/QueryDecorrelationTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/QueryDecorrelationTest.scala
index 4245f2c..97eb7c7 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/QueryDecorrelationTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/QueryDecorrelationTest.scala
@@ -29,8 +29,14 @@ class QueryDecorrelationTest extends TableTestBase {
   @Test
   def testCorrelationScalarAggAndFilter(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, String, String, Int, Int)]("emp", 'empno, 'ename, 'job, 'salary, 'deptno)
-    util.addTable[(Int, String)]("dept", 'deptno, 'name)
+    val table = util.addTable[(Int, String, String, Int, Int)](
+      "emp",
+      'empno,
+      'ename,
+      'job,
+      'salary,
+      'deptno)
+    val table1 = util.addTable[(Int, String)]("dept", 'deptno, 'name)
 
     val sql = "SELECT e1.empno\n" +
         "FROM emp e1, dept d1 where e1.deptno = d1.deptno\n" +
@@ -47,13 +53,13 @@ class QueryDecorrelationTest extends TableTestBase {
             "DataSetJoin",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "empno", "salary", "deptno"),
               term("where", "<(deptno, 10)")
             ),
             unaryNode(
               "DataSetCalc",
-              batchTableNode(1),
+              batchTableNode(table1),
               term("select", "deptno"),
               term("where", "<(deptno, 15)")
             ),
@@ -67,7 +73,7 @@ class QueryDecorrelationTest extends TableTestBase {
           "DataSetAggregate",
           unaryNode(
             "DataSetCalc",
-            batchTableNode(0),
+            batchTableNode(table),
             term("select", "empno", "salary"),
             term("where", "IS NOT NULL(empno)")
           ),
@@ -87,8 +93,14 @@ class QueryDecorrelationTest extends TableTestBase {
   @Test
   def testDecorrelateWithMultiAggregate(): Unit = {
     val util = batchTestUtil()
-    util.addTable[(Int, String, String, Int, Int)]("emp", 'empno, 'ename, 'job, 'salary, 'deptno)
-    util.addTable[(Int, String)]("dept", 'deptno, 'name)
+    val table = util.addTable[(Int, String, String, Int, Int)](
+      "emp",
+      'empno,
+      'ename,
+      'job,
+      'salary,
+      'deptno)
+    val table1 = util.addTable[(Int, String)]("dept", 'deptno, 'name)
 
     val sql = "select sum(e1.empno) from emp e1, dept d1 " +
         "where e1.deptno = d1.deptno " +
@@ -108,12 +120,12 @@ class QueryDecorrelationTest extends TableTestBase {
               "DataSetJoin",
               unaryNode(
                 "DataSetCalc",
-                batchTableNode(0),
+                batchTableNode(table),
                 term("select", "empno", "salary", "deptno")
               ),
               unaryNode(
                 "DataSetCalc",
-                batchTableNode(1),
+                batchTableNode(table1),
                 term("select", "deptno")
               ),
               term("where", "=(deptno, deptno0)"),
@@ -126,7 +138,7 @@ class QueryDecorrelationTest extends TableTestBase {
             "DataSetAggregate",
             unaryNode(
               "DataSetCalc",
-              batchTableNode(0),
+              batchTableNode(table),
               term("select", "deptno", "salary"),
               term("where", "IS NOT NULL(deptno)")
             ),
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/TimeIndicatorConversionTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/TimeIndicatorConversionTest.scala
index be93f72..6b7744d 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/TimeIndicatorConversionTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/plan/TimeIndicatorConversionTest.scala
@@ -47,7 +47,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(t),
       term("select", "FLOOR(CAST(rowtime)", "FLAG(DAY)) AS rowtime"),
       term("where", ">(long, 0)")
     )
@@ -64,7 +64,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(t),
       term("select", "rowtime", "long", "int",
         "PROCTIME(proctime) AS proctime")
     )
@@ -83,7 +83,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamCalc",
-      streamTableNode(0),
+      streamTableNode(t),
       term("select", "rowtime"),
       term("where", ">(CAST(rowtime), 1990-12-02 12:11:11)")
     )
@@ -106,7 +106,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "CAST(rowtime) AS rowtime", "long")
         ),
         term("groupBy", "rowtime"),
@@ -133,7 +133,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "CAST(rowtime) AS rowtime", "long")
         ),
         term("groupBy", "long"),
@@ -157,7 +157,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamCorrelate",
-        streamTableNode(0),
+        streamTableNode(t),
         term("invocation",
           s"${func.functionIdentifier}(CAST($$0):TIMESTAMP(3) NOT NULL, PROCTIME($$3), '')"),
         term("correlate", s"table(TableFunc(CAST(rowtime), PROCTIME(proctime), ''))"),
@@ -186,7 +186,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamGroupWindowAggregate",
-        streamTableNode(0),
+        streamTableNode(t),
         term("groupBy", "long"),
         term("window", "TumblingGroupWindow('w, 'rowtime, 100.millis)"),
         term("select", "long", "SUM(int) AS TMP_1", "end('w) AS TMP_0")
@@ -208,12 +208,12 @@ class TimeIndicatorConversionTest extends TableTestBase {
       "DataStreamUnion",
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "rowtime")
       ),
       unaryNode(
         "DataStreamCalc",
-        streamTableNode(0),
+        streamTableNode(t),
         term("select", "rowtime")
       ),
       term("all", "true"),
@@ -244,7 +244,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
           "DataStreamCalc",
           unaryNode(
             "DataStreamGroupWindowAggregate",
-            streamTableNode(0),
+            streamTableNode(t),
             term("groupBy", "long"),
             term("window", "TumblingGroupWindow('w, 'rowtime, 100.millis)"),
             term("select", "long", "SUM(int) AS TMP_1", "rowtime('w) AS TMP_0")
@@ -264,7 +264,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
   @Test
   def testGroupingOnProctime(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
+    val t = util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
 
     val result = util.tableEnv.sqlQuery("SELECT COUNT(long) FROM MyTable GROUP BY proctime")
 
@@ -274,7 +274,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "PROCTIME(proctime) AS proctime", "long")
         ),
         term("groupBy", "proctime"),
@@ -289,7 +289,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
   @Test
   def testAggregationOnProctime(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
+    val t = util.addTable[(Long, Int)]("MyTable" , 'long, 'int, 'proctime.proctime)
 
     val result = util.tableEnv.sqlQuery("SELECT MIN(proctime) FROM MyTable GROUP BY long")
 
@@ -299,7 +299,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
         "DataStreamGroupAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "long", "PROCTIME(proctime) AS proctime")
         ),
         term("groupBy", "long"),
@@ -314,7 +314,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
   @Test
   def testWindowSql(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
+    val t = util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
 
     val result = util.tableEnv.sqlQuery(
       "SELECT TUMBLE_END(rowtime, INTERVAL '0.1' SECOND) AS `rowtime`, `long`, " +
@@ -325,7 +325,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamGroupWindowAggregate",
-        streamTableNode(0),
+        streamTableNode(t),
         term("groupBy", "long"),
         term("window", "TumblingGroupWindow('w$, 'rowtime, 100.millis)"),
         term("select",
@@ -345,7 +345,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
   @Test
   def testWindowWithAggregationOnRowtime(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
+    val t = util.addTable[(Long, Long, Int)]("MyTable", 'rowtime.rowtime, 'long, 'int)
 
     val result = util.tableEnv.sqlQuery("SELECT MIN(rowtime), long FROM MyTable " +
       "GROUP BY long, TUMBLE(rowtime, INTERVAL '0.1' SECOND)")
@@ -356,7 +356,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
         "DataStreamGroupWindowAggregate",
         unaryNode(
           "DataStreamCalc",
-          streamTableNode(0),
+          streamTableNode(t),
           term("select", "long", "rowtime", "CAST(rowtime) AS rowtime0")
         ),
         term("groupBy", "long"),
@@ -483,7 +483,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
   @Test
   def testMatchRecognizeRowtimeMaterialization(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Long, Long, Int)](
+    val t = util.addTable[(Long, Long, Int)](
       "RowtimeTicker",
       'rowtime.rowtime,
       'symbol,
@@ -511,7 +511,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
 
     val expected = unaryNode(
       "DataStreamMatch",
-      streamTableNode(0),
+      streamTableNode(t),
       term("partitionBy", "symbol"),
       term("orderBy", "rowtime ASC"),
       term("measures",
@@ -531,7 +531,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
   @Test
   def testMatchRecognizeProctimeMaterialization(): Unit = {
     val util = streamTestUtil()
-    util.addTable[(Long, Long, Int)](
+    val t = util.addTable[(Long, Long, Int)](
       "ProctimeTicker",
       'rowtime.rowtime,
       'symbol,
@@ -562,7 +562,7 @@ class TimeIndicatorConversionTest extends TableTestBase {
       "DataStreamCalc",
       unaryNode(
         "DataStreamMatch",
-        streamTableNode(0),
+        streamTableNode(t),
         term("partitionBy", "symbol"),
         term("orderBy", "rowtime ASC"),
         term("measures",
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSourceITCase.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSourceITCase.scala
index eb571d5..37e340a 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSourceITCase.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/runtime/stream/table/TableSourceITCase.scala
@@ -75,6 +75,31 @@ class TableSourceITCase extends AbstractTestBase {
   }
 
   @Test
+  def testUnregisteredCsvTableSource(): Unit = {
+
+    val csvTable = CommonTestData.getCsvTableSource
+    StreamITCase.testResults = mutable.MutableList()
+
+    val env = StreamExecutionEnvironment.getExecutionEnvironment
+    val tEnv = StreamTableEnvironment.create(env)
+
+    tEnv.fromTableSource(csvTable)
+      .where('id > 4)
+      .select('last, 'score * 2)
+      .toAppendStream[Row]
+      .addSink(new StreamITCase.StringSink[Row])
+
+    env.execute()
+
+    val expected = Seq(
+      "Williams,69.0",
+      "Miller,13.56",
+      "Smith,180.2",
+      "Williams,4.68")
+    assertEquals(expected.sorted, StreamITCase.testResults.sorted)
+  }
+
+  @Test
   def testCsvTableSource(): Unit = {
 
     val csvTable = CommonTestData.getCsvTableSource
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
index 1d6b330..db0ec53 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/utils/TableTestBase.scala
@@ -28,20 +28,19 @@ import org.apache.flink.streaming.api.environment.LocalStreamEnvironment
 import org.apache.flink.streaming.api.functions.source.SourceFunction
 import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
 import org.apache.flink.table.api.java.{BatchTableEnvImpl => JavaBatchTableEnvImpl, StreamTableEnvImpl => JavaStreamTableEnvImpl}
-import org.apache.flink.table.api.scala.{BatchTableEnvironment => ScalaBatchTableEnv, StreamTableEnvironment => ScalaStreamTableEnv}
-import org.apache.flink.table.api.scala.{BatchTableEnvImpl => ScalaBatchTableEnvImpl, StreamTableEnvImpl => ScalaStreamTableEnvImpl}
-import org.apache.flink.table.api.scala._
+import org.apache.flink.table.api.scala.{BatchTableEnvImpl => ScalaBatchTableEnvImpl, _}
 import org.apache.flink.table.api.{Table, TableConfig, TableImpl, TableSchema}
-import org.apache.flink.table.catalog.{CatalogManager, GenericCatalogDatabase, GenericInMemoryCatalog}
+import org.apache.flink.table.catalog.{CatalogManager, GenericInMemoryCatalog}
 import org.apache.flink.table.expressions.Expression
 import org.apache.flink.table.functions.{AggregateFunction, ScalarFunction, TableFunction}
-import org.apache.flink.table.utils.TableTestUtil.{createCatalogManager, extractBuiltinPath}
+import org.apache.flink.table.operations.{CatalogTableOperation, DataSetTableOperation, DataStreamTableOperation}
+import org.apache.flink.table.utils.TableTestUtil.createCatalogManager
 import org.junit.Assert.assertEquals
-import org.junit.{ComparisonFailure, Rule}
 import org.junit.rules.ExpectedException
+import org.junit.{ComparisonFailure, Rule}
 import org.mockito.Mockito.{mock, when}
 
-import util.control.Breaks._
+import scala.util.control.Breaks._
 
 /**
   * Test base for testing Table API / SQL plans.
@@ -108,16 +107,8 @@ abstract class TableTestUtil(verifyCatalogPath: Boolean = false) {
     // depends on the native machine (Little/Big Endian)
     val actualNoCharset = actual.replace("_UTF-16LE'", "'").replace("_UTF-16BE'", "'")
 
-    // majority of tests did not assume existence of Catalog API.
-    // this enables disabling catalog path verification
-    val actualWithAdjustedPath = if (!verifyCatalogPath) {
-      actualNoCharset.replaceAll("default_catalog, default_database, ", "")
-    } else {
-      actualNoCharset
-    }
-
     val expectedLines = expected.split("\n").map(_.trim)
-    val actualLines = actualWithAdjustedPath.split("\n").map(_.trim)
+    val actualLines = actualNoCharset.split("\n").map(_.trim)
 
     val expectedMessage = expectedLines.mkString("\n")
     val actualMessage = actualLines.mkString("\n")
@@ -210,12 +201,16 @@ object TableTestUtil {
     term("tuples", "[" + listValues.mkString(", ") + "]")
   }
 
-  def batchTableNode(idx: Int): String = {
-    s"DataSetScan(table=[[_DataSetTable_$idx]])"
+  def batchTableNode(table: Table): String = {
+    val dataSetTable = table.getTableOperation.asInstanceOf[DataSetTableOperation[_]]
+    s"DataSetScan(ref=[${System.identityHashCode(dataSetTable.getDataSet)}], " +
+      s"fields=[${dataSetTable.getTableSchema.getFieldNames.mkString(", ")}])"
   }
 
-  def streamTableNode(idx: Int): String = {
-    s"DataStreamScan(table=[[_DataStreamTable_$idx]])"
+  def streamTableNode(table: Table): String = {
+    val dataStreamTable = table.getTableOperation.asInstanceOf[DataStreamTableOperation[_]]
+    s"DataStreamScan(id=[${dataStreamTable.getDataStream.getId}], " +
+      s"fields=[${dataStreamTable.getTableSchema.getFieldNames.mkString(", ")}])"
   }
 }
 
diff --git a/flink-table/flink-table-planner/src/test/scala/resources/testFilter0.out b/flink-table/flink-table-planner/src/test/scala/resources/testFilter0.out
index c5a4c9f..81d2b6b 100644
--- a/flink-table/flink-table-planner/src/test/scala/resources/testFilter0.out
+++ b/flink-table/flink-table-planner/src/test/scala/resources/testFilter0.out
@@ -1,10 +1,10 @@
 == Abstract Syntax Tree ==
 LogicalFilter(condition=[=(MOD($0, 2), 0)])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_0]])
+  %logicalSourceNode0%
 
 == Optimized Logical Plan ==
 DataSetCalc(select=[a, b], where=[=(MOD(a, 2), 0)])
-  DataSetScan(table=[[default_catalog, default_database, _DataSetTable_0]])
+  %sourceNode0%
 
 == Physical Execution Plan ==
 Stage 3 : Data Source
diff --git a/flink-table/flink-table-planner/src/test/scala/resources/testFilter1.out b/flink-table/flink-table-planner/src/test/scala/resources/testFilter1.out
index 88381f4..9eb5c7a 100644
--- a/flink-table/flink-table-planner/src/test/scala/resources/testFilter1.out
+++ b/flink-table/flink-table-planner/src/test/scala/resources/testFilter1.out
@@ -1,10 +1,10 @@
 == Abstract Syntax Tree ==
 LogicalFilter(condition=[=(MOD($0, 2), 0)])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_0]])
+  %logicalSourceNode0%
 
 == Optimized Logical Plan ==
 DataSetCalc(select=[a, b], where=[=(MOD(a, 2), 0)])
-  DataSetScan(table=[[default_catalog, default_database, _DataSetTable_0]])
+  %sourceNode0%
 
 == Physical Execution Plan ==
 Stage 3 : Data Source
diff --git a/flink-table/flink-table-planner/src/test/scala/resources/testFilterStream0.out b/flink-table/flink-table-planner/src/test/scala/resources/testFilterStream0.out
index 3a1088a..cfedce0 100644
--- a/flink-table/flink-table-planner/src/test/scala/resources/testFilterStream0.out
+++ b/flink-table/flink-table-planner/src/test/scala/resources/testFilterStream0.out
@@ -1,10 +1,10 @@
 == Abstract Syntax Tree ==
 LogicalFilter(condition=[=(MOD($0, 2), 0)])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataStreamTable_0]])
+  %logicalSourceNode0%
 
 == Optimized Logical Plan ==
 DataStreamCalc(select=[a, b], where=[=(MOD(a, 2), 0)])
-  DataStreamScan(table=[[default_catalog, default_database, _DataStreamTable_0]])
+  %sourceNode0%
 
 == Physical Execution Plan ==
 Stage 1 : Data Source
diff --git a/flink-table/flink-table-planner/src/test/scala/resources/testJoin0.out b/flink-table/flink-table-planner/src/test/scala/resources/testJoin0.out
index 0d995ac..986d21a 100644
--- a/flink-table/flink-table-planner/src/test/scala/resources/testJoin0.out
+++ b/flink-table/flink-table-planner/src/test/scala/resources/testJoin0.out
@@ -2,14 +2,14 @@
 LogicalProject(a=[$0], c=[$2])
   LogicalFilter(condition=[=($1, $3)])
     LogicalJoin(condition=[true], joinType=[inner])
-      LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_0]])
-      LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_1]])
+      %logicalSourceNode0%
+      %logicalSourceNode1%
 
 == Optimized Logical Plan ==
 DataSetCalc(select=[a, c])
   DataSetJoin(where=[=(b, d)], join=[a, b, c, d], joinType=[InnerJoin])
-    DataSetScan(table=[[default_catalog, default_database, _DataSetTable_0]])
-    DataSetScan(table=[[default_catalog, default_database, _DataSetTable_1]])
+    %sourceNode0%
+    %sourceNode1%
 
 == Physical Execution Plan ==
 Stage 4 : Data Source
diff --git a/flink-table/flink-table-planner/src/test/scala/resources/testJoin1.out b/flink-table/flink-table-planner/src/test/scala/resources/testJoin1.out
index cd95975..0db76f9 100644
--- a/flink-table/flink-table-planner/src/test/scala/resources/testJoin1.out
+++ b/flink-table/flink-table-planner/src/test/scala/resources/testJoin1.out
@@ -2,14 +2,14 @@
 LogicalProject(a=[$0], c=[$2])
   LogicalFilter(condition=[=($1, $3)])
     LogicalJoin(condition=[true], joinType=[inner])
-      LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_0]])
-      LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_1]])
+      %logicalSourceNode0%
+      %logicalSourceNode1%
 
 == Optimized Logical Plan ==
 DataSetCalc(select=[a, c])
   DataSetJoin(where=[=(b, d)], join=[a, b, c, d], joinType=[InnerJoin])
-    DataSetScan(table=[[default_catalog, default_database, _DataSetTable_0]])
-    DataSetScan(table=[[default_catalog, default_database, _DataSetTable_1]])
+    %sourceNode0%
+    %sourceNode1%
 
 == Physical Execution Plan ==
 Stage 4 : Data Source
diff --git a/flink-table/flink-table-planner/src/test/scala/resources/testUnion0.out b/flink-table/flink-table-planner/src/test/scala/resources/testUnion0.out
index 541efd7..dbee609 100644
--- a/flink-table/flink-table-planner/src/test/scala/resources/testUnion0.out
+++ b/flink-table/flink-table-planner/src/test/scala/resources/testUnion0.out
@@ -1,12 +1,12 @@
 == Abstract Syntax Tree ==
 LogicalUnion(all=[true])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_0]])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_1]])
+  %logicalSourceNode0%
+  %logicalSourceNode1%
 
 == Optimized Logical Plan ==
 DataSetUnion(all=[true], union=[count, word])
-  DataSetScan(table=[[default_catalog, default_database, _DataSetTable_0]])
-  DataSetScan(table=[[default_catalog, default_database, _DataSetTable_1]])
+  %sourceNode0%
+  %sourceNode1%
 
 == Physical Execution Plan ==
 Stage 3 : Data Source
diff --git a/flink-table/flink-table-planner/src/test/scala/resources/testUnion1.out b/flink-table/flink-table-planner/src/test/scala/resources/testUnion1.out
index 63d5865..cd12e1d 100644
--- a/flink-table/flink-table-planner/src/test/scala/resources/testUnion1.out
+++ b/flink-table/flink-table-planner/src/test/scala/resources/testUnion1.out
@@ -1,12 +1,12 @@
 == Abstract Syntax Tree ==
 LogicalUnion(all=[true])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_0]])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataSetTable_1]])
+  %logicalSourceNode0%
+  %logicalSourceNode1%
 
 == Optimized Logical Plan ==
 DataSetUnion(all=[true], union=[count, word])
-  DataSetScan(table=[[default_catalog, default_database, _DataSetTable_0]])
-  DataSetScan(table=[[default_catalog, default_database, _DataSetTable_1]])
+  %sourceNode0%
+  %sourceNode1%
 
 == Physical Execution Plan ==
 Stage 3 : Data Source
diff --git a/flink-table/flink-table-planner/src/test/scala/resources/testUnionStream0.out b/flink-table/flink-table-planner/src/test/scala/resources/testUnionStream0.out
index 4affe46..e8fb70b 100644
--- a/flink-table/flink-table-planner/src/test/scala/resources/testUnionStream0.out
+++ b/flink-table/flink-table-planner/src/test/scala/resources/testUnionStream0.out
@@ -1,12 +1,12 @@
 == Abstract Syntax Tree ==
 LogicalUnion(all=[true])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataStreamTable_0]])
-  LogicalTableScan(table=[[default_catalog, default_database, _DataStreamTable_1]])
+  %logicalSourceNode0%
+  %logicalSourceNode1%
 
 == Optimized Logical Plan ==
 DataStreamUnion(all=[true], union all=[count, word])
-  DataStreamScan(table=[[default_catalog, default_database, _DataStreamTable_0]])
-  DataStreamScan(table=[[default_catalog, default_database, _DataStreamTable_1]])
+  %sourceNode0%
+  %sourceNode1%
 
 == Physical Execution Plan ==
 Stage 1 : Data Source