You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by ku...@apache.org on 2019/06/11 00:55:28 UTC

[flink] 02/02: [FLINK-12443][table-planner-blink] Replace InternalType with LogicalType in blink planner

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

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

commit a21cc24bac61baf67c2acc93af8d8e7b36fbda87
Author: JingsongLi <lz...@aliyun.com>
AuthorDate: Tue Jun 4 19:59:16 2019 +0800

    [FLINK-12443][table-planner-blink] Replace InternalType with LogicalType in blink planner
    
    This closes #8435.
---
 .../flink/table/calcite/type/FlinkReturnTypes.java |  77 ++-
 .../flink/table/expressions/ExpressionBuilder.java |  15 +-
 .../expressions/ResolvedAggInputReference.java     |   8 +-
 .../expressions/ResolvedAggLocalReference.java     |   8 +-
 .../expressions/ResolvedDistinctKeyReference.java  |   8 +-
 .../flink/table/expressions/RexNodeConverter.java  | 122 ++---
 .../functions/aggfunctions/AvgAggFunction.java     |  54 ++-
 .../functions/aggfunctions/ConcatAggFunction.java  |  21 +-
 .../functions/aggfunctions/Count1AggFunction.java  |  14 +-
 .../functions/aggfunctions/CountAggFunction.java   |  14 +-
 .../aggfunctions/DeclarativeAggregateFunction.java |   7 +-
 .../aggfunctions/DenseRankAggFunction.java         |  20 +-
 .../aggfunctions/FirstValueAggFunction.java        |  13 +-
 .../FirstValueWithRetractAggFunction.java          |  19 +-
 .../functions/aggfunctions/IncrSumAggFunction.java |  48 +-
 .../IncrSumWithRetractAggFunction.java             |  53 +--
 .../aggfunctions/LastValueAggFunction.java         |  13 +-
 .../LastValueWithRetractAggFunction.java           |  19 +-
 .../functions/aggfunctions/LeadLagAggFunction.java |  62 ++-
 .../functions/aggfunctions/MaxAggFunction.java     |  65 ++-
 .../functions/aggfunctions/MinAggFunction.java     |  65 ++-
 .../functions/aggfunctions/RankAggFunction.java    |  22 +-
 .../aggfunctions/RankLikeAggFunctionBase.java      |  71 ++-
 .../aggfunctions/RowNumberAggFunction.java         |  14 +-
 .../aggfunctions/SingleValueAggFunction.java       |  75 ++-
 .../functions/aggfunctions/Sum0AggFunction.java    |  48 +-
 .../functions/aggfunctions/SumAggFunction.java     |  48 +-
 .../aggfunctions/SumWithRetractAggFunction.java    |  53 +--
 .../flink/table/plan/util/KeySelectorUtil.java     |  17 +-
 .../flink/table/api/StreamTableEnvironment.scala   |  39 +-
 .../apache/flink/table/api/TableEnvironment.scala  | 154 +++---
 .../org/apache/flink/table/api/TableImpl.scala     |  14 +-
 .../table/calcite/FlinkCalciteSqlValidator.scala   |   2 +-
 .../apache/flink/table/calcite/FlinkLocalRef.scala |   6 +-
 .../flink/table/calcite/FlinkTypeFactory.scala     | 464 +++++++++----------
 .../flink/table/calcite/FlinkTypeSystem.scala      |  83 +++-
 .../table/calcite/RelTimeIndicatorConverter.scala  |   8 +-
 .../flink/table/codegen/CalcCodeGenerator.scala    |   9 +-
 .../apache/flink/table/codegen/CodeGenUtils.scala  | 460 +++++++++---------
 .../flink/table/codegen/CodeGeneratorContext.scala |  35 +-
 .../table/codegen/CollectorCodeGenerator.scala     |   6 +-
 .../table/codegen/CorrelateCodeGenerator.scala     |  39 +-
 .../table/codegen/EqualiserCodeGenerator.scala     |  25 +-
 .../flink/table/codegen/ExpandCodeGenerator.scala  |   2 +-
 .../flink/table/codegen/ExprCodeGenerator.scala    |  58 ++-
 .../flink/table/codegen/ExpressionReducer.scala    |   8 +-
 .../table/codegen/FunctionCodeGenerator.scala      |   8 +-
 .../apache/flink/table/codegen/GenerateUtils.scala | 136 +++---
 .../flink/table/codegen/GeneratedExpression.scala  |   4 +-
 .../flink/table/codegen/HashCodeGenerator.scala    |   4 +-
 .../table/codegen/InputFormatCodeGenerator.scala   |   4 +-
 .../table/codegen/LongHashJoinGenerator.scala      |  36 +-
 .../table/codegen/LookupJoinCodeGenerator.scala    |  33 +-
 .../table/codegen/OperatorCodeGenerator.scala      |   8 +-
 .../table/codegen/ProjectionCodeGenerator.scala    |  12 +-
 .../flink/table/codegen/SinkCodeGenerator.scala    |  28 +-
 .../flink/table/codegen/ValuesCodeGenerator.scala  |   6 +-
 .../codegen/agg/AggsHandlerCodeGenerator.scala     |  41 +-
 .../table/codegen/agg/DeclarativeAggCodeGen.scala  |  11 +-
 .../table/codegen/agg/DistinctAggCodeGen.scala     |  21 +-
 .../table/codegen/agg/ImperativeAggCodeGen.scala   |  42 +-
 .../table/codegen/agg/batch/AggCodeGenHelper.scala |  79 ++--
 .../agg/batch/AggWithoutKeysCodeGenerator.scala    |   2 +-
 .../codegen/agg/batch/HashAggCodeGenHelper.scala   |  72 +--
 .../codegen/agg/batch/HashAggCodeGenerator.scala   |   4 +-
 .../agg/batch/HashWindowCodeGenerator.scala        |  36 +-
 .../codegen/agg/batch/SortAggCodeGenerator.scala   |   2 +-
 .../agg/batch/SortWindowCodeGenerator.scala        |   2 +-
 .../codegen/agg/batch/WindowCodeGenerator.scala    |  65 +--
 .../table/codegen/calls/BinaryStringCallGen.scala  |  84 ++--
 .../flink/table/codegen/calls/CallGenerator.scala  |   4 +-
 .../table/codegen/calls/ConstantCallGen.scala      |   4 +-
 .../codegen/calls/CurrentTimePointCallGen.scala    |  17 +-
 .../flink/table/codegen/calls/DivCallGen.scala     |  10 +-
 .../table/codegen/calls/FloorCeilCallGen.scala     |  17 +-
 .../table/codegen/calls/FunctionGenerator.scala    | 446 +++++++++---------
 .../table/codegen/calls/HashCodeCallGen.scala      |   4 +-
 .../flink/table/codegen/calls/IfCallGen.scala      |   4 +-
 .../flink/table/codegen/calls/LikeCallGen.scala    |   6 +-
 .../flink/table/codegen/calls/MethodCallGen.scala  |   4 +-
 .../flink/table/codegen/calls/PrintCallGen.scala   |   6 +-
 .../flink/table/codegen/calls/RandCallGen.scala    |   8 +-
 .../codegen/calls/ScalarFunctionCallGen.scala      |  15 +-
 .../table/codegen/calls/ScalarOperatorGens.scala   | 465 ++++++++++---------
 .../table/codegen/calls/TableFunctionCallGen.scala |  11 +-
 .../table/codegen/calls/TimestampDiffCallGen.scala |  42 +-
 ...ltiFieldRangeBoundComparatorCodeGenerator.scala |   4 +-
 .../over/RangeBoundComparatorCodeGenerator.scala   |  18 +-
 .../codegen/sort/ComparatorCodeGenerator.scala     |   4 +-
 .../table/codegen/sort/SortCodeGenerator.scala     |  83 ++--
 .../flink/table/dataview/DataViewUtils.scala       | 121 ++---
 .../flink/table/expressions/windowProperties.scala |  25 +-
 .../table/functions/utils/AggSqlFunction.scala     |  22 +-
 .../table/functions/utils/ScalarSqlFunction.scala  |  15 +-
 .../table/functions/utils/TableSqlFunction.scala   |  12 +-
 .../functions/utils/UserDefinedFunctionUtils.scala | 154 +++---
 .../flink/table/plan/nodes/calcite/Sink.scala      |  13 +-
 .../table/plan/nodes/calcite/WindowAggregate.scala |   2 +-
 .../table/plan/nodes/common/CommonLookupJoin.scala |  86 ++--
 .../batch/BatchExecBoundedStreamScan.scala         |   4 +-
 .../plan/nodes/physical/batch/BatchExecCalc.scala  |   5 +-
 .../nodes/physical/batch/BatchExecExchange.scala   |   6 +-
 .../nodes/physical/batch/BatchExecExpand.scala     |   9 +-
 .../batch/BatchExecHashAggregateBase.scala         |   7 +-
 .../batch/BatchExecHashWindowAggregateBase.scala   |   7 +-
 .../nodes/physical/batch/BatchExecJoinBase.scala   |   2 +-
 .../physical/batch/BatchExecOverAggregate.scala    |  47 +-
 .../plan/nodes/physical/batch/BatchExecRank.scala  |   7 +-
 .../plan/nodes/physical/batch/BatchExecSink.scala  |  16 +-
 .../plan/nodes/physical/batch/BatchExecSort.scala  |   7 +-
 .../batch/BatchExecSortAggregateBase.scala         |   7 +-
 .../nodes/physical/batch/BatchExecSortLimit.scala  |   3 +-
 .../physical/batch/BatchExecSortMergeJoin.scala    |  13 +-
 .../batch/BatchExecSortWindowAggregateBase.scala   |   7 +-
 .../physical/batch/BatchExecTableSourceScan.scala  |  26 +-
 .../nodes/physical/stream/StreamExecCalc.scala     |   5 +-
 .../physical/stream/StreamExecCorrelate.scala      |   2 +-
 .../physical/stream/StreamExecDataStreamScan.scala |  22 +-
 .../physical/stream/StreamExecDeduplicate.scala    |   4 +-
 .../nodes/physical/stream/StreamExecExchange.scala |   9 +-
 .../nodes/physical/stream/StreamExecExpand.scala   |   9 +-
 .../stream/StreamExecGlobalGroupAggregate.scala    |  25 +-
 .../physical/stream/StreamExecGroupAggregate.scala |  19 +-
 .../stream/StreamExecGroupWindowAggregate.scala    |  34 +-
 .../StreamExecIncrementalGroupAggregate.scala      |  15 +-
 .../nodes/physical/stream/StreamExecLimit.scala    |  12 +-
 .../stream/StreamExecLocalGroupAggregate.scala     |   9 +-
 .../physical/stream/StreamExecLookupJoin.scala     |  11 +-
 .../physical/stream/StreamExecOverAggregate.scala  |  24 +-
 .../nodes/physical/stream/StreamExecRank.scala     |  12 +-
 .../nodes/physical/stream/StreamExecSink.scala     |  24 +-
 .../nodes/physical/stream/StreamExecSort.scala     |   7 +-
 .../physical/stream/StreamExecSortLimit.scala      |   7 +-
 .../stream/StreamExecTableSourceScan.scala         |  22 +-
 .../physical/stream/StreamExecTemporalSort.scala   |  14 +-
 .../nodes/physical/stream/StreamExecValues.scala   |   5 +-
 .../physical/stream/StreamExecWindowJoin.scala     |  20 +-
 .../logical/BatchLogicalWindowAggregateRule.scala  |  12 +-
 .../rules/logical/ConvertToNotInOrInRule.scala     |   6 +-
 .../plan/rules/logical/LogicalUnnestRule.scala     |  32 +-
 .../logical/LogicalWindowAggregateRuleBase.scala   |  23 +-
 .../logical/StreamLogicalWindowAggregateRule.scala |  12 +-
 .../physical/batch/BatchExecAggRuleBase.scala      |  16 +-
 .../physical/batch/BatchExecHashAggRule.scala      |   4 +-
 .../physical/batch/BatchExecLookupJoinRule.scala   |  17 +-
 .../batch/BatchExecOverAggregateRule.scala         |   6 +-
 .../physical/batch/BatchExecSortAggRule.scala      |   6 +-
 .../batch/BatchExecWindowAggregateRule.scala       |  18 +-
 .../physical/stream/StreamExecLookupJoinRule.scala |  12 +-
 .../flink/table/plan/schema/ArrayRelDataType.scala |  55 ---
 .../flink/table/plan/schema/DataStreamTable.scala  |   8 +-
 .../schema/DeferredTypeFlinkTableFunction.scala    |  13 +-
 .../table/plan/schema/FlinkTableFunction.scala     |   5 +-
 .../table/plan/schema/GenericRelDataType.scala     |  21 +-
 .../flink/table/plan/schema/InlineTable.scala      |  53 +--
 .../flink/table/plan/schema/MapRelDataType.scala   |  50 --
 .../table/plan/schema/MultisetRelDataType.scala    |  50 --
 .../flink/table/plan/schema/RowRelDataType.scala   |  89 ----
 .../apache/flink/table/plan/schema/RowSchema.scala |  72 ---
 .../flink/table/plan/schema/TableSinkTable.scala   |   7 +-
 .../plan/schema/TypedFlinkTableFunction.scala      |  12 +-
 .../flink/table/plan/util/AggFunctionFactory.scala | 377 +++++++--------
 .../flink/table/plan/util/AggregateUtil.scala      | 117 +++--
 .../flink/table/plan/util/FlinkRelMdUtil.scala     |   4 +-
 .../flink/table/plan/util/LookupJoinUtil.scala     |   4 +-
 .../flink/table/plan/util/RelExplainUtil.scala     |   6 +-
 .../apache/flink/table/plan/util/ScanUtil.scala    |  26 +-
 .../flink/table/plan/util/WindowJoinUtil.scala     |   4 +-
 .../apache/flink/table/plan/util/aggregation.scala |  15 +-
 .../flink/table/sinks/DataStreamTableSink.scala    |   4 +-
 .../flink/table/sources/TableSourceUtil.scala      |  89 ++--
 .../table/sources/tsextractors/ExistingField.scala |   4 +-
 .../flink/table/typeutils/TypeCheckUtils.scala     | 155 ++-----
 .../flink/table/typeutils/TypeCoercion.scala       | 176 +++----
 .../flink/table/validate/FunctionCatalog.scala     |  14 +-
 .../table/codegen/LongHashJoinGeneratorTest.java   |  10 +-
 .../flink/table/codegen/SortCodeGeneratorTest.java | 515 +++++++++++----------
 .../apache/flink/table/util/BaseRowTestUtil.java   |  20 +-
 .../digest/testGetDigestWithDynamicFunction.out    |   6 +-
 .../testGetDigestWithDynamicFunctionView.out       |   6 +-
 .../apache/flink/table/plan/batch/sql/CalcTest.xml |   6 +-
 .../table/plan/batch/sql/DagOptimizationTest.xml   |  12 +-
 .../table/plan/batch/sql/RemoveCollationTest.xml   |  20 +-
 .../table/plan/batch/sql/RemoveShuffleTest.xml     |  12 +-
 .../table/plan/batch/sql/SetOperatorsTest.xml      |   4 +-
 .../table/plan/batch/sql/SubplanReuseTest.xml      |  20 +-
 .../flink/table/plan/batch/sql/UnionTest.xml       |   8 +-
 .../flink/table/plan/batch/sql/UnnestTest.xml      |  20 +-
 .../table/plan/batch/sql/agg/GroupingSetsTest.xml  |   6 +-
 .../table/plan/batch/sql/agg/HashAggregateTest.xml |  80 ++--
 .../table/plan/batch/sql/agg/SortAggregateTest.xml | 172 +++----
 .../sql/join/BroadcastHashSemiAntiJoinTest.xml     |  18 +-
 .../batch/sql/join/NestedLoopSemiAntiJoinTest.xml  |  18 +-
 .../table/plan/batch/sql/join/SemiAntiJoinTest.xml |  18 +-
 .../sql/join/ShuffledHashSemiAntiJoinTest.xml      |   6 +-
 .../batch/sql/join/SortMergeSemiAntiJoinTest.xml   |  18 +-
 .../logical/JoinConditionTypeCoerceRuleTest.xml    |  26 +-
 .../plan/rules/logical/LogicalUnnestRuleTest.xml   |  16 +-
 .../ProjectSemiAntiJoinTransposeRuleTest.xml       |   4 +-
 .../logical/subquery/SubQueryAntiJoinTest.xml      |  16 +-
 .../logical/subquery/SubQuerySemiJoinTest.xml      |  40 +-
 .../flink/table/plan/stream/sql/CalcTest.xml       |   6 +-
 .../table/plan/stream/sql/DagOptimizationTest.xml  |  12 +-
 .../stream/sql/RelTimeIndicatorConverterTest.xml   |   4 +-
 .../table/plan/stream/sql/SetOperatorsTest.xml     |   4 +-
 .../table/plan/stream/sql/SubplanReuseTest.xml     |  18 +-
 .../flink/table/plan/stream/sql/UnionTest.xml      |   8 +-
 .../flink/table/plan/stream/sql/UnnestTest.xml     |  20 +-
 .../table/plan/stream/sql/agg/AggregateTest.xml    |  40 +-
 .../table/plan/stream/sql/agg/GroupingSetsTest.xml |   6 +-
 .../plan/stream/sql/agg/TwoStageAggregateTest.xml  |   4 +-
 .../table/plan/stream/sql/join/LookupJoinTest.xml  |  26 +-
 .../plan/stream/sql/join/SemiAntiJoinTest.xml      |  18 +-
 .../apache/flink/table/api/batch/ExplainTest.scala |   6 +-
 .../flink/table/api/stream/ExplainTest.scala       |   6 +-
 .../flink/table/calcite/FlinkTypeFactoryTest.scala |  67 +--
 .../table/codegen/HashCodeGeneratorTest.scala      |   6 +-
 .../codegen/ProjectionCodeGeneratorTest.scala      |  14 +-
 .../flink/table/codegen/agg/AggTestBase.scala      |  25 +-
 .../codegen/agg/AggsHandlerCodeGeneratorTest.scala |   9 +-
 .../codegen/agg/batch/AggWithoutKeysTest.scala     |  24 +-
 .../table/codegen/agg/batch/BatchAggTestBase.scala |  19 +-
 .../agg/batch/HashAggCodeGeneratorTest.scala       |  18 +-
 .../agg/batch/SortAggCodeGeneratorTest.scala       |  28 +-
 .../expressions/utils/ExpressionTestBase.scala     |  27 +-
 .../table/plan/batch/sql/DagOptimizationTest.scala |   8 +-
 .../flink/table/plan/batch/sql/SinkTest.scala      |   5 +-
 .../table/plan/batch/sql/join/LookupJoinTest.scala |   2 +-
 .../metadata/FlinkRelMdColumnIntervalTest.scala    |   6 +-
 .../plan/metadata/FlinkRelMdDistributionTest.scala |  12 +-
 .../FlinkRelMdFilteredColumnIntervalTest.scala     |  12 +-
 .../plan/metadata/FlinkRelMdHandlerTestBase.scala  |  75 ++-
 .../table/plan/metadata/MetadataTestUtil.scala     |  43 +-
 .../plan/stream/sql/DagOptimizationTest.scala      |   6 +-
 .../flink/table/plan/stream/sql/SinkTest.scala     |   6 +-
 .../plan/stream/sql/join/LookupJoinTest.scala      |  24 +-
 .../table/runtime/batch/sql/DecimalITCase.scala    |  39 +-
 .../table/runtime/batch/sql/UnionITCase.scala      |  12 +-
 .../batch/sql/agg/AggregateITCaseBase.scala        |   5 +-
 .../table/runtime/stream/sql/CalcITCase.scala      |  26 +-
 .../table/runtime/stream/sql/RankITCase.scala      |  56 ++-
 .../table/runtime/stream/sql/ValuesITCase.scala    |   4 +-
 .../table/runtime/utils/BatchTableEnvUtil.scala    |   4 +-
 .../flink/table/runtime/utils/BatchTestBase.scala  |   4 +-
 .../table/runtime/utils/StreamTableEnvUtil.scala   |   4 +-
 .../flink/table/runtime/utils/StreamTestSink.scala |  10 +-
 .../runtime/utils/StreamingWithStateTestBase.scala |   9 +-
 .../flink/table/runtime/utils/TableUtil.scala      |   6 +-
 .../flink/table/runtime/utils/TestSinkUtil.scala   |   6 +-
 .../apache/flink/table/util/AvgAggFunction.scala   |  11 +-
 .../apache/flink/table/util/TableTestBase.scala    |  31 +-
 .../table/dataformat/AbstractBinaryWriter.java     |   6 +-
 .../apache/flink/table/dataformat/BinaryArray.java |  39 +-
 .../flink/table/dataformat/BinaryArrayWriter.java  |  56 ++-
 .../flink/table/dataformat/BinaryGeneric.java      |   3 +-
 .../apache/flink/table/dataformat/BinaryRow.java   |  62 ++-
 .../flink/table/dataformat/BinaryWriter.java       | 108 +++--
 .../table/dataformat/DataFormatConverters.java     | 354 ++++++++------
 .../org/apache/flink/table/dataformat/Decimal.java |   3 +
 .../flink/table/dataformat/TypeGetterSetters.java  |  89 ++--
 .../flink/table/dataformat/util/BaseRowUtil.java   |   4 +-
 .../table/runtime/aggregate/BytesHashMap.java      |  16 +-
 .../table/runtime/aggregate/GroupAggFunction.java  |   6 +-
 .../aggregate/MiniBatchGlobalGroupAggFunction.java |   6 +-
 .../aggregate/MiniBatchGroupAggFunction.java       |  15 +-
 .../table/runtime/functions/SqlDateTimeUtils.java  |  18 +-
 .../flink/table/runtime/join/HashJoinOperator.java |   2 +-
 .../runtime/join/ProcTimeBoundedStreamJoin.java    |   6 +-
 .../runtime/join/RowTimeBoundedStreamJoin.java     |   6 +-
 .../table/runtime/join/TimeBoundedStreamJoin.java  |  10 +-
 .../runtime/join/lookup/AsyncLookupJoinRunner.java |   5 +-
 .../AbstractRowTimeUnboundedPrecedingOver.java     |  10 +-
 .../ProcTimeRangeBoundedPrecedingFunction.java     |  10 +-
 .../over/ProcTimeRowsBoundedPrecedingFunction.java |  10 +-
 .../over/ProcTimeUnboundedPrecedingFunction.java   |   6 +-
 .../over/RowTimeRangeBoundedPrecedingFunction.java |  10 +-
 .../RowTimeRangeUnboundedPrecedingFunction.java    |   6 +-
 .../over/RowTimeRowsBoundedPrecedingFunction.java  |  10 +-
 .../RowTimeRowsUnboundedPrecedingFunction.java     |   6 +-
 .../runtime/over/frame/RangeSlidingOverFrame.java  |   2 +-
 .../frame/RangeUnboundedFollowingOverFrame.java    |   2 +-
 .../runtime/over/frame/RowSlidingOverFrame.java    |   2 +-
 .../over/frame/RowUnboundedFollowingOverFrame.java |   2 +-
 .../table/runtime/over/frame/SlidingOverFrame.java |   6 +-
 .../over/frame/UnboundedFollowingOverFrame.java    |   4 +-
 .../over/frame/UnboundedOverWindowFrame.java       |   7 +-
 .../table/runtime/rank/AbstractTopNFunction.java   |  33 +-
 .../table/runtime/values/ValuesInputFormat.java    |   3 +-
 .../flink/table/runtime/window/WindowOperator.java |  28 +-
 .../runtime/window/WindowOperatorBuilder.java      |  24 +-
 .../org/apache/flink/table/type/ArrayType.java     |  63 ---
 .../org/apache/flink/table/type/AtomicType.java    |  25 -
 .../org/apache/flink/table/type/BinaryType.java    |  53 ---
 .../org/apache/flink/table/type/BooleanType.java   |  31 --
 .../java/org/apache/flink/table/type/ByteType.java |  31 --
 .../java/org/apache/flink/table/type/DateType.java |  61 ---
 .../org/apache/flink/table/type/DecimalType.java   | 164 -------
 .../org/apache/flink/table/type/DoubleType.java    |  31 --
 .../org/apache/flink/table/type/FloatType.java     |  31 --
 .../org/apache/flink/table/type/GenericType.java   |  86 ----
 .../java/org/apache/flink/table/type/IntType.java  |  31 --
 .../org/apache/flink/table/type/InternalType.java  |  38 --
 .../apache/flink/table/type/InternalTypeUtils.java |  92 ----
 .../org/apache/flink/table/type/InternalTypes.java | 114 -----
 .../java/org/apache/flink/table/type/LongType.java |  31 --
 .../java/org/apache/flink/table/type/MapType.java  |  79 ----
 .../org/apache/flink/table/type/MultisetType.java  |  61 ---
 .../org/apache/flink/table/type/PrimitiveType.java |  43 --
 .../java/org/apache/flink/table/type/RowType.java  | 130 ------
 .../org/apache/flink/table/type/ShortType.java     |  31 --
 .../org/apache/flink/table/type/StringType.java    |  47 --
 .../java/org/apache/flink/table/type/TimeType.java |  47 --
 .../org/apache/flink/table/type/TimestampType.java |  66 ---
 .../apache/flink/table/type/TypeConverters.java    | 272 -----------
 .../flink/table/types/ClassDataTypeConverter.java  |  46 ++
 .../table/types/ClassLogicalTypeConverter.java     | 174 +++++++
 .../flink/table/types/InternalSerializers.java     |  90 ++++
 .../table/types/LogicalTypeDataTypeConverter.java  | 172 +++++++
 .../apache/flink/table/types/PlannerTypeUtils.java | 105 +++++
 .../table/types/TypeInfoDataTypeConverter.java     | 113 +++++
 .../table/types/TypeInfoLogicalTypeConverter.java  |  59 +++
 .../flink/table/typeutils/BaseRowSerializer.java   |  50 +-
 .../flink/table/typeutils/BaseRowTypeInfo.java     |  45 +-
 .../flink/table/typeutils/BinaryArrayTypeInfo.java | 105 -----
 .../table/typeutils/BinaryGenericSerializer.java   |  31 +-
 .../table/typeutils/BinaryGenericTypeInfo.java     | 101 ----
 .../flink/table/typeutils/BinaryMapTypeInfo.java   | 113 -----
 .../apache/flink/table/dataformat/BaseRowTest.java |   8 +-
 .../flink/table/dataformat/BinaryArrayTest.java    |  10 +-
 .../flink/table/dataformat/BinaryRowTest.java      |  10 +-
 .../table/dataformat/DataFormatConvertersTest.java |  31 +-
 .../table/runtime/aggregate/BytesHashMapTest.java  |  70 +--
 .../runtime/aggregate/SumHashAggTestOperator.java  |   9 +-
 .../deduplicate/DeduplicateFunctionTestBase.java   |  12 +-
 .../runtime/join/AsyncLookupJoinHarnessTest.java   |   9 +-
 .../runtime/join/Int2HashJoinOperatorTest.java     |  10 +-
 .../table/runtime/join/LookupJoinHarnessTest.java  |   7 +-
 .../join/ProcTimeBoundedStreamJoinTest.java        |   2 +-
 .../runtime/join/RandomSortMergeInnerJoinTest.java |   7 +-
 .../runtime/join/RowTimeBoundedStreamJoinTest.java |   2 +-
 .../runtime/join/String2HashJoinOperatorTest.java  |  10 +-
 .../join/String2SortMergeJoinOperatorTest.java     |   6 +-
 .../join/TimeBoundedStreamJoinTestBase.java        |   9 +-
 .../over/BufferDataOverWindowOperatorTest.java     |  10 +-
 .../over/NonBufferOverWindowOperatorTest.java      |  11 +-
 .../table/runtime/rank/TopNFunctionTestBase.java   |  28 +-
 .../runtime/sort/ProcTimeSortOperatorTest.java     |  12 +-
 .../runtime/sort/RowTimeSortOperatorTest.java      |  20 +-
 .../table/runtime/sort/StreamSortOperatorTest.java |   7 +-
 .../table/runtime/util/BaseRowHarnessAssertor.java |   8 +-
 .../table/runtime/util/BinaryRowKeySelector.java   |  10 +-
 .../util/GenericRowRecordSortComparator.java       |   6 +-
 .../table/runtime/util/StreamRecordUtils.java      |  10 +-
 .../runtime/window/WindowOperatorContractTest.java |  16 +-
 .../table/runtime/window/WindowOperatorTest.java   |  48 +-
 .../apache/flink/table/type/InternalTypeTest.java  | 122 -----
 .../table/typeutils/BaseRowSerializerTest.java     |  44 +-
 .../typeutils/BinaryGenericSerializerTest.java     |   4 +-
 .../table/typeutils/BinaryRowTypeInfoTest.java     |  28 +-
 .../table/typeutils/InternalTypeInfoTest.java      |  12 +-
 360 files changed, 6042 insertions(+), 7286 deletions(-)

diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/calcite/type/FlinkReturnTypes.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/calcite/type/FlinkReturnTypes.java
index ed77ca1..e1f3199 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/calcite/type/FlinkReturnTypes.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/calcite/type/FlinkReturnTypes.java
@@ -19,12 +19,12 @@
 package org.apache.flink.table.calcite.type;
 
 import org.apache.flink.table.calcite.FlinkTypeFactory;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalTypes;
+import org.apache.flink.table.calcite.FlinkTypeSystem;
+import org.apache.flink.table.types.logical.DecimalType;
+import org.apache.flink.table.types.logical.MapType;
+import org.apache.flink.table.types.logical.VarCharType;
 
 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.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.type.OrdinalReturnTypeInference;
 import org.apache.calcite.sql.type.ReturnTypes;
@@ -65,9 +65,9 @@ public class FlinkReturnTypes {
 			final int p = numType.getPrecision();
 			final int s = numType.getScale();
 			final int r = lenVal.intValueExact();
-			DecimalType dt = DecimalType.inferRoundType(p, s, r);
+			DecimalType dt = FlinkTypeSystem.inferRoundType(p, s, r);
 			return opBinding.getTypeFactory().createSqlType(
-				SqlTypeName.DECIMAL, dt.precision(), dt.scale());
+				SqlTypeName.DECIMAL, dt.getPrecision(), dt.getScale());
 		}
 
 		private BigDecimal getArg1Literal(SqlOperatorBinding opBinding) {
@@ -102,41 +102,35 @@ public class FlinkReturnTypes {
 		}
 	};
 
-	public static final SqlReturnTypeInference FLINK_QUOTIENT_NULLABLE = new SqlReturnTypeInference() {
-		@Override
-		public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
-			RelDataType type1 = opBinding.getOperandType(0);
-			RelDataType type2 = opBinding.getOperandType(1);
-			if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) {
-				return ReturnTypes.QUOTIENT_NULLABLE.inferReturnType(opBinding);
+	public static final SqlReturnTypeInference FLINK_QUOTIENT_NULLABLE = opBinding -> {
+		RelDataType type1 = opBinding.getOperandType(0);
+		RelDataType type2 = opBinding.getOperandType(1);
+		if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) {
+			return ReturnTypes.QUOTIENT_NULLABLE.inferReturnType(opBinding);
+		} else {
+			RelDataType doubleType = opBinding.getTypeFactory().createSqlType(SqlTypeName.DOUBLE);
+			if (type1.isNullable() || type2.isNullable()) {
+				return opBinding.getTypeFactory().createTypeWithNullability(doubleType, true);
 			} else {
-				RelDataType doubleType = opBinding.getTypeFactory().createSqlType(SqlTypeName.DOUBLE);
-				if (type1.isNullable() || type2.isNullable()) {
-					return opBinding.getTypeFactory().createTypeWithNullability(doubleType, true);
-				} else {
-					return doubleType;
-				}
+				return doubleType;
 			}
 		}
 	};
 
-	public static final SqlReturnTypeInference FLINK_DIV_NULLABLE = new SqlReturnTypeInference() {
-
-		@Override
-		public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
-			RelDataType type1 = opBinding.getOperandType(0);
-			RelDataType type2 = opBinding.getOperandType(1);
-			RelDataType returnType;
-			if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) {
-				DecimalType dt = DecimalType.inferIntDivType(type1.getPrecision(), type1.getScale(), type2.getScale());
-				returnType = opBinding.getTypeFactory().createSqlType(
-					SqlTypeName.DECIMAL, dt.precision(), dt.scale());
-			} else { // both are primitive
-				returnType = type1;
-			}
-			return opBinding.getTypeFactory().createTypeWithNullability(returnType,
-				type1.isNullable() || type2.isNullable());
+	public static final SqlReturnTypeInference FLINK_DIV_NULLABLE = opBinding -> {
+		RelDataType type1 = opBinding.getOperandType(0);
+		RelDataType type2 = opBinding.getOperandType(1);
+		RelDataType returnType;
+		if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) {
+			DecimalType dt = FlinkTypeSystem.inferIntDivType(
+					type1.getPrecision(), type1.getScale(), type2.getScale());
+			returnType = opBinding.getTypeFactory().createSqlType(
+				SqlTypeName.DECIMAL, dt.getPrecision(), dt.getScale());
+		} else { // both are primitive
+			returnType = type1;
 		}
+		return opBinding.getTypeFactory().createTypeWithNullability(returnType,
+			type1.isNullable() || type2.isNullable());
 	};
 
 	/**
@@ -154,14 +148,7 @@ public class FlinkReturnTypes {
 	public static final SqlReturnTypeInference NUMERIC_FROM_ARG1_DEFAULT1_NULLABLE =
 		ReturnTypes.cascade(NUMERIC_FROM_ARG1_DEFAULT1, SqlTypeTransforms.TO_NULLABLE);
 
-	public static final SqlReturnTypeInference STR_MAP_NULLABLE = ReturnTypes.explicit(new RelProtoDataType() {
-		@Override
-		public RelDataType apply(RelDataTypeFactory factory) {
-			return ((FlinkTypeFactory) factory).createTypeFromInternalType(
-				InternalTypes.createMapType(InternalTypes.STRING, InternalTypes.STRING),
-				true
-			);
-		}
-	});
-
+	public static final SqlReturnTypeInference STR_MAP_NULLABLE = ReturnTypes.explicit(
+			factory -> ((FlinkTypeFactory) factory).createFieldTypeFromLogicalType(
+		new MapType(new VarCharType(VarCharType.MAX_LENGTH), new VarCharType(VarCharType.MAX_LENGTH))));
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ExpressionBuilder.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ExpressionBuilder.java
index bb0d2c6..c8e4600 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ExpressionBuilder.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ExpressionBuilder.java
@@ -18,7 +18,7 @@
 
 package org.apache.flink.table.expressions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.table.types.DataType;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -41,14 +41,13 @@ import static org.apache.flink.table.expressions.BuiltInFunctionDefinitions.PLUS
 import static org.apache.flink.table.expressions.BuiltInFunctionDefinitions.REINTERPRET_CAST;
 import static org.apache.flink.table.expressions.BuiltInFunctionDefinitions.TIMES;
 import static org.apache.flink.table.expressions.InternalFunctionDefinitions.THROW_EXCEPTION;
-import static org.apache.flink.table.types.utils.TypeConversions.fromLegacyInfoToDataType;
 
 /**
  * Builder for {@link Expression}s.
  */
 public class ExpressionBuilder {
 
-	public static Expression nullOf(TypeInformation type) {
+	public static Expression nullOf(DataType type) {
 		return literal(null, type);
 	}
 
@@ -56,8 +55,8 @@ public class ExpressionBuilder {
 		return new ValueLiteralExpression(value);
 	}
 
-	public static Expression literal(Object value, TypeInformation<?> type) {
-		return new ValueLiteralExpression(value, fromLegacyInfoToDataType(type));
+	public static Expression literal(Object value, DataType type) {
+		return new ValueLiteralExpression(value, type);
 	}
 
 	public static Expression call(FunctionDefinition functionDefinition, Expression... args) {
@@ -130,15 +129,15 @@ public class ExpressionBuilder {
 		return call(REINTERPRET_CAST, child, type, literal(checkOverflow));
 	}
 
-	public static TypeLiteralExpression typeLiteral(TypeInformation<?> type) {
-		return new TypeLiteralExpression(fromLegacyInfoToDataType(type));
+	public static TypeLiteralExpression typeLiteral(DataType type) {
+		return new TypeLiteralExpression(type);
 	}
 
 	public static Expression concat(Expression input1, Expression input2) {
 		return call(CONCAT, input1, input2);
 	}
 
-	public static Expression throwException(String msg, TypeInformation<?> type) {
+	public static Expression throwException(String msg, DataType type) {
 		return call(THROW_EXCEPTION, typeLiteral(type));
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedAggInputReference.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedAggInputReference.java
index ef91692..a736def 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedAggInputReference.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedAggInputReference.java
@@ -18,7 +18,7 @@
 
 package org.apache.flink.table.expressions;
 
-import org.apache.flink.table.type.InternalType;
+import org.apache.flink.table.types.logical.LogicalType;
 import org.apache.flink.util.Preconditions;
 
 import java.util.Collections;
@@ -33,9 +33,9 @@ public class ResolvedAggInputReference implements Expression {
 
 	private final String name;
 	private final int index;
-	private final InternalType resultType;
+	private final LogicalType resultType;
 
-	public ResolvedAggInputReference(String name, int index, InternalType resultType) {
+	public ResolvedAggInputReference(String name, int index, LogicalType resultType) {
 		this.name = Preconditions.checkNotNull(name);
 		this.index = index;
 		this.resultType = resultType;
@@ -49,7 +49,7 @@ public class ResolvedAggInputReference implements Expression {
 		return index;
 	}
 
-	public InternalType getResultType() {
+	public LogicalType getResultType() {
 		return resultType;
 	}
 
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedAggLocalReference.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedAggLocalReference.java
index 6b1eabd..f1b3fa6 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedAggLocalReference.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedAggLocalReference.java
@@ -18,7 +18,7 @@
 
 package org.apache.flink.table.expressions;
 
-import org.apache.flink.table.type.InternalType;
+import org.apache.flink.table.types.logical.LogicalType;
 
 import java.util.Collections;
 import java.util.List;
@@ -34,9 +34,9 @@ public class ResolvedAggLocalReference implements Expression {
 
 	private final String fieldTerm;
 	private final String nullTerm;
-	private final InternalType resultType;
+	private final LogicalType resultType;
 
-	public ResolvedAggLocalReference(String fieldTerm, String nullTerm, InternalType resultType) {
+	public ResolvedAggLocalReference(String fieldTerm, String nullTerm, LogicalType resultType) {
 		this.fieldTerm = fieldTerm;
 		this.nullTerm = nullTerm;
 		this.resultType = resultType;
@@ -50,7 +50,7 @@ public class ResolvedAggLocalReference implements Expression {
 		return nullTerm;
 	}
 
-	public InternalType getResultType() {
+	public LogicalType getResultType() {
 		return resultType;
 	}
 
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedDistinctKeyReference.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedDistinctKeyReference.java
index ab64a06..ead7ed2 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedDistinctKeyReference.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/ResolvedDistinctKeyReference.java
@@ -18,7 +18,7 @@
 
 package org.apache.flink.table.expressions;
 
-import org.apache.flink.table.type.InternalType;
+import org.apache.flink.table.types.logical.LogicalType;
 import org.apache.flink.util.Preconditions;
 
 import java.util.Collections;
@@ -30,9 +30,9 @@ import java.util.List;
 public class ResolvedDistinctKeyReference implements Expression {
 
 	private final String name;
-	private final InternalType resultType;
+	private final LogicalType resultType;
 
-	public ResolvedDistinctKeyReference(String name, InternalType resultType) {
+	public ResolvedDistinctKeyReference(String name, LogicalType resultType) {
 		this.name = Preconditions.checkNotNull(name);
 		this.resultType = resultType;
 	}
@@ -41,7 +41,7 @@ public class ResolvedDistinctKeyReference implements Expression {
 		return name;
 	}
 
-	public InternalType getResultType() {
+	public LogicalType getResultType() {
 		return resultType;
 	}
 
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/RexNodeConverter.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/RexNodeConverter.java
index 1aea244..e0c2c27 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/RexNodeConverter.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/expressions/RexNodeConverter.java
@@ -18,18 +18,22 @@
 
 package org.apache.flink.table.expressions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
 import org.apache.flink.table.api.TableException;
 import org.apache.flink.table.calcite.FlinkTypeFactory;
 import org.apache.flink.table.calcite.RexAggLocalVariable;
 import org.apache.flink.table.calcite.RexDistinctKeyVariable;
 import org.apache.flink.table.dataformat.Decimal;
 import org.apache.flink.table.functions.sql.FlinkSqlOperatorTable;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
+import org.apache.flink.table.types.logical.BigIntType;
+import org.apache.flink.table.types.logical.DateType;
+import org.apache.flink.table.types.logical.DayTimeIntervalType;
+import org.apache.flink.table.types.logical.DecimalType;
+import org.apache.flink.table.types.logical.DoubleType;
+import org.apache.flink.table.types.logical.FloatType;
 import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.TimeType;
+import org.apache.flink.table.types.logical.TimestampType;
+import org.apache.flink.table.types.logical.YearMonthIntervalType;
 
 import org.apache.calcite.avatica.util.TimeUnit;
 import org.apache.calcite.rel.type.RelDataType;
@@ -52,20 +56,11 @@ import java.util.Optional;
 import java.util.stream.Collectors;
 
 import static org.apache.calcite.sql.type.SqlTypeName.VARCHAR;
-import static org.apache.flink.table.calcite.FlinkTypeFactory.toInternalType;
-import static org.apache.flink.table.type.TypeConverters.createInternalTypeFromTypeInfo;
-import static org.apache.flink.table.types.logical.LogicalTypeRoot.CHAR;
-import static org.apache.flink.table.types.logical.LogicalTypeRoot.DECIMAL;
-import static org.apache.flink.table.types.logical.LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE;
-import static org.apache.flink.table.types.logical.utils.LogicalTypeChecks.getPrecision;
-import static org.apache.flink.table.types.logical.utils.LogicalTypeChecks.hasLength;
-import static org.apache.flink.table.types.logical.utils.LogicalTypeChecks.hasPrecision;
-import static org.apache.flink.table.types.logical.utils.LogicalTypeChecks.hasRoot;
-import static org.apache.flink.table.types.logical.utils.LogicalTypeChecks.hasScale;
-import static org.apache.flink.table.types.utils.TypeConversions.fromDataTypeToLegacyInfo;
-import static org.apache.flink.table.typeutils.TypeCheckUtils.isString;
+import static org.apache.flink.table.calcite.FlinkTypeFactory.toLogicalType;
+import static org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType;
 import static org.apache.flink.table.typeutils.TypeCheckUtils.isTemporal;
 import static org.apache.flink.table.typeutils.TypeCheckUtils.isTimeInterval;
+import static org.apache.flink.table.typeutils.TypeCheckUtils.isVarchar;
 
 /**
  * Visit expression to generator {@link RexNode}.
@@ -102,20 +97,16 @@ public class RexNodeConverter implements ExpressionVisitor<RexNode> {
 			RexNode child = call.getChildren().get(0).accept(this);
 			TypeLiteralExpression type = (TypeLiteralExpression) call.getChildren().get(1);
 			return relBuilder.getRexBuilder().makeAbstractCast(
-					typeFactory.createTypeFromInternalType(
-							createInternalTypeFromTypeInfo(
-								fromDataTypeToLegacyInfo(type.getOutputDataType())),
-							child.getType().isNullable()),
+					typeFactory.createFieldTypeFromLogicalType(
+							type.getOutputDataType().getLogicalType().copy(child.getType().isNullable())),
 					child);
 		} else if (call.getFunctionDefinition().equals(BuiltInFunctionDefinitions.REINTERPRET_CAST)) {
 			RexNode child = call.getChildren().get(0).accept(this);
 			TypeLiteralExpression type = (TypeLiteralExpression) call.getChildren().get(1);
 			RexNode checkOverflow = call.getChildren().get(2).accept(this);
 			return relBuilder.getRexBuilder().makeReinterpretCast(
-					typeFactory.createTypeFromInternalType(
-							createInternalTypeFromTypeInfo(
-								fromDataTypeToLegacyInfo(type.getOutputDataType())),
-							child.getType().isNullable()),
+					typeFactory.createFieldTypeFromLogicalType(
+							type.getOutputDataType().getLogicalType().copy(child.getType().isNullable())),
 					child,
 					checkOverflow);
 		}
@@ -126,26 +117,26 @@ public class RexNodeConverter implements ExpressionVisitor<RexNode> {
 		} else if (BuiltInFunctionDefinitions.IS_NULL.equals(def)) {
 			return relBuilder.isNull(child.get(0));
 		} else if (BuiltInFunctionDefinitions.PLUS.equals(def)) {
-			if (isString(toInternalType(child.get(0).getType()))) {
+			if (isVarchar(toLogicalType(child.get(0).getType()))) {
 				return relBuilder.call(
 						FlinkSqlOperatorTable.CONCAT,
 						child.get(0),
 						relBuilder.cast(child.get(1), VARCHAR));
-			} else if (isString(toInternalType(child.get(1).getType()))) {
+			} else if (isVarchar(toLogicalType(child.get(1).getType()))) {
 				return relBuilder.call(
 						FlinkSqlOperatorTable.CONCAT,
 						relBuilder.cast(child.get(0), VARCHAR),
 						child.get(1));
-			} else if (isTimeInterval(toInternalType(child.get(0).getType())) &&
+			} else if (isTimeInterval(toLogicalType(child.get(0).getType())) &&
 					child.get(0).getType() == child.get(1).getType()) {
 				return relBuilder.call(FlinkSqlOperatorTable.PLUS, child);
-			} else if (isTimeInterval(toInternalType(child.get(0).getType()))
-					&& isTemporal(toInternalType(child.get(1).getType()))) {
+			} else if (isTimeInterval(toLogicalType(child.get(0).getType()))
+					&& isTemporal(toLogicalType(child.get(1).getType()))) {
 				// Calcite has a bug that can't apply INTERVAL + DATETIME (INTERVAL at left)
 				// we manually switch them here
 				return relBuilder.call(FlinkSqlOperatorTable.DATETIME_PLUS, child);
-			} else if (isTemporal(toInternalType(child.get(0).getType())) &&
-					isTemporal(toInternalType(child.get(1).getType()))) {
+			} else if (isTemporal(toLogicalType(child.get(0).getType())) &&
+					isTemporal(toLogicalType(child.get(1).getType()))) {
 				return relBuilder.call(FlinkSqlOperatorTable.DATETIME_PLUS, child);
 			} else {
 				return relBuilder.call(FlinkSqlOperatorTable.PLUS, child);
@@ -181,13 +172,13 @@ public class RexNodeConverter implements ExpressionVisitor<RexNode> {
 
 	@Override
 	public RexNode visitValueLiteral(ValueLiteralExpression expr) {
-		InternalType type = createInternalTypeFromTypeInfo(getLiteralTypeInfo(expr));
+		LogicalType type = fromDataTypeToLogicalType(expr.getOutputDataType());
 		RexBuilder rexBuilder = relBuilder.getRexBuilder();
 		FlinkTypeFactory typeFactory = (FlinkTypeFactory) relBuilder.getTypeFactory();
 		if (expr.isNull()) {
 			return relBuilder.getRexBuilder()
 					.makeCast(
-							typeFactory.createTypeFromInternalType(type, true),
+							typeFactory.createFieldTypeFromLogicalType(type),
 							relBuilder.getRexBuilder().constantNull());
 		}
 
@@ -195,37 +186,37 @@ public class RexNodeConverter implements ExpressionVisitor<RexNode> {
 			DecimalType dt = (DecimalType) type;
 			BigDecimal bigDecimal = extractValue(expr, BigDecimal.class);
 			RelDataType decType = relBuilder.getTypeFactory().createSqlType(SqlTypeName.DECIMAL,
-					dt.precision(), dt.scale());
+					dt.getPrecision(), dt.getScale());
 			return relBuilder.getRexBuilder().makeExactLiteral(bigDecimal, decType);
-		} else if (InternalTypes.LONG.equals(type)) {
+		} else if (type instanceof BigIntType) {
 			// create BIGINT literals for long type
 			BigDecimal bigint = extractValue(expr, BigDecimal.class);
 			return relBuilder.getRexBuilder().makeBigintLiteral(bigint);
-		} else if (InternalTypes.FLOAT.equals(type)) {
+		} else if (type instanceof FloatType) {
 			//Float/Double type should be liked as java type here.
 			return relBuilder.getRexBuilder().makeApproxLiteral(
 					extractValue(expr, BigDecimal.class),
 					relBuilder.getTypeFactory().createSqlType(SqlTypeName.FLOAT));
-		} else if (InternalTypes.DOUBLE.equals(type)) {
+		} else if (type instanceof DoubleType) {
 			//Float/Double type should be liked as java type here.
 			return rexBuilder.makeApproxLiteral(
 					extractValue(expr, BigDecimal.class),
 					relBuilder.getTypeFactory().createSqlType(SqlTypeName.DOUBLE));
-		} else if (InternalTypes.DATE.equals(type)) {
+		} else if (type instanceof DateType) {
 			return relBuilder.getRexBuilder().makeDateLiteral(
 					DateString.fromCalendarFields(valueAsCalendar(extractValue(expr, java.sql.Date.class))));
-		} else if (InternalTypes.TIME.equals(type)) {
+		} else if (type instanceof TimeType) {
 			return relBuilder.getRexBuilder().makeTimeLiteral(
 					TimeString.fromCalendarFields(valueAsCalendar(extractValue(expr, java.sql.Time.class))), 0);
-		} else if (InternalTypes.TIMESTAMP.equals(type)) {
+		} else if (type instanceof TimestampType) {
 			return relBuilder.getRexBuilder().makeTimestampLiteral(
 					TimestampString.fromCalendarFields(valueAsCalendar(extractValue(expr, java.sql.Timestamp.class))), 3);
-		} else if (InternalTypes.INTERVAL_MONTHS.equals(type)) {
+		} else if (type instanceof YearMonthIntervalType) {
 			BigDecimal interval = BigDecimal.valueOf(extractValue(expr, Integer.class));
 			SqlIntervalQualifier intervalQualifier = new SqlIntervalQualifier(
 					TimeUnit.YEAR, TimeUnit.MONTH, SqlParserPos.ZERO);
 			return relBuilder.getRexBuilder().makeIntervalLiteral(interval, intervalQualifier);
-		} else if (InternalTypes.TIMESTAMP.equals(type)) {
+		} else if (type instanceof DayTimeIntervalType) {
 			BigDecimal interval = BigDecimal.valueOf(extractValue(expr, Long.class));
 			SqlIntervalQualifier intervalQualifier = new SqlIntervalQualifier(
 					TimeUnit.DAY, TimeUnit.SECOND, SqlParserPos.ZERO);
@@ -236,41 +227,6 @@ public class RexNodeConverter implements ExpressionVisitor<RexNode> {
 	}
 
 	/**
-	 * This method makes the planner more lenient for new data types defined for literals.
-	 */
-	private static TypeInformation<?> getLiteralTypeInfo(ValueLiteralExpression literal) {
-		final LogicalType logicalType = literal.getOutputDataType().getLogicalType();
-
-		if (hasRoot(logicalType, DECIMAL)) {
-			if (literal.isNull()) {
-				return Types.BIG_DEC;
-			}
-			final BigDecimal value = extractValue(literal, BigDecimal.class);
-			if (hasPrecision(logicalType, value.precision()) && hasScale(logicalType, value.scale())) {
-				return Types.BIG_DEC;
-			}
-		}
-
-		else if (hasRoot(logicalType, CHAR)) {
-			if (literal.isNull()) {
-				return Types.STRING;
-			}
-			final String value = extractValue(literal, String.class);
-			if (hasLength(logicalType, value.length())) {
-				return Types.STRING;
-			}
-		}
-
-		else if (hasRoot(logicalType, TIMESTAMP_WITHOUT_TIME_ZONE)) {
-			if (getPrecision(logicalType) <= 3) {
-				return Types.SQL_TIMESTAMP;
-			}
-		}
-
-		return fromDataTypeToLegacyInfo(literal.getOutputDataType());
-	}
-
-	/**
 	 * Extracts a value from a literal. Including planner-specific instances such as {@link Decimal}.
 	 */
 	@SuppressWarnings("unchecked")
@@ -342,23 +298,23 @@ public class RexNodeConverter implements ExpressionVisitor<RexNode> {
 		// using index to resolve field directly, name used in toString only
 		return new RexInputRef(
 				reference.getIndex(),
-				typeFactory.createTypeFromInternalType(reference.getResultType(), true));
+				typeFactory.createFieldTypeFromLogicalType(reference.getResultType()));
 	}
 
 	private RexNode visitResolvedAggLocalReference(ResolvedAggLocalReference reference) {
-		InternalType type = reference.getResultType();
+		LogicalType type = reference.getResultType();
 		return new RexAggLocalVariable(
 				reference.getFieldTerm(),
 				reference.getNullTerm(),
-				typeFactory.createTypeFromInternalType(type, true),
+				typeFactory.createFieldTypeFromLogicalType(type),
 				type);
 	}
 
 	private RexNode visitResolvedDistinctKeyReference(ResolvedDistinctKeyReference reference) {
-		InternalType type = reference.getResultType();
+		LogicalType type = reference.getResultType();
 		return new RexDistinctKeyVariable(
 				reference.getName(),
-				typeFactory.createTypeFromInternalType(type, true),
+				typeFactory.createFieldTypeFromLogicalType(type),
 				type);
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/AvgAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/AvgAggFunction.java
index 83c1192..cdb4ec9 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/AvgAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/AvgAggFunction.java
@@ -18,16 +18,12 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
-import org.apache.flink.table.dataformat.Decimal;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.calcite.FlinkTypeSystem;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
 
 import java.math.BigDecimal;
 
@@ -48,7 +44,7 @@ public abstract class AvgAggFunction extends DeclarativeAggregateFunction {
 	private UnresolvedReferenceExpression sum = new UnresolvedReferenceExpression("sum");
 	private UnresolvedReferenceExpression count = new UnresolvedReferenceExpression("count");
 
-	public abstract TypeInformation getSumType();
+	public abstract DataType getSumType();
 
 	@Override
 	public int operandCount() {
@@ -63,10 +59,10 @@ public abstract class AvgAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] {
-				TypeConverters.createInternalTypeFromTypeInfo(getSumType()),
-				InternalTypes.LONG
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] {
+				getSumType(),
+				DataTypes.BIGINT()
 		};
 	}
 
@@ -117,13 +113,13 @@ public abstract class AvgAggFunction extends DeclarativeAggregateFunction {
 	public static class IntegralAvgAggFunction extends AvgAggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 
 		@Override
-		public TypeInformation getSumType() {
-			return Types.LONG;
+		public DataType getSumType() {
+			return DataTypes.BIGINT();
 		}
 	}
 
@@ -133,13 +129,13 @@ public abstract class AvgAggFunction extends DeclarativeAggregateFunction {
 	public static class DoubleAvgAggFunction extends AvgAggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 
 		@Override
-		public TypeInformation getSumType() {
-			return Types.DOUBLE;
+		public DataType getSumType() {
+			return DataTypes.DOUBLE();
 		}
 
 		@Override
@@ -153,27 +149,29 @@ public abstract class AvgAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class DecimalAvgAggFunction extends AvgAggFunction {
 
-		private final DecimalTypeInfo type;
+		private final DecimalType type;
 
-		public DecimalAvgAggFunction(DecimalTypeInfo type) {
+		public DecimalAvgAggFunction(DecimalType type) {
 			this.type = type;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return DecimalType.inferAggAvgType(type.scale()).toTypeInfo();
+		public DataType getResultType() {
+			DecimalType t = FlinkTypeSystem.inferAggAvgType(type.getScale());
+			return DataTypes.DECIMAL(t.getPrecision(), t.getScale());
 		}
 
 		@Override
-		public TypeInformation getSumType() {
-			return DecimalType.inferAggSumType(type.scale()).toTypeInfo();
+		public DataType getSumType() {
+			DecimalType t = FlinkTypeSystem.inferAggSumType(type.getScale());
+			return DataTypes.DECIMAL(t.getPrecision(), t.getScale());
 		}
 
 		@Override
 		public Expression[] initialValuesExpressions() {
 			return new Expression[] {
 				literal(
-					Decimal.fromBigDecimal(BigDecimal.ZERO, type.precision(), type.scale()),
+					BigDecimal.ZERO,
 					getSumType()),
 				literal(0L)
 			};
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/ConcatAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/ConcatAggFunction.java
index 852de04..dce2cc7 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/ConcatAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/ConcatAggFunction.java
@@ -18,14 +18,11 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
-import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.api.TableException;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.typeutils.BinaryStringTypeInfo;
+import org.apache.flink.table.types.DataType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.concat;
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
@@ -46,7 +43,7 @@ public class ConcatAggFunction extends DeclarativeAggregateFunction {
 	public ConcatAggFunction(int operandCount) {
 		this.operandCount = operandCount;
 		if (operandCount == 1) {
-			delimiter = literal("\n", BasicTypeInfo.STRING_TYPE_INFO);
+			delimiter = literal("\n", DataTypes.STRING());
 			operand = operand(0);
 		} else {
 			delimiter = operand(0);
@@ -65,20 +62,20 @@ public class ConcatAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { InternalTypes.STRING, InternalTypes.STRING };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { DataTypes.STRING(), DataTypes.STRING() };
 	}
 
 	@Override
-	public TypeInformation getResultType() {
-		return BinaryStringTypeInfo.INSTANCE;
+	public DataType getResultType() {
+		return DataTypes.STRING();
 	}
 
 	@Override
 	public Expression[] initialValuesExpressions() {
 		return new Expression[] {
-				/* delimiter */ literal("\n", BasicTypeInfo.STRING_TYPE_INFO),
-				/* acc */ nullOf(BasicTypeInfo.STRING_TYPE_INFO)
+				/* delimiter */ literal("\n", DataTypes.STRING()),
+				/* acc */ nullOf(DataTypes.STRING())
 		};
 	}
 
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/Count1AggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/Count1AggFunction.java
index c3bf00f..046644c 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/Count1AggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/Count1AggFunction.java
@@ -18,12 +18,10 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
+import org.apache.flink.table.types.DataType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.literal;
 import static org.apache.flink.table.expressions.ExpressionBuilder.minus;
@@ -48,13 +46,13 @@ public class Count1AggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { InternalTypes.LONG };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { DataTypes.BIGINT() };
 	}
 
 	@Override
-	public TypeInformation getResultType() {
-		return Types.LONG;
+	public DataType getResultType() {
+		return DataTypes.BIGINT();
 	}
 
 	@Override
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/CountAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/CountAggFunction.java
index dc60190..b849ebd 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/CountAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/CountAggFunction.java
@@ -18,12 +18,10 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
+import org.apache.flink.table.types.DataType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
 import static org.apache.flink.table.expressions.ExpressionBuilder.isNull;
@@ -48,13 +46,13 @@ public class CountAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { InternalTypes.LONG };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { DataTypes.BIGINT() };
 	}
 
 	@Override
-	public TypeInformation getResultType() {
-		return Types.LONG;
+	public DataType getResultType() {
+		return DataTypes.BIGINT();
 	}
 
 	@Override
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/DeclarativeAggregateFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/DeclarativeAggregateFunction.java
index 00eae36..a3c8633 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/DeclarativeAggregateFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/DeclarativeAggregateFunction.java
@@ -18,11 +18,10 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
 import org.apache.flink.table.functions.UserDefinedFunction;
-import org.apache.flink.table.type.InternalType;
+import org.apache.flink.table.types.DataType;
 import org.apache.flink.util.Preconditions;
 
 import java.util.Arrays;
@@ -62,12 +61,12 @@ public abstract class DeclarativeAggregateFunction extends UserDefinedFunction {
 	/**
 	 * All types of the aggregate buffer.
 	 */
-	public abstract InternalType[] getAggBufferTypes();
+	public abstract DataType[] getAggBufferTypes();
 
 	/**
 	 * The result type of the function.
 	 */
-	public abstract TypeInformation getResultType();
+	public abstract DataType getResultType();
 
 	/**
 	 * Expressions for initializing empty aggregation buffers.
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/DenseRankAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/DenseRankAggFunction.java
index 7997dca..0439746 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/DenseRankAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/DenseRankAggFunction.java
@@ -18,10 +18,14 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.utils.LogicalTypeDataTypeConverter;
+
+import java.util.Arrays;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
 import static org.apache.flink.table.expressions.ExpressionBuilder.literal;
@@ -32,7 +36,7 @@ import static org.apache.flink.table.expressions.ExpressionBuilder.plus;
  */
 public class DenseRankAggFunction extends RankLikeAggFunctionBase {
 
-	public DenseRankAggFunction(InternalType[] orderKeyTypes) {
+	public DenseRankAggFunction(LogicalType[] orderKeyTypes) {
 		super(orderKeyTypes);
 	}
 
@@ -45,10 +49,12 @@ public class DenseRankAggFunction extends RankLikeAggFunctionBase {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		InternalType[] aggBufferTypes = new InternalType[1 + orderKeyTypes.length];
-		aggBufferTypes[0] = InternalTypes.LONG;
-		System.arraycopy(orderKeyTypes, 0, aggBufferTypes, 1, orderKeyTypes.length);
+	public DataType[] getAggBufferTypes() {
+		DataType[] aggBufferTypes = new DataType[1 + orderKeyTypes.length];
+		aggBufferTypes[0] = DataTypes.BIGINT();
+		System.arraycopy(Arrays.stream(orderKeyTypes)
+				.map(LogicalTypeDataTypeConverter::toDataType).toArray(DataType[]::new),
+				0, aggBufferTypes, 1, orderKeyTypes.length);
 		return aggBufferTypes;
 	}
 
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/FirstValueAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/FirstValueAggFunction.java
index c7eb856..7c6af1f 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/FirstValueAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/FirstValueAggFunction.java
@@ -24,13 +24,14 @@ import org.apache.flink.table.dataformat.BinaryString;
 import org.apache.flink.table.dataformat.Decimal;
 import org.apache.flink.table.dataformat.GenericRow;
 import org.apache.flink.table.functions.AggregateFunction;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.type.TypeConverters;
+import org.apache.flink.table.types.logical.BigIntType;
+import org.apache.flink.table.types.logical.LogicalType;
 import org.apache.flink.table.typeutils.BaseRowTypeInfo;
 import org.apache.flink.table.typeutils.BinaryStringTypeInfo;
 import org.apache.flink.table.typeutils.DecimalTypeInfo;
 
+import static org.apache.flink.table.types.TypeInfoLogicalTypeConverter.fromTypeInfoToLogicalType;
+
 /**
  * built-in FirstValue aggregate function.
  */
@@ -78,9 +79,9 @@ public abstract class FirstValueAggFunction<T> extends AggregateFunction<T, Gene
 
 	@Override
 	public TypeInformation<GenericRow> getAccumulatorType() {
-		InternalType[] fieldTypes = new InternalType[] {
-				TypeConverters.createInternalTypeFromTypeInfo(getResultType()),
-				InternalTypes.LONG
+		LogicalType[] fieldTypes = new LogicalType[] {
+				fromTypeInfoToLogicalType(getResultType()),
+				new BigIntType()
 		};
 
 		String[] fieldNames = new String[] {
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/FirstValueWithRetractAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/FirstValueWithRetractAggFunction.java
index 97a4961..344e797 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/FirstValueWithRetractAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/FirstValueWithRetractAggFunction.java
@@ -37,10 +37,9 @@ import org.apache.flink.table.dataformat.BinaryString;
 import org.apache.flink.table.dataformat.Decimal;
 import org.apache.flink.table.dataformat.GenericRow;
 import org.apache.flink.table.functions.AggregateFunction;
-import org.apache.flink.table.type.GenericType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.type.TypeConverters;
+import org.apache.flink.table.types.logical.BigIntType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.TypeInformationAnyType;
 import org.apache.flink.table.typeutils.BaseRowTypeInfo;
 import org.apache.flink.table.typeutils.BinaryStringSerializer;
 import org.apache.flink.table.typeutils.BinaryStringTypeInfo;
@@ -53,6 +52,8 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import static org.apache.flink.table.types.TypeInfoLogicalTypeConverter.fromTypeInfoToLogicalType;
+
 /**
  * built-in FirstValue with retraction aggregate function.
  */
@@ -187,11 +188,11 @@ public abstract class FirstValueWithRetractAggFunction<T> extends AggregateFunct
 
 	@Override
 	public TypeInformation<GenericRow> getAccumulatorType() {
-		InternalType[] fieldTypes = new InternalType[] {
-				TypeConverters.createInternalTypeFromTypeInfo(getResultType()),
-				InternalTypes.LONG,
-				new GenericType<>(new MapViewTypeInfo<>(getResultType(), new ListTypeInfo<>(Types.LONG), false, false)),
-				new GenericType<>(new MapViewTypeInfo<>(Types.LONG, new ListTypeInfo<>(getResultType()), false, false))
+		LogicalType[] fieldTypes = new LogicalType[] {
+				fromTypeInfoToLogicalType(getResultType()),
+				new BigIntType(),
+				new TypeInformationAnyType<>(new MapViewTypeInfo<>(getResultType(), new ListTypeInfo<>(Types.LONG), false, false)),
+				new TypeInformationAnyType<>(new MapViewTypeInfo<>(Types.LONG, new ListTypeInfo<>(getResultType()), false, false))
 		};
 
 		String[] fieldNames = new String[] {
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/IncrSumAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/IncrSumAggFunction.java
index 828e5c3..0eccfef 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/IncrSumAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/IncrSumAggFunction.java
@@ -18,15 +18,13 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.api.TableException;
+import org.apache.flink.table.calcite.FlinkTypeSystem;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
 import static org.apache.flink.table.expressions.ExpressionBuilder.isNull;
@@ -54,8 +52,8 @@ public abstract class IncrSumAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { TypeConverters.createInternalTypeFromTypeInfo(getResultType()) };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { getResultType() };
 	}
 
 	@Override
@@ -99,8 +97,8 @@ public abstract class IncrSumAggFunction extends DeclarativeAggregateFunction {
 	public static class IntIncrSumAggFunction extends IncrSumAggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 	}
 
@@ -109,8 +107,8 @@ public abstract class IncrSumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ByteIncrSumAggFunction extends IncrSumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 	}
 
@@ -119,8 +117,8 @@ public abstract class IncrSumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ShortIncrSumAggFunction extends IncrSumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 	}
 
@@ -129,8 +127,8 @@ public abstract class IncrSumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class LongIncrSumAggFunction extends IncrSumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 	}
 
@@ -139,8 +137,8 @@ public abstract class IncrSumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class FloatIncrSumAggFunction extends IncrSumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 	}
 
@@ -149,8 +147,8 @@ public abstract class IncrSumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class DoubleIncrSumAggFunction extends IncrSumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 	}
 
@@ -158,16 +156,16 @@ public abstract class IncrSumAggFunction extends DeclarativeAggregateFunction {
 	 * Built-in Decimal IncrSum aggregate function.
 	 */
 	public static class DecimalIncrSumAggFunction extends IncrSumAggFunction {
-		private DecimalTypeInfo decimalType;
+		private DecimalType decimalType;
 
-		public DecimalIncrSumAggFunction(DecimalTypeInfo decimalType) {
+		public DecimalIncrSumAggFunction(DecimalType decimalType) {
 			this.decimalType = decimalType;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			DecimalType sumType = DecimalType.inferAggSumType(decimalType.scale());
-			return new DecimalTypeInfo(sumType.precision(), sumType.scale());
+		public DataType getResultType() {
+			DecimalType sumType = FlinkTypeSystem.inferAggSumType(decimalType.getScale());
+			return DataTypes.DECIMAL(sumType.getPrecision(), sumType.getScale());
 		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/IncrSumWithRetractAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/IncrSumWithRetractAggFunction.java
index deb8e28..ae385ca 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/IncrSumWithRetractAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/IncrSumWithRetractAggFunction.java
@@ -18,15 +18,12 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.calcite.FlinkTypeSystem;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.equalTo;
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
@@ -57,10 +54,10 @@ public abstract class IncrSumWithRetractAggFunction extends DeclarativeAggregate
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] {
-				TypeConverters.createInternalTypeFromTypeInfo(getResultType()),
-				InternalTypes.LONG };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] {
+				getResultType(),
+				DataTypes.BIGINT() };
 	}
 
 	@Override
@@ -118,8 +115,8 @@ public abstract class IncrSumWithRetractAggFunction extends DeclarativeAggregate
 	public static class IntIncrSumWithRetractAggFunction extends IncrSumWithRetractAggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 
 		@Override
@@ -133,8 +130,8 @@ public abstract class IncrSumWithRetractAggFunction extends DeclarativeAggregate
 	 */
 	public static class ByteIncrSumWithRetractAggFunction extends IncrSumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 
 		@Override
@@ -148,8 +145,8 @@ public abstract class IncrSumWithRetractAggFunction extends DeclarativeAggregate
 	 */
 	public static class ShortIncrSumWithRetractAggFunction extends IncrSumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 
 		@Override
@@ -163,8 +160,8 @@ public abstract class IncrSumWithRetractAggFunction extends DeclarativeAggregate
 	 */
 	public static class LongIncrSumWithRetractAggFunction extends IncrSumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 
 		@Override
@@ -178,8 +175,8 @@ public abstract class IncrSumWithRetractAggFunction extends DeclarativeAggregate
 	 */
 	public static class FloatIncrSumWithRetractAggFunction extends IncrSumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 
 		@Override
@@ -193,8 +190,8 @@ public abstract class IncrSumWithRetractAggFunction extends DeclarativeAggregate
 	 */
 	public static class DoubleIncrSumWithRetractAggFunction extends IncrSumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 
 		@Override
@@ -207,16 +204,16 @@ public abstract class IncrSumWithRetractAggFunction extends DeclarativeAggregate
 	 * Built-in Decimal IncrSum with retract aggregate function.
 	 */
 	public static class DecimalIncrSumWithRetractAggFunction extends IncrSumWithRetractAggFunction {
-		private DecimalTypeInfo decimalType;
+		private DecimalType decimalType;
 
-		public DecimalIncrSumWithRetractAggFunction(DecimalTypeInfo decimalType) {
+		public DecimalIncrSumWithRetractAggFunction(DecimalType decimalType) {
 			this.decimalType = decimalType;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			DecimalType sumType = DecimalType.inferAggSumType(decimalType.scale());
-			return new DecimalTypeInfo(sumType.precision(), sumType.scale());
+		public DataType getResultType() {
+			DecimalType sumType = FlinkTypeSystem.inferAggSumType(decimalType.getScale());
+			return DataTypes.DECIMAL(sumType.getPrecision(), sumType.getScale());
 		}
 
 		@Override
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LastValueAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LastValueAggFunction.java
index 844d32a..78aec59 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LastValueAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LastValueAggFunction.java
@@ -24,13 +24,14 @@ import org.apache.flink.table.dataformat.BinaryString;
 import org.apache.flink.table.dataformat.Decimal;
 import org.apache.flink.table.dataformat.GenericRow;
 import org.apache.flink.table.functions.AggregateFunction;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.type.TypeConverters;
+import org.apache.flink.table.types.logical.BigIntType;
+import org.apache.flink.table.types.logical.LogicalType;
 import org.apache.flink.table.typeutils.BaseRowTypeInfo;
 import org.apache.flink.table.typeutils.BinaryStringTypeInfo;
 import org.apache.flink.table.typeutils.DecimalTypeInfo;
 
+import static org.apache.flink.table.types.TypeInfoLogicalTypeConverter.fromTypeInfoToLogicalType;
+
 /**
  * built-in LastValue aggregate function.
  */
@@ -77,9 +78,9 @@ public class LastValueAggFunction<T> extends AggregateFunction<T, GenericRow> {
 
 	@Override
 	public TypeInformation<GenericRow> getAccumulatorType() {
-		InternalType[] fieldTypes = new InternalType[] {
-				TypeConverters.createInternalTypeFromTypeInfo(getResultType()),
-				InternalTypes.LONG
+		LogicalType[] fieldTypes = new LogicalType[] {
+				fromTypeInfoToLogicalType(getResultType()),
+				new BigIntType()
 		};
 
 		String[] fieldNames = new String[] {
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LastValueWithRetractAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LastValueWithRetractAggFunction.java
index 50a43d2..d07acfb 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LastValueWithRetractAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LastValueWithRetractAggFunction.java
@@ -37,10 +37,9 @@ import org.apache.flink.table.dataformat.BinaryString;
 import org.apache.flink.table.dataformat.Decimal;
 import org.apache.flink.table.dataformat.GenericRow;
 import org.apache.flink.table.functions.AggregateFunction;
-import org.apache.flink.table.type.GenericType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.type.TypeConverters;
+import org.apache.flink.table.types.logical.BigIntType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.TypeInformationAnyType;
 import org.apache.flink.table.typeutils.BaseRowTypeInfo;
 import org.apache.flink.table.typeutils.BinaryStringSerializer;
 import org.apache.flink.table.typeutils.BinaryStringTypeInfo;
@@ -53,6 +52,8 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import static org.apache.flink.table.types.TypeInfoLogicalTypeConverter.fromTypeInfoToLogicalType;
+
 /**
  * built-in LastValue with retraction aggregate function.
  */
@@ -186,11 +187,11 @@ public abstract class LastValueWithRetractAggFunction<T> extends AggregateFuncti
 
 	@Override
 	public TypeInformation<GenericRow> getAccumulatorType() {
-		InternalType[] fieldTypes = new InternalType[] {
-				TypeConverters.createInternalTypeFromTypeInfo(getResultType()),
-				InternalTypes.LONG,
-				new GenericType<>(new MapViewTypeInfo<>(getResultType(), new ListTypeInfo<>(Types.LONG), false, false)),
-				new GenericType<>(new MapViewTypeInfo<>(Types.LONG, new ListTypeInfo<>(getResultType()), false, false))
+		LogicalType[] fieldTypes = new LogicalType[] {
+				fromTypeInfoToLogicalType(getResultType()),
+				new BigIntType(),
+				new TypeInformationAnyType<>(new MapViewTypeInfo<>(getResultType(), new ListTypeInfo<>(Types.LONG), false, false)),
+				new TypeInformationAnyType<>(new MapViewTypeInfo<>(Types.LONG, new ListTypeInfo<>(getResultType()), false, false))
 		};
 
 		String[] fieldNames = new String[] {
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LeadLagAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LeadLagAggFunction.java
index 651a8cb..6e64728 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LeadLagAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/LeadLagAggFunction.java
@@ -18,15 +18,13 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
 import org.apache.flink.table.runtime.over.frame.OffsetOverFrame;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.BigDecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
+import org.apache.flink.table.types.logical.TimeType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.cast;
 import static org.apache.flink.table.expressions.ExpressionBuilder.literal;
@@ -76,8 +74,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] {TypeConverters.createInternalTypeFromTypeInfo(getResultType())};
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] {getResultType()};
 	}
 
 	@Override
@@ -117,8 +115,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 	}
 
@@ -132,8 +130,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 	}
 
@@ -147,8 +145,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 	}
 
@@ -162,8 +160,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 	}
 
@@ -177,8 +175,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 	}
 
@@ -192,8 +190,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 	}
 
@@ -207,8 +205,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BOOLEAN;
+		public DataType getResultType() {
+			return DataTypes.BOOLEAN();
 		}
 	}
 
@@ -225,8 +223,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return BigDecimalTypeInfo.of(decimalType.precision(), decimalType.scale());
+		public DataType getResultType() {
+			return DataTypes.DECIMAL(decimalType.getPrecision(), decimalType.getScale());
 		}
 	}
 
@@ -240,8 +238,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.STRING;
+		public DataType getResultType() {
+			return DataTypes.STRING();
 		}
 	}
 
@@ -255,8 +253,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_DATE;
+		public DataType getResultType() {
+			return DataTypes.DATE();
 		}
 	}
 
@@ -270,8 +268,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_TIME;
+		public DataType getResultType() {
+			return DataTypes.TIME(TimeType.DEFAULT_PRECISION);
 		}
 	}
 
@@ -285,8 +283,8 @@ public abstract class LeadLagAggFunction extends DeclarativeAggregateFunction {
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_TIMESTAMP;
+		public DataType getResultType() {
+			return DataTypes.TIMESTAMP(3);
 		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/MaxAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/MaxAggFunction.java
index 895728c..873d700 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/MaxAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/MaxAggFunction.java
@@ -18,13 +18,12 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
+import org.apache.flink.table.types.logical.TimeType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.greaterThan;
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
@@ -48,8 +47,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { TypeConverters.createInternalTypeFromTypeInfo(getResultType()) };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { getResultType() };
 	}
 
 	@Override
@@ -97,8 +96,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	public static class IntMaxAggFunction extends MaxAggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 	}
 
@@ -107,8 +106,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ByteMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 	}
 
@@ -117,8 +116,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ShortMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 	}
 
@@ -127,8 +126,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class LongMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 	}
 
@@ -137,8 +136,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class FloatMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 	}
 
@@ -147,8 +146,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class DoubleMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 	}
 
@@ -156,15 +155,15 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 * Built-in Decimal Max aggregate function.
 	 */
 	public static class DecimalMaxAggFunction extends MaxAggFunction {
-		private DecimalTypeInfo decimalType;
+		private DecimalType decimalType;
 
-		public DecimalMaxAggFunction(DecimalTypeInfo decimalType) {
+		public DecimalMaxAggFunction(DecimalType decimalType) {
 			this.decimalType = decimalType;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return decimalType;
+		public DataType getResultType() {
+			return DataTypes.DECIMAL(decimalType.getPrecision(), decimalType.getScale());
 		}
 	}
 
@@ -173,8 +172,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class BooleanMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BOOLEAN;
+		public DataType getResultType() {
+			return DataTypes.BOOLEAN();
 		}
 	}
 
@@ -183,8 +182,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class StringMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.STRING;
+		public DataType getResultType() {
+			return DataTypes.STRING();
 		}
 	}
 
@@ -193,8 +192,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class DateMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_DATE;
+		public DataType getResultType() {
+			return DataTypes.DATE();
 		}
 	}
 
@@ -203,8 +202,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class TimeMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_TIME;
+		public DataType getResultType() {
+			return DataTypes.TIME(TimeType.DEFAULT_PRECISION);
 		}
 	}
 
@@ -213,8 +212,8 @@ public abstract class MaxAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class TimestampMaxAggFunction extends MaxAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_TIMESTAMP;
+		public DataType getResultType() {
+			return DataTypes.TIMESTAMP(3);
 		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/MinAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/MinAggFunction.java
index 31af7e1..8f5651c 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/MinAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/MinAggFunction.java
@@ -18,13 +18,12 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
+import org.apache.flink.table.types.logical.TimeType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
 import static org.apache.flink.table.expressions.ExpressionBuilder.isNull;
@@ -48,8 +47,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { TypeConverters.createInternalTypeFromTypeInfo(getResultType()) };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { getResultType() };
 	}
 
 	@Override
@@ -97,8 +96,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	public static class IntMinAggFunction extends MinAggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 	}
 
@@ -107,8 +106,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ByteMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 	}
 
@@ -117,8 +116,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ShortMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 	}
 
@@ -127,8 +126,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class LongMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 	}
 
@@ -137,8 +136,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class FloatMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 	}
 
@@ -147,8 +146,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class DoubleMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 	}
 
@@ -156,15 +155,15 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 * Built-in Decimal Min aggregate function.
 	 */
 	public static class DecimalMinAggFunction extends MinAggFunction {
-		private DecimalTypeInfo decimalType;
+		private DecimalType decimalType;
 
-		public DecimalMinAggFunction(DecimalTypeInfo decimalType) {
+		public DecimalMinAggFunction(DecimalType decimalType) {
 			this.decimalType = decimalType;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return decimalType;
+		public DataType getResultType() {
+			return DataTypes.DECIMAL(decimalType.getPrecision(), decimalType.getScale());
 		}
 	}
 
@@ -173,8 +172,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class BooleanMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BOOLEAN;
+		public DataType getResultType() {
+			return DataTypes.BOOLEAN();
 		}
 	}
 
@@ -183,8 +182,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class StringMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.STRING;
+		public DataType getResultType() {
+			return DataTypes.STRING();
 		}
 	}
 
@@ -193,8 +192,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class DateMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_DATE;
+		public DataType getResultType() {
+			return DataTypes.DATE();
 		}
 	}
 
@@ -203,8 +202,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class TimeMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_TIME;
+		public DataType getResultType() {
+			return DataTypes.TIME(TimeType.DEFAULT_PRECISION);
 		}
 	}
 
@@ -213,8 +212,8 @@ public abstract class MinAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class TimestampMinAggFunction extends MinAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_TIMESTAMP;
+		public DataType getResultType() {
+			return DataTypes.TIMESTAMP(3);
 		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RankAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RankAggFunction.java
index 218e1f0..d8fb91f 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RankAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RankAggFunction.java
@@ -18,10 +18,14 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.utils.LogicalTypeDataTypeConverter;
+
+import java.util.Arrays;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.and;
 import static org.apache.flink.table.expressions.ExpressionBuilder.equalTo;
@@ -37,7 +41,7 @@ public class RankAggFunction extends RankLikeAggFunctionBase {
 
 	private UnresolvedReferenceExpression currNumber = new UnresolvedReferenceExpression("currNumber");
 
-	public RankAggFunction(InternalType[] orderKeyTypes) {
+	public RankAggFunction(LogicalType[] orderKeyTypes) {
 		super(orderKeyTypes);
 	}
 
@@ -51,11 +55,13 @@ public class RankAggFunction extends RankLikeAggFunctionBase {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		InternalType[] aggBufferTypes = new InternalType[2 + orderKeyTypes.length];
-		aggBufferTypes[0] = InternalTypes.LONG;
-		aggBufferTypes[1] = InternalTypes.LONG;
-		System.arraycopy(orderKeyTypes, 0, aggBufferTypes, 2, orderKeyTypes.length);
+	public DataType[] getAggBufferTypes() {
+		DataType[] aggBufferTypes = new DataType[2 + orderKeyTypes.length];
+		aggBufferTypes[0] = DataTypes.BIGINT();
+		aggBufferTypes[1] = DataTypes.BIGINT();
+		System.arraycopy(Arrays.stream(orderKeyTypes)
+				.map(LogicalTypeDataTypeConverter::toDataType).toArray(DataType[]::new), 0,
+				aggBufferTypes, 2, orderKeyTypes.length);
 		return aggBufferTypes;
 	}
 
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RankLikeAggFunctionBase.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RankLikeAggFunctionBase.java
index f50f491..3ab8e49 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RankLikeAggFunctionBase.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RankLikeAggFunctionBase.java
@@ -18,15 +18,13 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.api.TableException;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.ExpressionBuilder;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.LogicalType;
 
 import java.sql.Date;
 import java.sql.Time;
@@ -45,9 +43,9 @@ import static org.apache.flink.table.expressions.ExpressionBuilder.literal;
 public abstract class RankLikeAggFunctionBase extends DeclarativeAggregateFunction {
 	protected UnresolvedReferenceExpression sequence = new UnresolvedReferenceExpression("sequence");
 	protected UnresolvedReferenceExpression[] lastValues;
-	protected InternalType[] orderKeyTypes;
+	protected LogicalType[] orderKeyTypes;
 
-	public RankLikeAggFunctionBase(InternalType[] orderKeyTypes) {
+	public RankLikeAggFunctionBase(LogicalType[] orderKeyTypes) {
 		this.orderKeyTypes = orderKeyTypes;
 		lastValues = new UnresolvedReferenceExpression[orderKeyTypes.length];
 		for (int i = 0; i < orderKeyTypes.length; ++i) {
@@ -61,8 +59,8 @@ public abstract class RankLikeAggFunctionBase extends DeclarativeAggregateFuncti
 	}
 
 	@Override
-	public TypeInformation getResultType() {
-		return Types.LONG;
+	public DataType getResultType() {
+		return DataTypes.BIGINT();
 	}
 
 	@Override
@@ -98,33 +96,34 @@ public abstract class RankLikeAggFunctionBase extends DeclarativeAggregateFuncti
 		return ret.orElseGet(() -> literal(true));
 	}
 
-	protected Expression generateInitLiteral(InternalType orderType) {
-		if (orderType.equals(InternalTypes.BOOLEAN)) {
-			return literal(false);
-		} else if (orderType.equals(InternalTypes.BYTE)) {
-			return literal((byte) 0);
-		} else if (orderType.equals(InternalTypes.SHORT)) {
-			return literal((short) 0);
-		} else if (orderType.equals(InternalTypes.INT)) {
-			return literal(0);
-		} else if (orderType.equals(InternalTypes.LONG)) {
-			return literal(0L);
-		} else if (orderType.equals(InternalTypes.FLOAT)) {
-			return literal(0.0f);
-		} else if (orderType.equals(InternalTypes.DOUBLE)) {
-			return literal(0.0d);
-		} else if (orderType instanceof DecimalType) {
-			return literal(java.math.BigDecimal.ZERO);
-		} else if (orderType.equals(InternalTypes.STRING)) {
-			return literal("");
-		} else if (orderType.equals(InternalTypes.DATE)) {
-			return literal(new Date(0));
-		} else if (orderType.equals(InternalTypes.TIME)) {
-			return literal(new Time(0));
-		} else if (orderType.equals(InternalTypes.TIMESTAMP)) {
-			return literal(new Timestamp(0));
-		} else {
-			throw new TableException("Unsupported type: " + orderType);
+	protected Expression generateInitLiteral(LogicalType orderType) {
+		switch (orderType.getTypeRoot()) {
+			case BOOLEAN:
+				return literal(false);
+			case TINYINT:
+				return literal((byte) 0);
+			case SMALLINT:
+				return literal((short) 0);
+			case INTEGER:
+				return literal(0);
+			case BIGINT:
+				return literal(0L);
+			case FLOAT:
+				return literal(0.0f);
+			case DOUBLE:
+				return literal(0.0d);
+			case DECIMAL:
+				return literal(java.math.BigDecimal.ZERO);
+			case VARCHAR:
+				return literal("");
+			case DATE:
+				return literal(new Date(0));
+			case TIME_WITHOUT_TIME_ZONE:
+				return literal(new Time(0));
+			case TIMESTAMP_WITHOUT_TIME_ZONE:
+				return literal(new Timestamp(0));
+			default:
+				throw new TableException("Unsupported type: " + orderType);
 		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RowNumberAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RowNumberAggFunction.java
index 26a1d28..780fbe3 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RowNumberAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/RowNumberAggFunction.java
@@ -18,13 +18,11 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.api.TableException;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
+import org.apache.flink.table.types.DataType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.literal;
 import static org.apache.flink.table.expressions.ExpressionBuilder.plus;
@@ -46,13 +44,13 @@ public class RowNumberAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { InternalTypes.LONG };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { DataTypes.BIGINT() };
 	}
 
 	@Override
-	public TypeInformation getResultType() {
-		return Types.LONG;
+	public DataType getResultType() {
+		return DataTypes.BIGINT();
 	}
 
 	@Override
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SingleValueAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SingleValueAggFunction.java
index 8b95084..a1188bb 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SingleValueAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SingleValueAggFunction.java
@@ -18,15 +18,12 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.BinaryStringTypeInfo;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
+import org.apache.flink.table.types.logical.TimeType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.equalTo;
 import static org.apache.flink.table.expressions.ExpressionBuilder.greaterThan;
@@ -44,8 +41,8 @@ import static org.apache.flink.table.expressions.ExpressionBuilder.throwExceptio
 public abstract class SingleValueAggFunction extends DeclarativeAggregateFunction {
 
 	private static final long serialVersionUID = 8850662568341069949L;
-	private static final Expression ZERO = literal(0, Types.INT);
-	private static final Expression ONE = literal(1, Types.INT);
+	private static final Expression ZERO = literal(0, DataTypes.INT());
+	private static final Expression ONE = literal(1, DataTypes.INT());
 	private static final String ERROR_MSG = "SingleValueAggFunction received more than one element.";
 	private UnresolvedReferenceExpression value = new UnresolvedReferenceExpression("value");
 	private UnresolvedReferenceExpression count = new UnresolvedReferenceExpression("count");
@@ -61,10 +58,10 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[]{
-			TypeConverters.createInternalTypeFromTypeInfo(getResultType()),
-			InternalTypes.INT};
+	public DataType[] getAggBufferTypes() {
+		return new DataType[]{
+			getResultType(),
+			DataTypes.INT()};
 	}
 
 	@Override
@@ -128,8 +125,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 	}
 
@@ -141,8 +138,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 	}
 
@@ -154,8 +151,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 	}
 
@@ -167,8 +164,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 	}
 
@@ -180,8 +177,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 	}
 
@@ -193,8 +190,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 	}
 
@@ -206,8 +203,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BOOLEAN;
+		public DataType getResultType() {
+			return DataTypes.BOOLEAN();
 		}
 	}
 
@@ -218,15 +215,15 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 
 		private static final long serialVersionUID = 320495723666949978L;
 
-		private final DecimalTypeInfo type;
+		private final DecimalType type;
 
-		public DecimalSingleValueAggFunction(DecimalTypeInfo type) {
+		public DecimalSingleValueAggFunction(DecimalType type) {
 			this.type = type;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			return type;
+		public DataType getResultType() {
+			return DataTypes.DECIMAL(type.getPrecision(), type.getScale());
 		}
 	}
 
@@ -238,8 +235,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return BinaryStringTypeInfo.INSTANCE;
+		public DataType getResultType() {
+			return DataTypes.STRING();
 		}
 	}
 
@@ -251,8 +248,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_DATE;
+		public DataType getResultType() {
+			return DataTypes.DATE();
 		}
 	}
 
@@ -264,8 +261,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_TIME;
+		public DataType getResultType() {
+			return DataTypes.TIME(TimeType.DEFAULT_PRECISION);
 		}
 	}
 
@@ -277,8 +274,8 @@ public abstract class SingleValueAggFunction extends DeclarativeAggregateFunctio
 		private static final long serialVersionUID = 320495723666949978L;
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SQL_TIMESTAMP;
+		public DataType getResultType() {
+			return DataTypes.TIMESTAMP(3);
 		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/Sum0AggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/Sum0AggFunction.java
index 95905bf..e65e42b 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/Sum0AggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/Sum0AggFunction.java
@@ -18,14 +18,12 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.calcite.FlinkTypeSystem;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
 
 import java.math.BigDecimal;
 
@@ -52,8 +50,8 @@ public abstract class Sum0AggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { TypeConverters.createInternalTypeFromTypeInfo(getResultType()) };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { getResultType() };
 	}
 
 	@Override
@@ -88,8 +86,8 @@ public abstract class Sum0AggFunction extends DeclarativeAggregateFunction {
 	public static class IntSum0AggFunction extends Sum0AggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 
 		@Override
@@ -105,8 +103,8 @@ public abstract class Sum0AggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ByteSum0AggFunction extends Sum0AggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 
 		@Override
@@ -122,8 +120,8 @@ public abstract class Sum0AggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ShortSum0AggFunction extends Sum0AggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 
 		@Override
@@ -139,8 +137,8 @@ public abstract class Sum0AggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class LongSum0AggFunction extends Sum0AggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 
 		@Override
@@ -156,8 +154,8 @@ public abstract class Sum0AggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class FloatSum0AggFunction extends Sum0AggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 
 		@Override
@@ -173,8 +171,8 @@ public abstract class Sum0AggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class DoubleSum0AggFunction extends Sum0AggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 
 		@Override
@@ -189,16 +187,16 @@ public abstract class Sum0AggFunction extends DeclarativeAggregateFunction {
 	 * Built-in Decimal Sum0 aggregate function.
 	 */
 	public static class DecimalSum0AggFunction extends Sum0AggFunction {
-		private DecimalTypeInfo decimalType;
+		private DecimalType decimalType;
 
-		public DecimalSum0AggFunction(DecimalTypeInfo decimalType) {
+		public DecimalSum0AggFunction(DecimalType decimalType) {
 			this.decimalType = decimalType;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			DecimalType sumType = DecimalType.inferAggSumType(decimalType.scale());
-			return new DecimalTypeInfo(sumType.precision(), sumType.scale());
+		public DataType getResultType() {
+			DecimalType sumType = FlinkTypeSystem.inferAggSumType(decimalType.getScale());
+			return DataTypes.DECIMAL(sumType.getPrecision(), sumType.getScale());
 		}
 
 		@Override
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SumAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SumAggFunction.java
index 48a7c66..b76318d 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SumAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SumAggFunction.java
@@ -18,15 +18,13 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.api.TableException;
+import org.apache.flink.table.calcite.FlinkTypeSystem;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
 import static org.apache.flink.table.expressions.ExpressionBuilder.isNull;
@@ -50,8 +48,8 @@ public abstract class SumAggFunction extends DeclarativeAggregateFunction {
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] { TypeConverters.createInternalTypeFromTypeInfo(getResultType()) };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] { getResultType() };
 	}
 
 	@Override
@@ -95,8 +93,8 @@ public abstract class SumAggFunction extends DeclarativeAggregateFunction {
 	public static class IntSumAggFunction extends SumAggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 	}
 
@@ -105,8 +103,8 @@ public abstract class SumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ByteSumAggFunction extends SumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 	}
 
@@ -115,8 +113,8 @@ public abstract class SumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class ShortSumAggFunction extends SumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 	}
 
@@ -125,8 +123,8 @@ public abstract class SumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class LongSumAggFunction extends SumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 	}
 
@@ -135,8 +133,8 @@ public abstract class SumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class FloatSumAggFunction extends SumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 	}
 
@@ -145,8 +143,8 @@ public abstract class SumAggFunction extends DeclarativeAggregateFunction {
 	 */
 	public static class DoubleSumAggFunction extends SumAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 	}
 
@@ -154,16 +152,16 @@ public abstract class SumAggFunction extends DeclarativeAggregateFunction {
 	 * Built-in Decimal Sum aggregate function.
 	 */
 	public static class DecimalSumAggFunction extends SumAggFunction {
-		private DecimalTypeInfo decimalType;
+		private DecimalType decimalType;
 
-		public DecimalSumAggFunction(DecimalTypeInfo decimalType) {
+		public DecimalSumAggFunction(DecimalType decimalType) {
 			this.decimalType = decimalType;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			DecimalType sumType = DecimalType.inferAggSumType(decimalType.scale());
-			return new DecimalTypeInfo(sumType.precision(), sumType.scale());
+		public DataType getResultType() {
+			DecimalType sumType = FlinkTypeSystem.inferAggSumType(decimalType.getScale());
+			return DataTypes.DECIMAL(sumType.getPrecision(), sumType.getScale());
 		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SumWithRetractAggFunction.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SumWithRetractAggFunction.java
index ae904b0..a3de544 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SumWithRetractAggFunction.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/functions/aggfunctions/SumWithRetractAggFunction.java
@@ -18,15 +18,12 @@
 
 package org.apache.flink.table.functions.aggfunctions;
 
-import org.apache.flink.api.common.typeinfo.TypeInformation;
-import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.calcite.FlinkTypeSystem;
 import org.apache.flink.table.expressions.Expression;
 import org.apache.flink.table.expressions.UnresolvedReferenceExpression;
-import org.apache.flink.table.type.DecimalType;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.InternalTypes;
-import org.apache.flink.table.type.TypeConverters;
-import org.apache.flink.table.typeutils.DecimalTypeInfo;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.DecimalType;
 
 import static org.apache.flink.table.expressions.ExpressionBuilder.equalTo;
 import static org.apache.flink.table.expressions.ExpressionBuilder.ifThenElse;
@@ -54,10 +51,10 @@ public abstract class SumWithRetractAggFunction extends DeclarativeAggregateFunc
 	}
 
 	@Override
-	public InternalType[] getAggBufferTypes() {
-		return new InternalType[] {
-				TypeConverters.createInternalTypeFromTypeInfo(getResultType()),
-				InternalTypes.LONG };
+	public DataType[] getAggBufferTypes() {
+		return new DataType[] {
+				getResultType(),
+				DataTypes.BIGINT() };
 	}
 
 	@Override
@@ -114,8 +111,8 @@ public abstract class SumWithRetractAggFunction extends DeclarativeAggregateFunc
 	public static class IntSumWithRetractAggFunction extends SumWithRetractAggFunction {
 
 		@Override
-		public TypeInformation getResultType() {
-			return Types.INT;
+		public DataType getResultType() {
+			return DataTypes.INT();
 		}
 
 		@Override
@@ -129,8 +126,8 @@ public abstract class SumWithRetractAggFunction extends DeclarativeAggregateFunc
 	 */
 	public static class ByteSumWithRetractAggFunction extends SumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.BYTE;
+		public DataType getResultType() {
+			return DataTypes.TINYINT();
 		}
 
 		@Override
@@ -144,8 +141,8 @@ public abstract class SumWithRetractAggFunction extends DeclarativeAggregateFunc
 	 */
 	public static class ShortSumWithRetractAggFunction extends SumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.SHORT;
+		public DataType getResultType() {
+			return DataTypes.SMALLINT();
 		}
 
 		@Override
@@ -159,8 +156,8 @@ public abstract class SumWithRetractAggFunction extends DeclarativeAggregateFunc
 	 */
 	public static class LongSumWithRetractAggFunction extends SumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.LONG;
+		public DataType getResultType() {
+			return DataTypes.BIGINT();
 		}
 
 		@Override
@@ -174,8 +171,8 @@ public abstract class SumWithRetractAggFunction extends DeclarativeAggregateFunc
 	 */
 	public static class FloatSumWithRetractAggFunction extends SumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.FLOAT;
+		public DataType getResultType() {
+			return DataTypes.FLOAT();
 		}
 
 		@Override
@@ -189,8 +186,8 @@ public abstract class SumWithRetractAggFunction extends DeclarativeAggregateFunc
 	 */
 	public static class DoubleSumWithRetractAggFunction extends SumWithRetractAggFunction {
 		@Override
-		public TypeInformation getResultType() {
-			return Types.DOUBLE;
+		public DataType getResultType() {
+			return DataTypes.DOUBLE();
 		}
 
 		@Override
@@ -203,16 +200,16 @@ public abstract class SumWithRetractAggFunction extends DeclarativeAggregateFunc
 	 * Built-in Decimal Sum with retract aggregate function.
 	 */
 	public static class DecimalSumWithRetractAggFunction extends SumWithRetractAggFunction {
-		private DecimalTypeInfo decimalType;
+		private DecimalType decimalType;
 
-		public DecimalSumWithRetractAggFunction(DecimalTypeInfo decimalType) {
+		public DecimalSumWithRetractAggFunction(DecimalType decimalType) {
 			this.decimalType = decimalType;
 		}
 
 		@Override
-		public TypeInformation getResultType() {
-			DecimalType sumType = DecimalType.inferAggSumType(decimalType.scale());
-			return new DecimalTypeInfo(sumType.precision(), sumType.scale());
+		public DataType getResultType() {
+			DecimalType sumType = FlinkTypeSystem.inferAggSumType(decimalType.getScale());
+			return DataTypes.DECIMAL(sumType.getPrecision(), sumType.getScale());
 		}
 
 		@Override
diff --git a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/plan/util/KeySelectorUtil.java b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/plan/util/KeySelectorUtil.java
index c3e6933..992861a 100644
--- a/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/plan/util/KeySelectorUtil.java
+++ b/flink-table/flink-table-planner-blink/src/main/java/org/apache/flink/table/plan/util/KeySelectorUtil.java
@@ -25,10 +25,9 @@ import org.apache.flink.table.generated.GeneratedProjection;
 import org.apache.flink.table.runtime.keyselector.BaseRowKeySelector;
 import org.apache.flink.table.runtime.keyselector.BinaryRowKeySelector;
 import org.apache.flink.table.runtime.keyselector.NullBinaryRowKeySelector;
-import org.apache.flink.table.type.InternalType;
-import org.apache.flink.table.type.RowType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.RowType;
 import org.apache.flink.table.typeutils.BaseRowTypeInfo;
-import org.apache.flink.table.typeutils.TypeCheckUtils;
 
 /**
  * Utility for KeySelector.
@@ -44,24 +43,22 @@ public class KeySelectorUtil {
 	 */
 	public static BaseRowKeySelector getBaseRowSelector(int[] keyFields, BaseRowTypeInfo rowType) {
 		if (keyFields.length > 0) {
-			InternalType[] inputFieldTypes = rowType.getInternalTypes();
+			LogicalType[] inputFieldTypes = rowType.getLogicalTypes();
 			String[] inputFieldNames = rowType.getFieldNames();
-			InternalType[] keyFieldTypes = new InternalType[keyFields.length];
+			LogicalType[] keyFieldTypes = new LogicalType[keyFields.length];
 			String[] keyFieldNames = new String[keyFields.length];
 			for (int i = 0; i < keyFields.length; ++i) {
 				keyFieldTypes[i] = inputFieldTypes[keyFields[i]];
 				keyFieldNames[i] = inputFieldNames[keyFields[i]];
 			}
-			RowType returnType = new RowType(keyFieldTypes, keyFieldNames);
-			RowType inputType = new RowType(inputFieldTypes, rowType.getFieldNames());
+			RowType returnType = RowType.of(keyFieldTypes, keyFieldNames);
+			RowType inputType = RowType.of(inputFieldTypes, rowType.getFieldNames());
 			GeneratedProjection generatedProjection = ProjectionCodeGenerator.generateProjection(
 				CodeGeneratorContext.apply(new TableConfig()),
 				"KeyProjection",
 				inputType,
 				returnType, keyFields);
-			BaseRowTypeInfo keyRowType = returnType.toTypeInfo();
-			// check if type implements proper equals/hashCode
-			TypeCheckUtils.validateEqualsHashCode("grouping", keyRowType);
+			BaseRowTypeInfo keyRowType = BaseRowTypeInfo.of(returnType);
 			return new BinaryRowKeySelector(keyRowType, generatedProjection);
 		} else {
 			return NullBinaryRowKeySelector.INSTANCE;
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/StreamTableEnvironment.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/StreamTableEnvironment.scala
index 87f40af..8269613 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/StreamTableEnvironment.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/StreamTableEnvironment.scala
@@ -20,7 +20,6 @@ package org.apache.flink.table.api
 
 import org.apache.flink.api.common.JobExecutionResult
 import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.common.typeutils.CompositeType
 import org.apache.flink.configuration.Configuration
 import org.apache.flink.runtime.state.filesystem.FsStateBackend
 import org.apache.flink.runtime.state.memory.MemoryStateBackend
@@ -29,7 +28,6 @@ import org.apache.flink.streaming.api.datastream.DataStream
 import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment
 import org.apache.flink.streaming.api.graph.{StreamGraph, StreamGraphGenerator}
 import org.apache.flink.streaming.api.transformations.StreamTransformation
-import org.apache.flink.table.`type`.TypeConverters
 import org.apache.flink.table.dataformat.BaseRow
 import org.apache.flink.table.plan.`trait`.{AccModeTraitDef, FlinkRelDistributionTraitDef, MiniBatchIntervalTraitDef, UpdateAsRetractionTraitDef}
 import org.apache.flink.table.plan.nodes.calcite.LogicalSink
@@ -40,6 +38,9 @@ import org.apache.flink.table.plan.stats.FlinkStatistic
 import org.apache.flink.table.plan.util.{ExecNodePlanDumper, FlinkRelOptUtil}
 import org.apache.flink.table.sinks.DataStreamTableSink
 import org.apache.flink.table.sources.{StreamTableSource, TableSource}
+import org.apache.flink.table.types.{DataType, LogicalTypeDataTypeConverter}
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
+import org.apache.flink.table.types.utils.TypeConversions.fromLegacyInfoToDataType
 import org.apache.flink.table.typeutils.{TimeIndicatorTypeInfo, TypeCheckUtils}
 import org.apache.flink.table.util.PlanUtil
 
@@ -305,7 +306,7 @@ abstract class StreamTableEnvironment(
     name: String,
     dataStream: DataStream[T]): Unit = {
 
-    val (fieldNames, fieldIndexes) = getFieldInfo[T](dataStream.getType)
+    val (fieldNames, fieldIndexes) = getFieldInfo[T](fromLegacyInfoToDataType(dataStream.getType))
     val dataStreamTable = new DataStreamTable[T](
       dataStream,
       fieldIndexes,
@@ -329,11 +330,13 @@ abstract class StreamTableEnvironment(
       fields: Array[String]): Unit = {
 
     // get field names and types for all non-replaced fields
-    val (fieldNames, fieldIndexes) = getFieldInfo(dataStream.getType, fields)
+    val (fieldNames, fieldIndexes) = getFieldInfo(
+      fromLegacyInfoToDataType(dataStream.getType), fields)
 
     // TODO: validate and extract time attributes after we introduce [Expression],
     //  return None currently
-    val (rowtime, proctime) = validateAndExtractTimeAttributes(dataStream.getType, fields)
+    val (rowtime, proctime) = validateAndExtractTimeAttributes(
+      fromLegacyInfoToDataType(dataStream.getType), fields)
 
     // check if event-time is enabled
     if (rowtime.isDefined && execEnv.getStreamTimeCharacteristic != TimeCharacteristic.EventTime) {
@@ -362,14 +365,17 @@ abstract class StreamTableEnvironment(
     */
   // TODO: we should support Expression fields after we introduce [Expression]
   private[flink] def validateAndExtractTimeAttributes(
-      streamType: TypeInformation[_],
+      streamType: DataType,
       fields: Array[String]): (Option[(Int, String)], Option[(Int, String)]) = {
 
-    val (isRefByPos, fieldTypes) = streamType match {
-      case c: CompositeType[_] =>
+    val streamLogicalType = LogicalTypeDataTypeConverter.fromDataTypeToLogicalType(streamType)
+
+    val (isRefByPos, fieldTypes) = streamLogicalType match {
+      case c: RowType =>
         // determine schema definition mode (by position or by name)
-        (isReferenceByPosition(c, fields), (0 until c.getArity).map(i => c.getTypeAt(i)).toArray)
-      case t: TypeInformation[_] =>
+        (isReferenceByPosition(c, fields),
+            (0 until c.getFieldCount).map(i => c.getTypeAt(i)).toArray)
+      case t =>
         (false, Array(t))
     }
 
@@ -377,12 +383,11 @@ abstract class StreamTableEnvironment(
     var rowtime: Option[(Int, String)] = None
     var proctime: Option[(Int, String)] = None
 
-    def checkRowtimeType(typeInfo: TypeInformation[_]): Unit = {
-      val t = TypeConverters.createInternalTypeFromTypeInfo(typeInfo)
+    def checkRowtimeType(t: LogicalType): Unit = {
       if (!(TypeCheckUtils.isLong(t) || TypeCheckUtils.isTimePoint(t))) {
         throw new TableException(
           s"The rowtime attribute can only replace a field with a valid time type, " +
-            s"such as Timestamp or Long. But was: $typeInfo")
+            s"such as Timestamp or Long. But was: $t")
       }
     }
 
@@ -407,9 +412,9 @@ abstract class StreamTableEnvironment(
         // check reference-by-name
         else {
           val aliasOrName = origName.getOrElse(name)
-          streamType match {
+          streamLogicalType match {
             // both alias and reference must have a valid type if they replace a field
-            case ct: CompositeType[_] if ct.hasField(aliasOrName) =>
+            case ct: RowType if ct.getFieldIndex(aliasOrName) != -1 =>
               val t = ct.getTypeAt(ct.getFieldIndex(aliasOrName))
               checkRowtimeType(t)
             // alias could not be found
@@ -441,9 +446,9 @@ abstract class StreamTableEnvironment(
         }
         // check reference-by-name
         else {
-          streamType match {
+          streamLogicalType match {
             // proctime attribute must not replace a field
-            case ct: CompositeType[_] if ct.hasField(name) =>
+            case ct: RowType if ct.getFieldIndex(name) != -1 =>
               throw new TableException(
                 s"The proctime attribute '$name' must not replace an existing field.")
             case _ => // ok
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/TableEnvironment.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/TableEnvironment.scala
index 1c27219..506f724 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/TableEnvironment.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/TableEnvironment.scala
@@ -18,27 +18,10 @@
 
 package org.apache.flink.table.api
 
-import _root_.java.lang.reflect.Modifier
-import _root_.java.util.concurrent.atomic.AtomicInteger
-import _root_.java.util.{Arrays => JArrays}
-
-import org.apache.calcite.config.Lex
-import org.apache.calcite.jdbc.CalciteSchema
-import org.apache.calcite.plan.{RelOptPlanner, RelTrait, RelTraitDef}
-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.sql.util.{ChainedSqlOperatorTable, ListSqlOperatorTable}
-import org.apache.calcite.sql2rel.SqlToRelConverter
-import org.apache.calcite.tools._
 import org.apache.flink.annotation.VisibleForTesting
 import org.apache.flink.api.common.JobExecutionResult
 import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.api.common.typeutils.CompositeType
 import org.apache.flink.api.java.typeutils._
-import org.apache.flink.api.scala.typeutils.CaseClassTypeInfo
 import org.apache.flink.streaming.api.environment.{StreamExecutionEnvironment => JavaStreamExecEnv}
 import org.apache.flink.streaming.api.graph.StreamGraph
 import org.apache.flink.streaming.api.scala.{StreamExecutionEnvironment => ScalaStreamExecEnv}
@@ -49,8 +32,7 @@ import org.apache.flink.table.calcite._
 import org.apache.flink.table.codegen.ExpressionReducer
 import org.apache.flink.table.dataformat.BaseRow
 import org.apache.flink.table.functions.sql.FlinkSqlOperatorTable
-import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils
-import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils.{checkForInstantiation, checkNotSingleton, getAccumulatorTypeOfAggregateFunction, getResultTypeOfAggregateFunction}
+import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils.{checkForInstantiation, checkNotSingleton, extractResultTypeFromTableFunction, getAccumulatorTypeOfAggregateFunction, getResultTypeOfAggregateFunction}
 import org.apache.flink.table.functions.{AggregateFunction, ScalarFunction, TableFunction}
 import org.apache.flink.table.plan.cost.FlinkCostFactory
 import org.apache.flink.table.plan.nodes.calcite.{LogicalSink, Sink}
@@ -63,10 +45,29 @@ import org.apache.flink.table.plan.stats.FlinkStatistic
 import org.apache.flink.table.plan.util.SameRelObjectShuttle
 import org.apache.flink.table.sinks.TableSink
 import org.apache.flink.table.sources.TableSource
-import org.apache.flink.table.typeutils.BaseRowTypeInfo
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
+import org.apache.flink.table.types.logical.{LogicalType, RowType, TypeInformationAnyType}
+import org.apache.flink.table.types.utils.TypeConversions.fromLegacyInfoToDataType
+import org.apache.flink.table.types.{ClassLogicalTypeConverter, DataType}
 import org.apache.flink.table.validate.FunctionCatalog
 import org.apache.flink.types.Row
 
+import org.apache.calcite.config.Lex
+import org.apache.calcite.jdbc.CalciteSchema
+import org.apache.calcite.plan.{RelOptPlanner, RelTrait, RelTraitDef}
+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.sql.util.{ChainedSqlOperatorTable, ListSqlOperatorTable}
+import org.apache.calcite.sql2rel.SqlToRelConverter
+import org.apache.calcite.tools._
+
+import _root_.java.lang.reflect.Modifier
+import _root_.java.util.concurrent.atomic.AtomicInteger
+import _root_.java.util.{Arrays => JArrays}
+
 import _root_.scala.annotation.varargs
 import _root_.scala.collection.JavaConversions._
 import _root_.scala.collection.JavaConverters._
@@ -606,8 +607,7 @@ abstract class TableEnvironment(val config: TableConfig) {
     * @tparam T The type of the output row.
     */
   def registerFunction[T](name: String, tf: TableFunction[T]): Unit = {
-    implicit val typeInfo: TypeInformation[T] =
-      UserDefinedFunctionUtils.extractResultTypeFromTableFunction(tf)
+    implicit val typeInfo: TypeInformation[T] = extractResultTypeFromTableFunction(tf)
     registerTableFunctionInternal(name, tf)
   }
 
@@ -625,7 +625,7 @@ abstract class TableEnvironment(val config: TableConfig) {
     functionCatalog.registerTableFunction(
       name,
       function,
-      implicitly[TypeInformation[T]],
+      fromLegacyInfoToDataType(implicitly[TypeInformation[T]]),
       typeFactory)
   }
 
@@ -663,13 +663,13 @@ abstract class TableEnvironment(val config: TableConfig) {
     // check if class could be instantiated
     checkForInstantiation(function.getClass)
 
-    val resultTypeInfo: TypeInformation[_] = getResultTypeOfAggregateFunction(
+    val resultTypeInfo = getResultTypeOfAggregateFunction(
       function,
-      implicitly[TypeInformation[T]])
+      fromLegacyInfoToDataType(implicitly[TypeInformation[T]]))
 
-    val accTypeInfo: TypeInformation[_] = getAccumulatorTypeOfAggregateFunction(
+    val accTypeInfo = getAccumulatorTypeOfAggregateFunction(
       function,
-      implicitly[TypeInformation[ACC]])
+      fromLegacyInfoToDataType(implicitly[TypeInformation[ACC]]))
 
     functionCatalog.registerAggregateFunction(
       name,
@@ -700,11 +700,7 @@ abstract class TableEnvironment(val config: TableConfig) {
     * references a field of the input type.
     */
   // TODO: we should support Expression fields after we introduce [Expression]
-  protected def isReferenceByPosition(ct: CompositeType[_], fields: Array[String]): Boolean = {
-    if (!ct.isInstanceOf[TupleTypeInfoBase[_]]) {
-      return false
-    }
-
+  protected def isReferenceByPosition(ct: RowType, fields: Array[String]): Boolean = {
     val inputNames = ct.getFieldNames
 
     // Use the by-position mode if no of the fields exists in the input.
@@ -714,41 +710,44 @@ abstract class TableEnvironment(val config: TableConfig) {
   }
 
   /**
-    * Returns field names and field positions for a given [[TypeInformation]].
+    * Returns field names and field positions for a given [[DataType]].
     *
-    * @param inputType The TypeInformation extract the field names and positions from.
-    * @tparam A The type of the TypeInformation.
+    * @param inputType The DataType extract the field names and positions from.
+    * @tparam A The type of the DataType.
     * @return A tuple of two arrays holding the field names and corresponding field positions.
     */
   protected[flink] def getFieldInfo[A](
-      inputType: TypeInformation[A]): (Array[String], Array[Int]) = {
+      inputType: DataType): (Array[String], Array[Int]) = {
 
-    if (inputType.isInstanceOf[GenericTypeInfo[A]] && inputType.getTypeClass == classOf[Row]) {
-      throw new TableException(
-        "An input of GenericTypeInfo<Row> cannot be converted to Table. " +
-          "Please specify the type of the input with a RowTypeInfo.")
-    } else {
-      (TableEnvironment.getFieldNames(inputType), TableEnvironment.getFieldIndices(inputType))
+    val logicalType = fromDataTypeToLogicalType(inputType)
+    logicalType match {
+      case value: TypeInformationAnyType[A]
+        if value.getTypeInformation.getTypeClass == classOf[Row] =>
+        throw new TableException(
+          "An input of GenericTypeInfo<Row> cannot be converted to Table. " +
+              "Please specify the type of the input with a RowTypeInfo.")
+      case _ =>
+        (TableEnvironment.getFieldNames(inputType), TableEnvironment.getFieldIndices(inputType))
     }
   }
 
   /**
-    * Returns field names and field positions for a given [[TypeInformation]] and [[Array]] of
+    * Returns field names and field positions for a given [[DataType]] and [[Array]] of
     * field names. It does not handle time attributes.
     *
-    * @param inputType The [[TypeInformation]] against which the field names are referenced.
+    * @param inputType The [[DataType]] against which the field names are referenced.
     * @param fields The fields that define the field names.
-    * @tparam A The type of the TypeInformation.
+    * @tparam A The type of the DataType.
     * @return A tuple of two arrays holding the field names and corresponding field positions.
     */
   // TODO: we should support Expression fields after we introduce [Expression]
   protected[flink] def getFieldInfo[A](
-    inputType: TypeInformation[A],
+    inputType: DataType,
     fields: Array[String]): (Array[String], Array[Int]) = {
 
     TableEnvironment.validateType(inputType)
 
-    def referenceByName(name: String, ct: CompositeType[_]): Option[Int] = {
+    def referenceByName(name: String, ct: RowType): Option[Int] = {
       val inputIdx = ct.getFieldIndex(name)
       if (inputIdx < 0) {
         throw new TableException(s"$name is not a field of type $ct. " +
@@ -758,17 +757,16 @@ abstract class TableEnvironment(val config: TableConfig) {
       }
     }
 
-    val indexedNames: Array[(Int, String)] = inputType match {
+    val indexedNames: Array[(Int, String)] = fromDataTypeToLogicalType(inputType) match {
 
-      case g: GenericTypeInfo[A]
-        if g.getTypeClass == classOf[Row] || g.getTypeClass == classOf[BaseRow] =>
+      case g: TypeInformationAnyType[A]
+        if g.getTypeInformation.getTypeClass == classOf[Row] ||
+            g.getTypeInformation.getTypeClass == classOf[BaseRow] =>
         throw new TableException(
           "An input of GenericTypeInfo<Row> cannot be converted to Table. " +
             "Please specify the type of the input with a RowTypeInfo.")
 
-      case t: TupleTypeInfoBase[A] if t.isInstanceOf[TupleTypeInfo[A]] ||
-        t.isInstanceOf[CaseClassTypeInfo[A]] || t.isInstanceOf[RowTypeInfo] ||
-          t.isInstanceOf[BaseRowTypeInfo] =>
+      case t: RowType =>
 
         // determine schema definition mode (by position or by name)
         val isRefByPos = isReferenceByPosition(t, fields)
@@ -784,12 +782,7 @@ abstract class TableEnvironment(val config: TableConfig) {
             }
         }
 
-      case p: PojoTypeInfo[A] =>
-        fields flatMap { name =>
-          referenceByName(name, p).map((_, name))
-        }
-
-      case _: TypeInformation[_] => // atomic or other custom type information
+      case _ => // atomic or other custom type information
         if (fields.length > 1) {
           // only accept the first field for an atomic type
           throw new TableException("Only accept one field to reference an atomic type.")
@@ -855,18 +848,18 @@ abstract class TableEnvironment(val config: TableConfig) {
 object TableEnvironment {
 
   /**
-    * Returns field names for a given [[TypeInformation]].
+    * Returns field names for a given [[DataType]].
     *
-    * @param inputType The TypeInformation extract the field names.
-    * @tparam A The type of the TypeInformation.
+    * @param inputType The DataType extract the field names.
+    * @tparam A The type of the DataType.
     * @return An array holding the field names
     */
-  def getFieldNames[A](inputType: TypeInformation[A]): Array[String] = {
+  def getFieldNames[A](inputType: DataType): Array[String] = {
     validateType(inputType)
 
-    val fieldNames: Array[String] = inputType match {
-      case t: CompositeType[_] => t.getFieldNames
-      case _: TypeInformation[_] => Array("f0")
+    val fieldNames: Array[String] = fromDataTypeToLogicalType(inputType) match {
+      case t: RowType => t.getFieldNames.toArray(Array[String]())
+      case t => Array("f0")
     }
 
     if (fieldNames.contains("*")) {
@@ -878,42 +871,45 @@ object TableEnvironment {
 
   /**
     * Validate if class represented by the typeInfo is static and globally accessible
-    * @param typeInfo type to check
+    * @param dataType type to check
     * @throws TableException if type does not meet these criteria
     */
-  def validateType(typeInfo: TypeInformation[_]): Unit = {
-    val clazz = typeInfo.getTypeClass
+  def validateType(dataType: DataType): Unit = {
+    var clazz = dataType.getConversionClass
+    if (clazz == null) {
+      clazz = ClassLogicalTypeConverter.getDefaultExternalClassForType(dataType.getLogicalType)
+    }
     if ((clazz.isMemberClass && !Modifier.isStatic(clazz.getModifiers)) ||
       !Modifier.isPublic(clazz.getModifiers) ||
       clazz.getCanonicalName == null) {
       throw new TableException(
-        s"Class '$clazz' described in type information '$typeInfo' must be " +
+        s"Class '$clazz' described in type information '$dataType' must be " +
           s"static and globally accessible.")
     }
   }
 
   /**
-    * Returns field indexes for a given [[TypeInformation]].
+    * Returns field indexes for a given [[DataType]].
     *
-    * @param inputType The TypeInformation extract the field positions from.
+    * @param inputType The DataType extract the field positions from.
     * @return An array holding the field positions
     */
-  def getFieldIndices(inputType: TypeInformation[_]): Array[Int] = {
+  def getFieldIndices(inputType: DataType): Array[Int] = {
     getFieldNames(inputType).indices.toArray
   }
 
   /**
-    * Returns field types for a given [[TypeInformation]].
+    * Returns field types for a given [[DataType]].
     *
-    * @param inputType The TypeInformation to extract field types from.
+    * @param inputType The DataType to extract field types from.
     * @return An array holding the field types.
     */
-  def getFieldTypes(inputType: TypeInformation[_]): Array[TypeInformation[_]] = {
+  def getFieldTypes(inputType: DataType): Array[LogicalType] = {
     validateType(inputType)
 
-    inputType match {
-      case ct: CompositeType[_] => 0.until(ct.getArity).map(i => ct.getTypeAt(i)).toArray
-      case t: TypeInformation[_] => Array(t.asInstanceOf[TypeInformation[_]])
+    fromDataTypeToLogicalType(inputType) match {
+      case t: RowType => t.getChildren.toArray(Array[LogicalType]())
+      case t => Array(t)
     }
   }
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/TableImpl.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/TableImpl.scala
index 82edb6f..5505cc7 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/TableImpl.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/api/TableImpl.scala
@@ -18,12 +18,13 @@
 
 package org.apache.flink.table.api
 
-import org.apache.flink.table.`type`.TypeConverters.createExternalTypeInfoFromInternalType
 import org.apache.flink.table.calcite.FlinkTypeFactory._
 import org.apache.flink.table.expressions.Expression
 import org.apache.flink.table.functions.TemporalTableFunction
-import org.apache.calcite.rel.RelNode
 import org.apache.flink.table.operations.QueryOperation
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromLogicalTypeToDataType
+
+import org.apache.calcite.rel.RelNode
 
 import _root_.scala.collection.JavaConversions._
 
@@ -42,12 +43,11 @@ class TableImpl(val tableEnv: TableEnvironment, relNode: RelNode) extends Table
 
   private lazy val tableSchema: TableSchema = {
     val rowType = relNode.getRowType
-    val fieldNames = rowType.getFieldList.map(_.getName)
-    val fieldTypes = rowType.getFieldList map { tp =>
-      val internalType = toInternalType(tp.getType)
-      createExternalTypeInfoFromInternalType(internalType)
+    val builder = TableSchema.builder()
+    rowType.getFieldList.foreach { field =>
+      builder.field(field.getName, fromLogicalTypeToDataType(toLogicalType(field.getType)))
     }
-    new TableSchema(fieldNames.toArray, fieldTypes.toArray)
+    builder.build()
   }
 
   /**
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkCalciteSqlValidator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkCalciteSqlValidator.scala
index 1fb0be8..715f2d9 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkCalciteSqlValidator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkCalciteSqlValidator.scala
@@ -18,8 +18,8 @@
 
 package org.apache.flink.table.calcite
 
-import org.apache.flink.table.`type`.DecimalType
 import org.apache.flink.table.api.ValidationException
+import org.apache.flink.table.types.logical.DecimalType
 
 import org.apache.calcite.adapter.java.JavaTypeFactory
 import org.apache.calcite.prepare.CalciteCatalogReader
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkLocalRef.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkLocalRef.scala
index 62831dd..e1d8975 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkLocalRef.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkLocalRef.scala
@@ -19,7 +19,7 @@ package org.apache.flink.table.calcite
 
 import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.rex.RexLocalRef
-import org.apache.flink.table.`type`.InternalType
+import org.apache.flink.table.types.logical.LogicalType
 
 /**
   * Special reference which represent a local filed, such as aggregate buffers or constants.
@@ -32,7 +32,7 @@ case class RexAggLocalVariable(
     fieldTerm: String,
     nullTerm: String,
     dataType: RelDataType,
-    internalType: InternalType)
+    internalType: LogicalType)
   extends RexLocalRef(0, dataType)
 
 /**
@@ -44,5 +44,5 @@ case class RexAggLocalVariable(
 case class RexDistinctKeyVariable(
     keyTerm: String,
     dataType: RelDataType,
-    internalType: InternalType)
+    internalType: LogicalType)
   extends RexLocalRef(0, dataType)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkTypeFactory.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkTypeFactory.scala
index 67642ff..9fdefe0 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkTypeFactory.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkTypeFactory.scala
@@ -18,110 +18,137 @@
 
 package org.apache.flink.table.calcite
 
-import org.apache.flink.api.common.typeinfo.{NothingTypeInfo, TypeInformation}
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
-import org.apache.flink.table.`type`._
-import org.apache.flink.table.api.{TableException, TableSchema}
+import org.apache.flink.api.common.typeinfo.NothingTypeInfo
+import org.apache.flink.api.java.typeutils.TypeExtractor
+import org.apache.flink.table.api.{DataTypes, TableException}
+import org.apache.flink.table.calcite.FlinkTypeFactory.toLogicalType
 import org.apache.flink.table.plan.schema.{GenericRelDataType, _}
-import org.apache.flink.table.typeutils.TimeIndicatorTypeInfo
+import org.apache.flink.table.types.logical._
+import org.apache.flink.types.Nothing
+import org.apache.flink.util.Preconditions.checkArgument
 
 import org.apache.calcite.avatica.util.TimeUnit
 import org.apache.calcite.jdbc.JavaTypeFactoryImpl
+import org.apache.calcite.rel.RelNode
 import org.apache.calcite.rel.`type`._
 import org.apache.calcite.sql.SqlIntervalQualifier
 import org.apache.calcite.sql.`type`.SqlTypeName._
-import org.apache.calcite.sql.`type`.{BasicSqlType, SqlTypeName, SqlTypeUtil}
+import org.apache.calcite.sql.`type`.{BasicSqlType, MapSqlType, SqlTypeName, SqlTypeUtil}
 import org.apache.calcite.sql.parser.SqlParserPos
 import org.apache.calcite.util.ConversionUtil
 
 import java.nio.charset.Charset
 import java.util
 
+import scala.collection.JavaConversions._
 import scala.collection.JavaConverters._
 import scala.collection.mutable
 
 /**
-  * Flink specific type factory that represents the interface between Flink's [[InternalType]]
+  * Flink specific type factory that represents the interface between Flink's [[LogicalType]]
   * and Calcite's [[RelDataType]].
   */
 class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImpl(typeSystem) {
 
-  // NOTE: for future data types it might be necessary to
-  // override more methods of RelDataTypeFactoryImpl
+  private val seenTypes = mutable.HashMap[LogicalType, RelDataType]()
 
-  private val seenTypes = mutable.HashMap[(InternalType, Boolean), RelDataType]()
-
-  def createTypeFromInternalType(
-      tp: InternalType,
-      isNullable: Boolean): RelDataType = {
+  /**
+    * Create a calcite field type in table schema from [[LogicalType]]. It use
+    * PEEK_FIELDS_NO_EXPAND when type is a nested struct type (Flink [[RowType]]).
+    *
+    * @param t flink logical type.
+    * @return calcite [[RelDataType]].
+    */
+  def createFieldTypeFromLogicalType(t: LogicalType): RelDataType = {
+    def newRelDataType(): RelDataType = t.getTypeRoot match {
+      case LogicalTypeRoot.BOOLEAN => createSqlType(BOOLEAN)
+      case LogicalTypeRoot.TINYINT => createSqlType(TINYINT)
+      case LogicalTypeRoot.SMALLINT => createSqlType(SMALLINT)
+      case LogicalTypeRoot.INTEGER => createSqlType(INTEGER)
+      case LogicalTypeRoot.BIGINT => createSqlType(BIGINT)
+      case LogicalTypeRoot.FLOAT => createSqlType(FLOAT)
+      case LogicalTypeRoot.DOUBLE => createSqlType(DOUBLE)
+      case LogicalTypeRoot.VARCHAR =>
+        createSqlType(VARCHAR, t.asInstanceOf[VarCharType].getLength)
+
+      // temporal types
+      case LogicalTypeRoot.DATE => createSqlType(DATE)
+      case LogicalTypeRoot.TIME_WITHOUT_TIME_ZONE => createSqlType(TIME)
+
+      // interval types
+      case LogicalTypeRoot.INTERVAL_YEAR_MONTH =>
+        createSqlIntervalType(
+          new SqlIntervalQualifier(TimeUnit.YEAR, TimeUnit.MONTH, SqlParserPos.ZERO))
+      case LogicalTypeRoot.INTERVAL_DAY_TIME =>
+        createSqlIntervalType(
+          new SqlIntervalQualifier(TimeUnit.DAY, TimeUnit.SECOND, SqlParserPos.ZERO))
+
+      case LogicalTypeRoot.VARBINARY =>
+        createSqlType(VARBINARY, t.asInstanceOf[VarBinaryType].getLength)
+
+      case LogicalTypeRoot.DECIMAL =>
+        val decimalType = t.asInstanceOf[DecimalType]
+        createSqlType(DECIMAL, decimalType.getPrecision, decimalType.getScale)
+
+      case LogicalTypeRoot.ROW =>
+        val rowType = t.asInstanceOf[RowType]
+        buildStructType(
+          rowType.getFieldNames,
+          rowType.getChildren,
+          // fields are not expanded in "SELECT *"
+          StructKind.PEEK_FIELDS_NO_EXPAND)
+
+      case LogicalTypeRoot.ARRAY =>
+        val arrayType = t.asInstanceOf[ArrayType]
+        createArrayType(createFieldTypeFromLogicalType(arrayType.getElementType), -1)
+
+      case LogicalTypeRoot.MAP =>
+        val mapType = t.asInstanceOf[MapType]
+        createMapType(
+          createFieldTypeFromLogicalType(mapType.getKeyType),
+          createFieldTypeFromLogicalType(mapType.getValueType))
+
+      case LogicalTypeRoot.MULTISET =>
+        val multisetType = t.asInstanceOf[MultisetType]
+        createMultisetType(createFieldTypeFromLogicalType(multisetType.getElementType), -1)
+
+      case LogicalTypeRoot.ANY =>
+        new GenericRelDataType(
+          t.asInstanceOf[TypeInformationAnyType[_]],
+          true,
+          getTypeSystem)
+
+      case _@t =>
+        throw new TableException(s"Type is not supported: $t")
+    }
 
-    val relType = seenTypes.get((tp, isNullable)) match {
-      case Some(retType: RelDataType) => retType
-      case None =>
-        val refType = tp match {
-          case InternalTypes.BOOLEAN => createSqlType(BOOLEAN)
-          case InternalTypes.BYTE => createSqlType(TINYINT)
-          case InternalTypes.SHORT => createSqlType(SMALLINT)
-          case InternalTypes.INT => createSqlType(INTEGER)
-          case InternalTypes.LONG => createSqlType(BIGINT)
-          case InternalTypes.FLOAT => createSqlType(FLOAT)
-          case InternalTypes.DOUBLE => createSqlType(DOUBLE)
-          case InternalTypes.STRING => createSqlType(VARCHAR)
-
-          // temporal types
-          case InternalTypes.DATE => createSqlType(DATE)
-          case InternalTypes.TIME => createSqlType(TIME)
-          case InternalTypes.TIMESTAMP => createSqlType(TIMESTAMP)
-          case InternalTypes.PROCTIME_INDICATOR => createProctimeIndicatorType()
-          case InternalTypes.ROWTIME_INDICATOR => createRowtimeIndicatorType()
-
-          // interval types
-          case InternalTypes.INTERVAL_MONTHS =>
-            createSqlIntervalType(
-              new SqlIntervalQualifier(TimeUnit.YEAR, TimeUnit.MONTH, SqlParserPos.ZERO))
-          case InternalTypes.INTERVAL_MILLIS =>
-            createSqlIntervalType(
-              new SqlIntervalQualifier(TimeUnit.DAY, TimeUnit.SECOND, SqlParserPos.ZERO))
-
-          case InternalTypes.BINARY => createSqlType(VARBINARY)
-
-          case decimal: DecimalType =>
-            createSqlType(DECIMAL, decimal.precision(), decimal.scale())
-
-          case rowType: RowType => new RowRelDataType(rowType, isNullable, this)
-
-          case arrayType: ArrayType => new ArrayRelDataType(arrayType,
-            createTypeFromInternalType(arrayType.getElementType, isNullable = true), isNullable)
-
-          case mapType: MapType => new MapRelDataType(
-            mapType,
-            createTypeFromInternalType(mapType.getKeyType, isNullable = true),
-            createTypeFromInternalType(mapType.getValueType, isNullable = true),
-            isNullable)
-
-          case multisetType: MultisetType => new MultisetRelDataType(
-            multisetType,
-            createTypeFromInternalType(multisetType.getElementType, isNullable = true),
-            isNullable)
-
-          case generic: GenericType[_] =>
-            new GenericRelDataType(generic, isNullable, getTypeSystem)
-
-          case _@t =>
-            throw new TableException(s"Type is not supported: $t")
+    // Kind in TimestampType do not affect the hashcode and equals, So we can't put it to seenTypes
+    val relType = t.getTypeRoot match {
+      case LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE =>
+        val timestampType = t.asInstanceOf[TimestampType]
+        timestampType.getKind match {
+          case TimestampKind.PROCTIME => createProctimeIndicatorType()
+          case TimestampKind.ROWTIME => createRowtimeIndicatorType()
+          case TimestampKind.REGULAR => createSqlType(TIMESTAMP)
+        }
+      case _ =>
+        seenTypes.get(t) match {
+          case Some(retType: RelDataType) => retType
+          case None =>
+            val refType = newRelDataType()
+            seenTypes.put(t, refType)
+            refType
         }
-        seenTypes.put((tp, isNullable), refType)
-        refType
     }
 
-    createTypeWithNullability(relType, isNullable)
+    createTypeWithNullability(relType, t.isNullable)
   }
 
   /**
     * Creates a indicator type for processing-time, but with similar properties as SQL timestamp.
     */
   def createProctimeIndicatorType(): RelDataType = {
-    val originalType = createTypeFromInternalType(InternalTypes.TIMESTAMP, isNullable = false)
+    val originalType = createFieldTypeFromLogicalType(new TimestampType(3))
     canonize(
       new TimeIndicatorRelDataType(
         getTypeSystem,
@@ -134,7 +161,7 @@ class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImp
     * Creates a indicator type for event-time, but with similar properties as SQL timestamp.
     */
   def createRowtimeIndicatorType(): RelDataType = {
-    val originalType = createTypeFromInternalType(InternalTypes.TIMESTAMP, isNullable = false)
+    val originalType = createFieldTypeFromLogicalType(new TimestampType(3))
     canonize(
       new TimeIndicatorRelDataType(
         getTypeSystem,
@@ -144,80 +171,38 @@ class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImp
   }
 
   /**
-    * Creates a struct type with the input fieldNames and input fieldTypes using FlinkTypeFactory
+    * Creates a table row type with the input fieldNames and input fieldTypes using
+    * FlinkTypeFactory. Table row type is table schema for Calcite RelNode. See getRowType of
+    * [[RelNode]]. Use FULLY_QUALIFIED to let each field must be referenced explicitly.
     *
     * @param fieldNames field names
-    * @param fieldTypes field types, every element is Flink's [[InternalType]]
-    * @return a struct type with the input fieldNames, input fieldTypes, and system fields
+    * @param fieldTypes field types, every element is Flink's [[LogicalType]]
+    * @return a table row type with the input fieldNames, input fieldTypes.
     */
-  def buildLogicalRowType(
+  def buildRelNodeRowType(
       fieldNames: Seq[String],
-      fieldTypes: Seq[InternalType]): RelDataType = {
-    buildLogicalRowType(
-      fieldNames,
-      fieldTypes,
-      fieldTypes.map(_ => true))
+      fieldTypes: Seq[LogicalType]): RelDataType = {
+    buildStructType(fieldNames, fieldTypes, StructKind.FULLY_QUALIFIED)
   }
 
   /**
-    * Creates a struct type with the input fieldNames, input fieldTypes and input fieldNullables
-    * using FlinkTypeFactory
+    * 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 [[InternalType]]
-    * @param fieldNullables field nullable properties
-    * @return a struct type with the input fieldNames, input fieldTypes, and system fields
-    */
-  def buildLogicalRowType(
-      fieldNames: Seq[String],
-      fieldTypes: Seq[InternalType],
-      fieldNullables: Seq[Boolean]): RelDataType = {
-    val logicalRowTypeBuilder = builder
-    val fields = fieldNames.zip(fieldTypes).zip(fieldNullables)
-    fields foreach {
-      case ((fieldName, fieldType), fieldNullable) =>
-        logicalRowTypeBuilder.add(fieldName, createTypeFromInternalType(fieldType, fieldNullable))
-    }
-    logicalRowTypeBuilder.build
-  }
-
-  /**
-    * Created a struct type with the input table schema using FlinkTypeFactory
-    * @param tableSchema  the table schema
-    * @return a struct type with the input fieldNames, input fieldTypes, and system fields
+    * @param fieldNames field names
+    * @param fieldTypes field types, every element is Flink's [[LogicalType]].
+    * @param structKind Name resolution policy. See more information in [[StructKind]].
+    * @return a struct type with the input fieldNames, input fieldTypes.
     */
-  def buildLogicalRowType(tableSchema: TableSchema, isStreaming: Option[Boolean]): RelDataType = {
-    buildRelDataType(
-      tableSchema.getFieldNames.toSeq,
-      tableSchema.getFieldTypes map {
-        case _: TimeIndicatorTypeInfo if isStreaming.isDefined && !isStreaming.get =>
-          InternalTypes.TIMESTAMP
-        case tpe: TypeInformation[_] => createInternalTypeFromTypeInfo(tpe)
-      })
-  }
-
-  def buildRelDataType(
-      fieldNames: Seq[String],
-      fieldTypes: Seq[InternalType]): RelDataType = {
-    buildRelDataType(
-      fieldNames,
-      fieldTypes,
-      fieldTypes.map(!FlinkTypeFactory.isTimeIndicatorType(_)))
-  }
-
-  def buildRelDataType(
+  private def buildStructType(
       fieldNames: Seq[String],
-      fieldTypes: Seq[InternalType],
-      fieldNullables: Seq[Boolean]): RelDataType = {
+      fieldTypes: Seq[LogicalType],
+      structKind: StructKind): RelDataType = {
     val b = builder
-    val fields = fieldNames.zip(fieldTypes).zip(fieldNullables)
+    b.kind(structKind)
+    val fields = fieldNames.zip(fieldTypes)
     fields foreach {
-      case ((fieldName, fieldType), fieldNullable) =>
-        if (FlinkTypeFactory.isTimeIndicatorType(fieldType) && fieldNullable) {
-          throw new TableException(
-            s"$fieldName can not be nullable because it is TimeIndicatorType!")
-        }
-        b.add(fieldName, createTypeFromInternalType(fieldType, fieldNullable))
+      case (fieldName, fieldType) =>
+        b.add(fieldName, createFieldTypeFromLogicalType(fieldType))
     }
     b.build
   }
@@ -246,35 +231,23 @@ class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImp
     }
   }
 
-
   override def createArrayType(elementType: RelDataType, maxCardinality: Long): RelDataType = {
-    val arrayType = InternalTypes.createArrayType(FlinkTypeFactory.toInternalType(elementType))
-    val relType = new ArrayRelDataType(
-      arrayType,
-      elementType,
-      isNullable = false)
-    canonize(relType)
+    // Just validate type, make sure there is a failure in validate phase.
+    toLogicalType(elementType)
+    super.createArrayType(elementType, maxCardinality)
   }
 
   override def createMapType(keyType: RelDataType, valueType: RelDataType): RelDataType = {
-    val internalKeyType = FlinkTypeFactory.toInternalType(keyType)
-    val internalValueType = FlinkTypeFactory.toInternalType(valueType)
-    val internalMapType = InternalTypes.createMapType(internalKeyType, internalValueType)
-    val relType = new MapRelDataType(
-      internalMapType,
-      keyType,
-      valueType,
-      isNullable = false)
-    canonize(relType)
+    // Just validate type, make sure there is a failure in validate phase.
+    toLogicalType(keyType)
+    toLogicalType(valueType)
+    super.createMapType(keyType, valueType)
   }
 
   override def createMultisetType(elementType: RelDataType, maxCardinality: Long): RelDataType = {
-    val internalElementType = FlinkTypeFactory.toInternalType(elementType)
-    val relType = new MultisetRelDataType(
-      InternalTypes.createMultisetType(internalElementType),
-      elementType,
-      isNullable = false)
-    canonize(relType)
+    // Just validate type, make sure there is a failure in validate phase.
+    toLogicalType(elementType)
+    super.createMultisetType(elementType, maxCardinality)
   }
 
   override def createSqlType(typeName: SqlTypeName): RelDataType = {
@@ -282,8 +255,7 @@ class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImp
       // if we got here, the precision and scale are not specified, here we
       // keep precision/scale in sync with our type system's default value,
       // see DecimalType.USER_DEFAULT.
-      createSqlType(typeName, DecimalType.USER_DEFAULT.precision(),
-        DecimalType.USER_DEFAULT.scale())
+      createSqlType(typeName, DecimalType.DEFAULT_PRECISION, DecimalType.DEFAULT_SCALE)
     } else {
       super.createSqlType(typeName)
     }
@@ -300,15 +272,6 @@ class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImp
 
     // change nullability
     val newType = relDataType match {
-      case array: ArrayRelDataType =>
-        new ArrayRelDataType(array.arrayType, array.getComponentType, isNullable)
-
-      case map: MapRelDataType =>
-        new MapRelDataType(map.mapType, map.keyType, map.valueType, isNullable)
-
-      case multiSet: MultisetRelDataType =>
-        new MultisetRelDataType(multiSet.multisetType, multiSet.getComponentType, isNullable)
-
       case generic: GenericRelDataType =>
         new GenericRelDataType(generic.genericType, isNullable, typeSystem)
 
@@ -374,10 +337,10 @@ class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImp
   override def createDecimalQuotient(type1: RelDataType, type2: RelDataType): RelDataType = {
     if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2) &&
         (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2))) {
-      val result = DecimalType.inferDivisionType(
+      val result = FlinkTypeSystem.inferDivisionType(
         type1.getPrecision, type1.getScale,
         type2.getPrecision, type2.getScale)
-      createSqlType(SqlTypeName.DECIMAL, result.precision, result.scale)
+      createSqlType(SqlTypeName.DECIMAL, result.getPrecision, result.getScale)
     } else {
       null
     }
@@ -386,8 +349,9 @@ class FlinkTypeFactory(typeSystem: RelDataTypeSystem) extends JavaTypeFactoryImp
 
 object FlinkTypeFactory {
 
-  def isTimeIndicatorType(t: InternalType): Boolean = t match {
-    case InternalTypes.ROWTIME_INDICATOR | InternalTypes.PROCTIME_INDICATOR => true
+  def isTimeIndicatorType(t: LogicalType): Boolean = t match {
+    case t: TimestampType
+      if t.getKind == TimestampKind.ROWTIME || t.getKind == TimestampKind.PROCTIME => true
     case _ => false
   }
 
@@ -406,81 +370,91 @@ object FlinkTypeFactory {
     case _ => false
   }
 
-  def toInternalType(relDataType: RelDataType): InternalType = relDataType.getSqlTypeName match {
-    case BOOLEAN => InternalTypes.BOOLEAN
-    case TINYINT => InternalTypes.BYTE
-    case SMALLINT => InternalTypes.SHORT
-    case INTEGER => InternalTypes.INT
-    case BIGINT => InternalTypes.LONG
-    case FLOAT => InternalTypes.FLOAT
-    case DOUBLE => InternalTypes.DOUBLE
-    case VARCHAR | CHAR => InternalTypes.STRING
-    case VARBINARY | BINARY => InternalTypes.BINARY
-    case DECIMAL => InternalTypes.createDecimalType(relDataType.getPrecision, relDataType.getScale)
-
-    // time indicators
-    case TIMESTAMP if relDataType.isInstanceOf[TimeIndicatorRelDataType] =>
-      val indicator = relDataType.asInstanceOf[TimeIndicatorRelDataType]
-      if (indicator.isEventTime) {
-        InternalTypes.ROWTIME_INDICATOR
-      } else {
-        InternalTypes.PROCTIME_INDICATOR
-      }
-
-    // temporal types
-    case DATE => InternalTypes.DATE
-    case TIME => InternalTypes.TIME
-    case TIMESTAMP => InternalTypes.TIMESTAMP
-    case typeName if YEAR_INTERVAL_TYPES.contains(typeName) => InternalTypes.INTERVAL_MONTHS
-    case typeName if DAY_INTERVAL_TYPES.contains(typeName) => InternalTypes.INTERVAL_MILLIS
-
-    case NULL =>
-      throw new TableException(
-        "Type NULL is not supported. Null values must have a supported type.")
-
-    // symbol for special flags e.g. TRIM's BOTH, LEADING, TRAILING
-    // are represented as Enum
-    case SYMBOL => InternalTypes.createGenericType(classOf[Enum[_]])
-
-    // extract encapsulated Type
-    case ANY if relDataType.isInstanceOf[GenericRelDataType] =>
-      val genericRelDataType = relDataType.asInstanceOf[GenericRelDataType]
-      genericRelDataType.genericType
-
-    case ROW if relDataType.isInstanceOf[RowRelDataType] =>
-      val compositeRelDataType = relDataType.asInstanceOf[RowRelDataType]
-      compositeRelDataType.rowType
-
-    case ROW if relDataType.isInstanceOf[RelRecordType] =>
-      val relRecordType = relDataType.asInstanceOf[RelRecordType]
-      new RowSchema(relRecordType).internalType
-
-    case MULTISET if relDataType.isInstanceOf[MultisetRelDataType] =>
-      val multisetRelDataType = relDataType.asInstanceOf[MultisetRelDataType]
-      multisetRelDataType.multisetType
-
-    case ARRAY if relDataType.isInstanceOf[ArrayRelDataType] =>
-      val arrayRelDataType = relDataType.asInstanceOf[ArrayRelDataType]
-      arrayRelDataType.arrayType
-
-    case MAP if relDataType.isInstanceOf[MapRelDataType] =>
-      val mapRelDataType = relDataType.asInstanceOf[MapRelDataType]
-      mapRelDataType.mapType
-
-    // CURSOR for UDTF case, whose type info will never be used, just a placeholder
-    case CURSOR => new GenericType(new NothingTypeInfo)
+  def toLogicalType(relDataType: RelDataType): LogicalType = {
+    val logicalType = relDataType.getSqlTypeName match {
+      case BOOLEAN => new BooleanType()
+      case TINYINT => new TinyIntType()
+      case SMALLINT => new SmallIntType()
+      case INTEGER => new IntType()
+      case BIGINT => new BigIntType()
+      case FLOAT => new FloatType()
+      case DOUBLE => new DoubleType()
+      case VARCHAR | CHAR =>
+        // TODO we use VarCharType to support sql CHAR, VarCharType don't support 0 length
+        new VarCharType(
+          if (relDataType.getPrecision == 0) VarCharType.MAX_LENGTH else relDataType.getPrecision)
+      case VARBINARY | BINARY =>
+        // TODO we use VarBinaryType to support sql BINARY, VarBinaryType don't support 0 length
+        new VarBinaryType(
+          if (relDataType.getPrecision == 0) VarBinaryType.MAX_LENGTH else relDataType.getPrecision)
+      case DECIMAL => new DecimalType(relDataType.getPrecision, relDataType.getScale)
+
+      // time indicators
+      case TIMESTAMP if relDataType.isInstanceOf[TimeIndicatorRelDataType] =>
+        val indicator = relDataType.asInstanceOf[TimeIndicatorRelDataType]
+        if (indicator.isEventTime) {
+          new TimestampType(true, TimestampKind.ROWTIME, 3)
+        } else {
+          new TimestampType(true, TimestampKind.PROCTIME, 3)
+        }
 
-    case _@t =>
-      throw new TableException(s"Type is not supported: $t")
+      // temporal types
+      case DATE => new DateType()
+      case TIME => new TimeType()
+      case TIMESTAMP => new TimestampType(3)
+      case typeName if YEAR_INTERVAL_TYPES.contains(typeName) =>
+        DataTypes.INTERVAL(DataTypes.MONTH).getLogicalType
+      case typeName if DAY_INTERVAL_TYPES.contains(typeName) =>
+        DataTypes.INTERVAL(DataTypes.SECOND(3)).getLogicalType
+
+      case NULL =>
+        throw new TableException(
+          "Type NULL is not supported. Null values must have a supported type.")
+
+      // symbol for special flags e.g. TRIM's BOTH, LEADING, TRAILING
+      // are represented as Enum
+      case SYMBOL => new TypeInformationAnyType[Enum[_]](
+        TypeExtractor.createTypeInfo(classOf[Enum[_]]))
+
+      // extract encapsulated Type
+      case ANY if relDataType.isInstanceOf[GenericRelDataType] =>
+        val genericRelDataType = relDataType.asInstanceOf[GenericRelDataType]
+        genericRelDataType.genericType
+
+      case ROW if relDataType.isInstanceOf[RelRecordType] =>
+        val recordType = relDataType.asInstanceOf[RelRecordType]
+        RowType.of(
+          recordType.getFieldList.map(_.getType).map(toLogicalType).toArray,
+          recordType.getFieldNames.toSeq.toArray)
+
+      case ROW if relDataType.isInstanceOf[RelRecordType] =>
+        toLogicalRowType(relDataType.asInstanceOf[RelRecordType])
+
+      case MULTISET => new MultisetType(toLogicalType(relDataType.getComponentType))
+
+      case ARRAY => new ArrayType(toLogicalType(relDataType.getComponentType))
+
+      case MAP if relDataType.isInstanceOf[MapSqlType] =>
+        val mapRelDataType = relDataType.asInstanceOf[MapSqlType]
+        new MapType(
+          toLogicalType(mapRelDataType.getKeyType),
+          toLogicalType(mapRelDataType.getValueType))
+
+      // CURSOR for UDTF case, whose type info will never be used, just a placeholder
+      case CURSOR => new TypeInformationAnyType[Nothing](new NothingTypeInfo)
+
+      case _@t =>
+        throw new TableException(s"Type is not supported: $t")
+    }
+    logicalType.copy(relDataType.isNullable)
   }
 
-  def toInternalRowType(logicalRowType: RelDataType): RowType = {
-    // convert to InternalType
-    val logicalFieldTypes = logicalRowType.getFieldList.asScala map {
-      relDataType => FlinkTypeFactory.toInternalType(relDataType.getType)
-    }
-    // field names
-    val logicalFieldNames = logicalRowType.getFieldNames.asScala
-    new RowType(logicalFieldTypes.toArray[InternalType], logicalFieldNames.toArray)
+  def toLogicalRowType(relType: RelDataType): RowType = {
+    checkArgument(relType.isStruct)
+    RowType.of(
+      relType.getFieldList.asScala
+          .map(fieldType => toLogicalType(fieldType.getType))
+          .toArray[LogicalType],
+      relType.getFieldNames.asScala.toArray)
   }
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkTypeSystem.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkTypeSystem.scala
index ff208fb..7151929 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkTypeSystem.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/FlinkTypeSystem.scala
@@ -18,7 +18,7 @@
 
 package org.apache.flink.table.calcite
 
-import org.apache.flink.table.`type`.{DecimalType, InternalType, InternalTypes}
+import org.apache.flink.table.types.logical.{DecimalType, DoubleType, LogicalType}
 import org.apache.flink.table.typeutils.TypeCheckUtils
 
 import org.apache.calcite.rel.`type`.{RelDataType, RelDataTypeFactory, RelDataTypeSystemImpl}
@@ -38,7 +38,7 @@ class FlinkTypeSystem extends RelDataTypeSystemImpl {
   override def getDefaultPrecision(typeName: SqlTypeName): Int = typeName match {
 
     // Calcite will limit the length of the VARCHAR field to 65536
-    case SqlTypeName.VARCHAR =>
+    case SqlTypeName.VARCHAR | SqlTypeName.VARBINARY =>
       Int.MaxValue
 
     // we currently support only timestamps with milliseconds precision
@@ -49,6 +49,14 @@ class FlinkTypeSystem extends RelDataTypeSystemImpl {
       super.getDefaultPrecision(typeName)
   }
 
+  override def getMaxPrecision(typeName: SqlTypeName): Int = typeName match {
+    case SqlTypeName.VARCHAR | SqlTypeName.CHAR | SqlTypeName.VARBINARY | SqlTypeName.BINARY =>
+      Int.MaxValue
+
+    case _ =>
+      super.getMaxPrecision(typeName)
+  }
+
   // when union a number of CHAR types of different lengths, we should cast to a VARCHAR
   // this fixes the problem of CASE WHEN with different length string literals but get wrong
   // result with additional space suffix
@@ -56,40 +64,85 @@ class FlinkTypeSystem extends RelDataTypeSystemImpl {
 
   override def deriveAvgAggType(
       typeFactory: RelDataTypeFactory, argType: RelDataType): RelDataType = {
-    val argTypeInfo = FlinkTypeFactory.toInternalType(argType)
+    val argTypeInfo = FlinkTypeFactory.toLogicalType(argType)
     val avgType = FlinkTypeSystem.deriveAvgAggType(argTypeInfo)
-    typeFactory.asInstanceOf[FlinkTypeFactory].createTypeFromInternalType(
-      avgType, argType.isNullable)
+    typeFactory.asInstanceOf[FlinkTypeFactory].createFieldTypeFromLogicalType(
+      avgType.copy(argType.isNullable))
   }
 
   override def deriveSumType(
       typeFactory: RelDataTypeFactory, argType: RelDataType): RelDataType = {
-    val argTypeInfo = FlinkTypeFactory.toInternalType(argType)
+    val argTypeInfo = FlinkTypeFactory.toLogicalType(argType)
     val sumType = FlinkTypeSystem.deriveSumType(argTypeInfo)
-    typeFactory.asInstanceOf[FlinkTypeFactory].createTypeFromInternalType(
-      sumType, argType.isNullable)
+    typeFactory.asInstanceOf[FlinkTypeFactory].createFieldTypeFromLogicalType(
+      sumType.copy(argType.isNullable))
   }
 }
 
 object FlinkTypeSystem {
 
-  def deriveAvgAggType(argType: InternalType): InternalType = argType match {
+  def deriveAvgAggType(argType: LogicalType): LogicalType = argType match {
     case dt: DecimalType =>
-      val result = DecimalType.inferAggAvgType(dt.scale())
-      DecimalType.of(result.precision(), result.scale())
-    case nt if TypeCheckUtils.isNumeric(nt) => InternalTypes.DOUBLE
+      val result = inferAggAvgType(dt.getScale)
+      new DecimalType(result.getPrecision, result.getScale)
+    case nt if TypeCheckUtils.isNumeric(nt) => new DoubleType()
     case _ =>
       throw new RuntimeException("Unsupported argType for AVG(): " + argType)
   }
 
-  def deriveSumType(argType: InternalType): InternalType = argType match {
+  def deriveSumType(argType: LogicalType): LogicalType = argType match {
     case dt: DecimalType =>
-      val result = DecimalType.inferAggSumType(dt.scale())
-      DecimalType.of(result.precision(), result.scale())
+      val result = inferAggSumType(dt.getScale())
+      new DecimalType(result.getPrecision(), result.getScale())
     case nt if TypeCheckUtils.isNumeric(nt) =>
       argType
     case _ =>
       throw new RuntimeException("Unsupported argType for SUM(): " + argType)
   }
 
+  /**
+    * https://docs.microsoft.com/en-us/sql/t-sql/data-types/precision-scale-and-length-transact-sql.
+    */
+  def inferDivisionType(
+      precision1: Int, scale1: Int, precision2: Int, scale2: Int): DecimalType = {
+    // note: magic numbers are used directly here, because it's not really a general algorithm.
+    var scale = Math.max(6, scale1 + precision2 + 1)
+    var precision = precision1 - scale1 + scale2 + scale
+    if (precision > 38) {
+      scale = Math.max(6, 38 - (precision - scale))
+      precision = 38
+    }
+    new DecimalType(precision, scale)
+  }
+
+  def inferIntDivType(precision1: Int, scale1: Int, scale2: Int): DecimalType = {
+    val p = Math.min(38, precision1 - scale1 + scale2)
+    new DecimalType(p, 0)
+  }
+
+  /**
+    * https://docs.microsoft.com/en-us/sql/t-sql/functions/sum-transact-sql.
+    */
+  def inferAggSumType(scale: Int) = new DecimalType(38, scale)
+
+  /**
+    * https://docs.microsoft.com/en-us/sql/t-sql/functions/avg-transact-sql
+    * however, we count by LONG, therefore divide by Decimal(20,0),
+    * but the end result is actually the same, which is Decimal(38, max(6,s)).
+    */
+  def inferAggAvgType(scale: Int): DecimalType = inferDivisionType(38, scale, 20, 0)
+
+  /**
+    * return type of Round( DECIMAL(p,s), r).
+    */
+  def inferRoundType(precision: Int, scale: Int, r: Int): DecimalType = {
+    if (r >= scale) new DecimalType(precision, scale)
+    else if (r < 0) new DecimalType(Math.min(38, 1 + precision - scale), 0)
+    else { // 0 <= r < s
+      new DecimalType(1 + precision - scale + r, r)
+    }
+    // NOTE: rounding may increase the digits by 1, therefore we need +1 on precisions.
+  }
+
+  val DECIMAL_SYSTEM_DEFAULT = new DecimalType(DecimalType.MAX_PRECISION, 18)
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/RelTimeIndicatorConverter.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/RelTimeIndicatorConverter.scala
index 7675b84..0447e79 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/RelTimeIndicatorConverter.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/calcite/RelTimeIndicatorConverter.scala
@@ -18,12 +18,12 @@
 
 package org.apache.flink.table.calcite
 
-import org.apache.flink.table.`type`.InternalTypes
 import org.apache.flink.table.api.{TableException, ValidationException}
 import org.apache.flink.table.calcite.FlinkTypeFactory._
 import org.apache.flink.table.functions.sql.FlinkSqlOperatorTable
 import org.apache.flink.table.plan.nodes.calcite._
 import org.apache.flink.table.plan.schema.TimeIndicatorRelDataType
+import org.apache.flink.table.types.logical.TimestampType
 
 import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.rel.core._
@@ -47,7 +47,7 @@ class RelTimeIndicatorConverter(rexBuilder: RexBuilder) extends RelShuttle {
   private def timestamp(isNullable: Boolean): RelDataType = rexBuilder
     .getTypeFactory
     .asInstanceOf[FlinkTypeFactory]
-    .createTypeFromInternalType(InternalTypes.TIMESTAMP, isNullable = isNullable)
+    .createFieldTypeFromLogicalType(new TimestampType(isNullable, 3))
 
   val materializerUtils = new RexTimeIndicatorMaterializerUtils(rexBuilder)
 
@@ -510,7 +510,7 @@ class RexTimeIndicatorMaterializer(
   private def timestamp(isNullable: Boolean): RelDataType = rexBuilder
     .getTypeFactory
     .asInstanceOf[FlinkTypeFactory]
-    .createTypeFromInternalType(InternalTypes.TIMESTAMP, isNullable = isNullable)
+    .createFieldTypeFromLogicalType(new TimestampType(isNullable, 3))
 
   override def visitInputRef(inputRef: RexInputRef): RexNode = {
     // reference is interesting
@@ -602,7 +602,7 @@ class RexTimeIndicatorMaterializerUtils(rexBuilder: RexBuilder) {
   private def timestamp(isNullable: Boolean): RelDataType = rexBuilder
     .getTypeFactory
     .asInstanceOf[FlinkTypeFactory]
-    .createTypeFromInternalType(InternalTypes.TIMESTAMP, isNullable = isNullable)
+    .createFieldTypeFromLogicalType(new TimestampType(isNullable, 3))
 
   def projectAndMaterializeFields(input: RelNode, indicesToMaterialize: Set[Int]): RelNode = {
     val projects = input.getRowType.getFieldList.map { field =>
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CalcCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CalcCodeGenerator.scala
index c93ecbb..2756038 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CalcCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CalcCodeGenerator.scala
@@ -18,14 +18,16 @@
 package org.apache.flink.table.codegen
 
 import org.apache.flink.streaming.api.transformations.StreamTransformation
-import org.apache.flink.table.`type`.{RowType, TypeConverters}
 import org.apache.flink.table.api.{TableConfig, TableException}
 import org.apache.flink.table.dataformat.{BaseRow, BoxedWrapperRow}
 import org.apache.flink.table.runtime.CodeGenOperatorFactory
+import org.apache.flink.table.types.logical.RowType
+
 import org.apache.calcite.plan.RelOptCluster
 import org.apache.calcite.rex._
 import org.apache.flink.api.common.functions.{FlatMapFunction, Function}
 import org.apache.flink.table.generated.GeneratedFunction
+import org.apache.flink.table.typeutils.BaseRowTypeInfo
 
 import scala.collection.JavaConversions._
 
@@ -41,8 +43,7 @@ object CalcCodeGenerator {
       condition: Option[RexNode],
       retainHeader: Boolean = false,
       opName: String): CodeGenOperatorFactory[BaseRow] = {
-    val inputType = TypeConverters.createInternalTypeFromTypeInfo(
-      inputTransform.getOutputType).asInstanceOf[RowType]
+    val inputType = inputTransform.getOutputType.asInstanceOf[BaseRowTypeInfo].toRowType
     // filter out time attributes
     val inputTerm = CodeGenUtils.DEFAULT_INPUT1_TERM
     val processCode = generateProcessCode(
@@ -126,7 +127,7 @@ object CalcCodeGenerator {
     val exprGenerator = new ExprCodeGenerator(ctx, false)
         .bindInput(inputType, inputTerm = inputTerm)
 
-    val onlyFilter = projection.lengthCompare(inputType.getArity) == 0 &&
+    val onlyFilter = projection.lengthCompare(inputType.getFieldCount) == 0 &&
       projection.zipWithIndex.forall { case (rexNode, index) =>
         rexNode.isInstanceOf[RexInputRef] && rexNode.asInstanceOf[RexInputRef].getIndex == index
       }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CodeGenUtils.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CodeGenUtils.scala
index 7a13af4..ddac75a 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CodeGenUtils.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CodeGenUtils.scala
@@ -18,17 +18,20 @@
 
 package org.apache.flink.table.codegen
 
-import org.apache.flink.api.common.typeinfo.TypeInformation
+import org.apache.flink.api.common.ExecutionConfig
 import org.apache.flink.core.memory.MemorySegment
-import org.apache.flink.table.`type`.InternalTypeUtils.getInternalClassForType
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
-import org.apache.flink.table.`type`._
 import org.apache.flink.table.dataformat.DataFormatConverters.IdentityConverter
-import org.apache.flink.table.dataformat.{Decimal, _}
 import org.apache.flink.table.dataformat.util.BinaryRowUtil.BYTE_ARRAY_BASE_OFFSET
+import org.apache.flink.table.dataformat.{Decimal, _}
 import org.apache.flink.table.dataview.StateDataViewStore
 import org.apache.flink.table.functions.UserDefinedFunction
 import org.apache.flink.table.generated.{AggsHandleFunction, HashFunction, NamespaceAggsHandleFunction}
+import org.apache.flink.table.types.ClassLogicalTypeConverter.getInternalClassForType
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
+import org.apache.flink.table.types.PlannerTypeUtils.isInteroperable
+import org.apache.flink.table.types.logical.LogicalTypeRoot._
+import org.apache.flink.table.types.logical._
+import org.apache.flink.table.types.{ClassLogicalTypeConverter, DataType}
 import org.apache.flink.table.typeutils.TypeCheckUtils
 import org.apache.flink.table.util.MurmurHashUtil
 import org.apache.flink.types.Row
@@ -75,7 +78,7 @@ object CodeGenUtils {
 
   val GENERIC_ROW: String = className[GenericRow]
 
-  val DECIMAL: String = className[Decimal]
+  val DECIMAL_TERM: String = className[Decimal]
 
   val SEGMENT: String = className[MemorySegment]
 
@@ -110,68 +113,77 @@ object CodeGenUtils {
   // works, but for boxed types we need this:
   // Float a = 1.0f;
   // Byte b = (byte)(float) a;
-  def primitiveTypeTermForType(t: InternalType): String = t match {
-    case InternalTypes.INT => "int"
-    case InternalTypes.LONG => "long"
-    case InternalTypes.SHORT => "short"
-    case InternalTypes.BYTE => "byte"
-    case InternalTypes.FLOAT => "float"
-    case InternalTypes.DOUBLE => "double"
-    case InternalTypes.BOOLEAN => "boolean"
-
-    case InternalTypes.DATE => "int"
-    case InternalTypes.TIME => "int"
-    case _: TimestampType => "long"
-
-    case InternalTypes.INTERVAL_MONTHS => "int"
-    case InternalTypes.INTERVAL_MILLIS => "long"
+  def primitiveTypeTermForType(t: LogicalType): String = t.getTypeRoot match {
+    case INTEGER => "int"
+    case BIGINT => "long"
+    case SMALLINT => "short"
+    case TINYINT => "byte"
+    case FLOAT => "float"
+    case DOUBLE => "double"
+    case BOOLEAN => "boolean"
+
+    case DATE => "int"
+    case TIME_WITHOUT_TIME_ZONE => "int"
+    case TIMESTAMP_WITHOUT_TIME_ZONE => "long"
+    case INTERVAL_YEAR_MONTH => "int"
+    case INTERVAL_DAY_TIME => "long"
 
     case _ => boxedTypeTermForType(t)
   }
 
-  def boxedTypeTermForType(t: InternalType): String = t match {
-    case InternalTypes.INT => className[JInt]
-    case InternalTypes.LONG => className[JLong]
-    case InternalTypes.SHORT => className[JShort]
-    case InternalTypes.BYTE => className[JByte]
-    case InternalTypes.FLOAT => className[JFloat]
-    case InternalTypes.DOUBLE => className[JDouble]
-    case InternalTypes.BOOLEAN => className[JBoolean]
-
-    case InternalTypes.DATE => boxedTypeTermForType(InternalTypes.INT)
-    case InternalTypes.TIME => boxedTypeTermForType(InternalTypes.INT)
-    case _: TimestampType => boxedTypeTermForType(InternalTypes.LONG)
-
-    case InternalTypes.STRING => BINARY_STRING
-    case InternalTypes.BINARY => "byte[]"
-
-    case _: DecimalType => className[Decimal]
-    case _: ArrayType => className[BinaryArray]
-    case _: MapType => className[BinaryMap]
-    case _: RowType => className[BaseRow]
-
-    case _: GenericType[_] => className[BinaryGeneric[_]]
+  def boxedTypeTermForType(t: LogicalType): String = t.getTypeRoot match {
+    case INTEGER => className[JInt]
+    case BIGINT => className[JLong]
+    case SMALLINT => className[JShort]
+    case TINYINT => className[JByte]
+    case FLOAT => className[JFloat]
+    case DOUBLE => className[JDouble]
+    case BOOLEAN => className[JBoolean]
+
+    case DATE => className[JInt]
+    case TIME_WITHOUT_TIME_ZONE => className[JInt]
+    case TIMESTAMP_WITHOUT_TIME_ZONE => className[JLong]
+    case INTERVAL_YEAR_MONTH => className[JInt]
+    case INTERVAL_DAY_TIME => className[JLong]
+
+    case VARCHAR => BINARY_STRING
+    case VARBINARY => "byte[]"
+
+    case DECIMAL => className[Decimal]
+    case ARRAY => className[BinaryArray]
+    case MULTISET | MAP => className[BinaryMap]
+    case ROW => className[BaseRow]
+
+    case ANY => className[BinaryGeneric[_]]
   }
 
   /**
     * Gets the boxed type term from external type info.
     * We only use TypeInformation to store external type info.
     */
-  def boxedTypeTermForExternalType(t: TypeInformation[_]): String = t.getTypeClass.getCanonicalName
+  def boxedTypeTermForExternalType(t: DataType): String = {
+    if (t.getConversionClass == null) {
+      ClassLogicalTypeConverter.getDefaultExternalClassForType(t.getLogicalType).getCanonicalName
+    } else {
+      t.getConversionClass.getCanonicalName
+    }
+  }
 
   /**
     * Gets the default value for a primitive type, and null for generic types
     */
-  def primitiveDefaultValue(t: InternalType): String = t match {
-    case InternalTypes.INT | InternalTypes.BYTE | InternalTypes.SHORT => "-1"
-    case InternalTypes.LONG => "-1L"
-    case InternalTypes.FLOAT => "-1.0f"
-    case InternalTypes.DOUBLE => "-1.0d"
-    case InternalTypes.BOOLEAN => "false"
-    case InternalTypes.STRING => s"$BINARY_STRING.EMPTY_UTF8"
-
-    case _: DateType | InternalTypes.TIME => "-1"
-    case _: TimestampType => "-1L"
+  def primitiveDefaultValue(t: LogicalType): String = t.getTypeRoot match {
+    case INTEGER | TINYINT | SMALLINT => "-1"
+    case BIGINT => "-1L"
+    case FLOAT => "-1.0f"
+    case DOUBLE => "-1.0d"
+    case BOOLEAN => "false"
+    case VARCHAR => s"$BINARY_STRING.EMPTY_UTF8"
+
+    case DATE | TIME_WITHOUT_TIME_ZONE => "-1"
+    case TIMESTAMP_WITHOUT_TIME_ZONE => "-1L"
+    case INTERVAL_YEAR_MONTH => "-1"
+    case INTERVAL_DAY_TIME => "-1L"
 
     case _ => "null"
   }
@@ -180,38 +192,44 @@ object CodeGenUtils {
     * If it's internally compatible, don't need to DataStructure converter.
     * clazz != classOf[Row] => Row can only infer GenericType[Row].
     */
-  def isInternalClass(clazz: Class[_], t: TypeInformation[_]): Boolean =
+  def isInternalClass(clazz: Class[_], t: DataType): Boolean =
     clazz != classOf[Object] && clazz != classOf[Row] &&
       (classOf[BaseRow].isAssignableFrom(clazz) ||
-          clazz == getInternalClassForType(createInternalTypeFromTypeInfo(t)))
-
-  def hashCodeForType(ctx: CodeGeneratorContext, t: InternalType, term: String): String = t match {
-    case InternalTypes.BYTE => s"${className[JByte]}.hashCode($term)"
-    case InternalTypes.SHORT => s"${className[JShort]}.hashCode($term)"
-    case InternalTypes.INT => s"${className[JInt]}.hashCode($term)"
-    case InternalTypes.LONG => s"${className[JLong]}.hashCode($term)"
-    case InternalTypes.FLOAT => s"${className[JFloat]}.hashCode($term)"
-    case InternalTypes.DOUBLE => s"${className[JDouble]}.hashCode($term)"
-    case InternalTypes.STRING => s"$term.hashCode()"
-    case InternalTypes.BINARY => s"${className[MurmurHashUtil]}.hashUnsafeBytes(" +
+          clazz == getInternalClassForType(fromDataTypeToLogicalType(t)))
+
+  def hashCodeForType(
+      ctx: CodeGeneratorContext, t: LogicalType, term: String): String = t.getTypeRoot match {
+    case TINYINT => s"${className[JByte]}.hashCode($term)"
+    case SMALLINT => s"${className[JShort]}.hashCode($term)"
+    case INTEGER => s"${className[JInt]}.hashCode($term)"
+    case BIGINT => s"${className[JLong]}.hashCode($term)"
+    case FLOAT => s"${className[JFloat]}.hashCode($term)"
+    case DOUBLE => s"${className[JDouble]}.hashCode($term)"
+    case VARCHAR => s"$term.hashCode()"
+    case VARBINARY => s"${className[MurmurHashUtil]}.hashUnsafeBytes(" +
       s"$term, $BYTE_ARRAY_BASE_OFFSET, $term.length)"
-    case _: DecimalType => s"$term.hashCode()"
-    case _: DateType => s"${className[JInt]}.hashCode($term)"
-    case InternalTypes.TIME => s"${className[JInt]}.hashCode($term)"
-    case _: TimestampType => s"${className[JLong]}.hashCode($term)"
-    case _: ArrayType => throw new IllegalArgumentException(s"Not support type to hash: $t")
-    case rowType: RowType =>
+    case DECIMAL => s"$term.hashCode()"
+    case DATE => s"${className[JInt]}.hashCode($term)"
+    case TIME_WITHOUT_TIME_ZONE => s"${className[JInt]}.hashCode($term)"
+    case TIMESTAMP_WITHOUT_TIME_ZONE => s"${className[JLong]}.hashCode($term)"
+    case INTERVAL_YEAR_MONTH => s"${className[JInt]}.hashCode($term)"
+    case INTERVAL_DAY_TIME => s"${className[JLong]}.hashCode($term)"
+    case ARRAY => throw new IllegalArgumentException(s"Not support type to hash: $t")
+    case ROW =>
+      val rowType = t.asInstanceOf[RowType]
       val subCtx = CodeGeneratorContext(ctx.tableConfig)
       val genHash = HashCodeGenerator.generateRowHash(
-        subCtx, rowType, "SubHashRow", (0 until rowType.getArity).toArray)
+        subCtx, rowType, "SubHashRow", (0 until rowType.getFieldCount).toArray)
       ctx.addReusableInnerClass(genHash.getClassName, genHash.getCode)
       val refs = ctx.addReusableObject(subCtx.references.toArray, "subRefs")
       val hashFunc = newName("hashFunc")
       ctx.addReusableMember(s"${classOf[HashFunction].getCanonicalName} $hashFunc;")
       ctx.addReusableInitStatement(s"$hashFunc = new ${genHash.getClassName}($refs);")
       s"$hashFunc.hashCode($term)"
-    case gt: GenericType[_] =>
-      val serTerm = ctx.addReusableObject(gt.getSerializer, "serializer")
+    case ANY =>
+      val gt = t.asInstanceOf[TypeInformationAnyType[_]]
+      val serTerm = ctx.addReusableObject(
+        gt.getTypeInformation.createSerializer(new ExecutionConfig), "serializer")
       s"$BINARY_GENERIC.getJavaObjectFromBinaryGeneric($term, $serTerm).hashCode()"
   }
 
@@ -219,55 +237,60 @@ object CodeGenUtils {
 
   // Cast numeric type to another numeric type with larger range.
   // This function must be in sync with [[NumericOrDefaultReturnTypeInference]].
-  def getNumericCastedResultTerm(expr: GeneratedExpression, targetType: InternalType): String = {
-    (expr.resultType, targetType) match {
-      case _ if expr.resultType == targetType => expr.resultTerm
+  def getNumericCastedResultTerm(expr: GeneratedExpression, targetType: LogicalType): String = {
+    (expr.resultType.getTypeRoot, targetType.getTypeRoot) match {
+      case _ if isInteroperable(expr.resultType, targetType) => expr.resultTerm
 
       // byte -> other numeric types
-      case (_: ByteType, _: ShortType) => s"(short) ${expr.resultTerm}"
-      case (_: ByteType, _: IntType) => s"(int) ${expr.resultTerm}"
-      case (_: ByteType, _: LongType) => s"(long) ${expr.resultTerm}"
-      case (_: ByteType, dt: DecimalType) =>
+      case (TINYINT, SMALLINT) => s"(short) ${expr.resultTerm}"
+      case (TINYINT, INTEGER) => s"(int) ${expr.resultTerm}"
+      case (TINYINT, BIGINT) => s"(long) ${expr.resultTerm}"
+      case (TINYINT, DECIMAL) =>
+        val dt = targetType.asInstanceOf[DecimalType]
         s"${classOf[Decimal].getCanonicalName}.castFrom(" +
-          s"${expr.resultTerm}, ${dt.precision}, ${dt.scale})"
-      case (_: ByteType, _: FloatType) => s"(float) ${expr.resultTerm}"
-      case (_: ByteType, _: DoubleType) => s"(double) ${expr.resultTerm}"
+          s"${expr.resultTerm}, ${dt.getPrecision}, ${dt.getScale})"
+      case (TINYINT, FLOAT) => s"(float) ${expr.resultTerm}"
+      case (TINYINT, DOUBLE) => s"(double) ${expr.resultTerm}"
 
       // short -> other numeric types
-      case (_: ShortType, _: IntType) => s"(int) ${expr.resultTerm}"
-      case (_: ShortType, _: LongType) => s"(long) ${expr.resultTerm}"
-      case (_: ShortType, dt: DecimalType) =>
+      case (SMALLINT, INTEGER) => s"(int) ${expr.resultTerm}"
+      case (SMALLINT, BIGINT) => s"(long) ${expr.resultTerm}"
+      case (SMALLINT, DECIMAL) =>
+        val dt = targetType.asInstanceOf[DecimalType]
         s"${classOf[Decimal].getCanonicalName}.castFrom(" +
-          s"${expr.resultTerm}, ${dt.precision}, ${dt.scale})"
-      case (_: ShortType, _: FloatType) => s"(float) ${expr.resultTerm}"
-      case (_: ShortType, _: DoubleType) => s"(double) ${expr.resultTerm}"
+          s"${expr.resultTerm}, ${dt.getPrecision}, ${dt.getScale})"
+      case (SMALLINT, FLOAT) => s"(float) ${expr.resultTerm}"
+      case (SMALLINT, DOUBLE) => s"(double) ${expr.resultTerm}"
 
       // int -> other numeric types
-      case (_: IntType, _: LongType) => s"(long) ${expr.resultTerm}"
-      case (_: IntType, dt: DecimalType) =>
+      case (INTEGER, BIGINT) => s"(long) ${expr.resultTerm}"
+      case (INTEGER, DECIMAL) =>
+        val dt = targetType.asInstanceOf[DecimalType]
         s"${classOf[Decimal].getCanonicalName}.castFrom(" +
-          s"${expr.resultTerm}, ${dt.precision}, ${dt.scale})"
-      case (_: IntType, _: FloatType) => s"(float) ${expr.resultTerm}"
-      case (_: IntType, _: DoubleType) => s"(double) ${expr.resultTerm}"
+          s"${expr.resultTerm}, ${dt.getPrecision}, ${dt.getScale})"
+      case (INTEGER, FLOAT) => s"(float) ${expr.resultTerm}"
+      case (INTEGER, DOUBLE) => s"(double) ${expr.resultTerm}"
 
       // long -> other numeric types
-      case (_: LongType, dt: DecimalType) =>
+      case (BIGINT, DECIMAL) =>
+        val dt = targetType.asInstanceOf[DecimalType]
         s"${classOf[Decimal].getCanonicalName}.castFrom(" +
-          s"${expr.resultTerm}, ${dt.precision}, ${dt.scale})"
-      case (_: LongType, _: FloatType) => s"(float) ${expr.resultTerm}"
-      case (_: LongType, _: DoubleType) => s"(double) ${expr.resultTerm}"
+          s"${expr.resultTerm}, ${dt.getPrecision}, ${dt.getScale})"
+      case (BIGINT, FLOAT) => s"(float) ${expr.resultTerm}"
+      case (BIGINT, DOUBLE) => s"(double) ${expr.resultTerm}"
 
       // decimal -> other numeric types
-      case (_: DecimalType, dt: DecimalType) =>
+      case (DECIMAL, DECIMAL) =>
+        val dt = targetType.asInstanceOf[DecimalType]
         s"${classOf[Decimal].getCanonicalName}.castToDecimal(" +
-          s"${expr.resultTerm}, ${dt.precision}, ${dt.scale})"
-      case (_: DecimalType, _: FloatType) =>
+          s"${expr.resultTerm}, ${dt.getPrecision}, ${dt.getScale})"
+      case (DECIMAL, FLOAT) =>
         s"${classOf[Decimal].getCanonicalName}.castToFloat(${expr.resultTerm})"
-      case (_: DecimalType, _: DoubleType) =>
+      case (DECIMAL, DOUBLE) =>
         s"${classOf[Decimal].getCanonicalName}.castToDouble(${expr.resultTerm})"
 
       // float -> other numeric types
-      case (_: FloatType, _: DoubleType) => s"(double) ${expr.resultTerm}"
+      case (FLOAT, DOUBLE) => s"(double) ${expr.resultTerm}"
 
       case _ => null
     }
@@ -286,7 +309,8 @@ object CodeGenUtils {
   def getEnum(genExpr: GeneratedExpression): Enum[_] = {
     val split = genExpr.resultTerm.split('.')
     val value = split.last
-    val clazz = genExpr.resultType.asInstanceOf[GenericType[_]].getTypeClass
+    val clazz = genExpr.resultType.asInstanceOf[TypeInformationAnyType[_]]
+        .getTypeInformation.getTypeClass
     enumValueOf(clazz, value)
   }
 
@@ -307,7 +331,7 @@ object CodeGenUtils {
     }
 
   def requireString(genExpr: GeneratedExpression): Unit =
-    if (!TypeCheckUtils.isString(genExpr.resultType)) {
+    if (!TypeCheckUtils.isVarchar(genExpr.resultType)) {
       throw new CodeGenException("String expression type expected.")
     }
 
@@ -351,38 +375,42 @@ object CodeGenUtils {
       ctx: CodeGeneratorContext,
       index: Int,
       rowTerm: String,
-      fieldType: InternalType) : String =
+      fieldType: LogicalType) : String =
     baseRowFieldReadAccess(ctx, index.toString, rowTerm, fieldType)
 
   def baseRowFieldReadAccess(
       ctx: CodeGeneratorContext,
       indexTerm: String,
       rowTerm: String,
-      fieldType: InternalType) : String =
-    fieldType match {
+      t: LogicalType) : String =
+    t.getTypeRoot match {
       // primitive types
-      case InternalTypes.BOOLEAN => s"$rowTerm.getBoolean($indexTerm)"
-      case InternalTypes.BYTE => s"$rowTerm.getByte($indexTerm)"
-      case InternalTypes.SHORT => s"$rowTerm.getShort($indexTerm)"
-      case InternalTypes.INT => s"$rowTerm.getInt($indexTerm)"
-      case InternalTypes.LONG => s"$rowTerm.getLong($indexTerm)"
-      case InternalTypes.FLOAT => s"$rowTerm.getFloat($indexTerm)"
-      case InternalTypes.DOUBLE => s"$rowTerm.getDouble($indexTerm)"
-      case InternalTypes.STRING => s"$rowTerm.getString($indexTerm)"
-      case InternalTypes.BINARY => s"$rowTerm.getBinary($indexTerm)"
-      case dt: DecimalType => s"$rowTerm.getDecimal($indexTerm, ${dt.precision()}, ${dt.scale()})"
+      case BOOLEAN => s"$rowTerm.getBoolean($indexTerm)"
+      case TINYINT => s"$rowTerm.getByte($indexTerm)"
+      case SMALLINT => s"$rowTerm.getShort($indexTerm)"
+      case INTEGER => s"$rowTerm.getInt($indexTerm)"
+      case BIGINT => s"$rowTerm.getLong($indexTerm)"
+      case FLOAT => s"$rowTerm.getFloat($indexTerm)"
+      case DOUBLE => s"$rowTerm.getDouble($indexTerm)"
+      case VARCHAR => s"$rowTerm.getString($indexTerm)"
+      case VARBINARY => s"$rowTerm.getBinary($indexTerm)"
+      case DECIMAL =>
+        val dt = t.asInstanceOf[DecimalType]
+        s"$rowTerm.getDecimal($indexTerm, ${dt.getPrecision}, ${dt.getScale})"
 
       // temporal types
-      case _: DateType => s"$rowTerm.getInt($indexTerm)"
-      case InternalTypes.TIME => s"$rowTerm.getInt($indexTerm)"
-      case _: TimestampType => s"$rowTerm.getLong($indexTerm)"
+      case DATE => s"$rowTerm.getInt($indexTerm)"
+      case TIME_WITHOUT_TIME_ZONE => s"$rowTerm.getInt($indexTerm)"
+      case TIMESTAMP_WITHOUT_TIME_ZONE => s"$rowTerm.getLong($indexTerm)"
+      case INTERVAL_YEAR_MONTH => s"$rowTerm.getInt($indexTerm)"
+      case INTERVAL_DAY_TIME => s"$rowTerm.getLong($indexTerm)"
 
       // complex types
-      case _: ArrayType => s"$rowTerm.getArray($indexTerm)"
-      case _: MapType  => s"$rowTerm.getMap($indexTerm)"
-      case rt: RowType => s"$rowTerm.getRow($indexTerm, ${rt.getArity})"
+      case ARRAY => s"$rowTerm.getArray($indexTerm)"
+      case MULTISET | MAP  => s"$rowTerm.getMap($indexTerm)"
+      case ROW => s"$rowTerm.getRow($indexTerm, ${t.asInstanceOf[RowType].getFieldCount})"
 
-      case _: GenericType[_] => s"$rowTerm.getGeneric($indexTerm)"
+      case ANY => s"$rowTerm.getGeneric($indexTerm)"
     }
 
   // -------------------------- BaseRow Set Field -------------------------------
@@ -466,43 +494,46 @@ object CodeGenUtils {
 
   // -------------------------- BinaryRow Set Field -------------------------------
 
-  def binaryRowSetNull(index: Int, rowTerm: String, t: InternalType): String =
+  def binaryRowSetNull(index: Int, rowTerm: String, t: LogicalType): String =
     binaryRowSetNull(index.toString, rowTerm, t)
 
-  def binaryRowSetNull(indexTerm: String, rowTerm: String, t: InternalType): String = t match {
-    case d: DecimalType if !Decimal.isCompact(d.precision()) =>
-      s"$rowTerm.setDecimal($indexTerm, null, ${d.precision()})"
+  def binaryRowSetNull(indexTerm: String, rowTerm: String, t: LogicalType): String = t match {
+    case d: DecimalType if !Decimal.isCompact(d.getPrecision) =>
+      s"$rowTerm.setDecimal($indexTerm, null, ${d.getPrecision})"
     case _ => s"$rowTerm.setNullAt($indexTerm)"
   }
 
   def binaryRowFieldSetAccess(
       index: Int,
       binaryRowTerm: String,
-      fieldType: InternalType,
+      fieldType: LogicalType,
       fieldValTerm: String): String =
     binaryRowFieldSetAccess(index.toString, binaryRowTerm, fieldType, fieldValTerm)
 
   def binaryRowFieldSetAccess(
       index: String,
       binaryRowTerm: String,
-      fieldType: InternalType,
+      t: LogicalType,
       fieldValTerm: String): String =
-    fieldType match {
-      case InternalTypes.INT => s"$binaryRowTerm.setInt($index, $fieldValTerm)"
-      case InternalTypes.LONG => s"$binaryRowTerm.setLong($index, $fieldValTerm)"
-      case InternalTypes.SHORT => s"$binaryRowTerm.setShort($index, $fieldValTerm)"
-      case InternalTypes.BYTE => s"$binaryRowTerm.setByte($index, $fieldValTerm)"
-      case InternalTypes.FLOAT => s"$binaryRowTerm.setFloat($index, $fieldValTerm)"
-      case InternalTypes.DOUBLE => s"$binaryRowTerm.setDouble($index, $fieldValTerm)"
-      case InternalTypes.BOOLEAN => s"$binaryRowTerm.setBoolean($index, $fieldValTerm)"
-      case _: DateType =>  s"$binaryRowTerm.setInt($index, $fieldValTerm)"
-      case InternalTypes.TIME =>  s"$binaryRowTerm.setInt($index, $fieldValTerm)"
-      case _: TimestampType =>  s"$binaryRowTerm.setLong($index, $fieldValTerm)"
-      case d: DecimalType =>
-        s"$binaryRowTerm.setDecimal($index, $fieldValTerm, ${d.precision()})"
+    t.getTypeRoot match {
+      case INTEGER => s"$binaryRowTerm.setInt($index, $fieldValTerm)"
+      case BIGINT => s"$binaryRowTerm.setLong($index, $fieldValTerm)"
+      case SMALLINT => s"$binaryRowTerm.setShort($index, $fieldValTerm)"
+      case TINYINT => s"$binaryRowTerm.setByte($index, $fieldValTerm)"
+      case FLOAT => s"$binaryRowTerm.setFloat($index, $fieldValTerm)"
+      case DOUBLE => s"$binaryRowTerm.setDouble($index, $fieldValTerm)"
+      case BOOLEAN => s"$binaryRowTerm.setBoolean($index, $fieldValTerm)"
+      case DATE =>  s"$binaryRowTerm.setInt($index, $fieldValTerm)"
+      case TIME_WITHOUT_TIME_ZONE =>  s"$binaryRowTerm.setInt($index, $fieldValTerm)"
+      case TIMESTAMP_WITHOUT_TIME_ZONE =>  s"$binaryRowTerm.setLong($index, $fieldValTerm)"
+      case INTERVAL_YEAR_MONTH =>  s"$binaryRowTerm.setInt($index, $fieldValTerm)"
+      case INTERVAL_DAY_TIME =>  s"$binaryRowTerm.setLong($index, $fieldValTerm)"
+      case DECIMAL =>
+        val dt = t.asInstanceOf[DecimalType]
+        s"$binaryRowTerm.setDecimal($index, $fieldValTerm, ${dt.getPrecision})"
       case _ =>
-        throw new CodeGenException("Fail to find binary row field setter method of InternalType "
-          + fieldType + ".")
+        throw new CodeGenException("Fail to find binary row field setter method of LogicalType "
+          + t + ".")
     }
 
   // -------------------------- BoxedWrapperRow Set Field -------------------------------
@@ -511,18 +542,20 @@ object CodeGenUtils {
       rowTerm: String,
       indexTerm: String,
       fieldTerm: String,
-      fieldType: InternalType): String =
-    fieldType match {
-      case InternalTypes.INT => s"$rowTerm.setInt($indexTerm, $fieldTerm)"
-      case InternalTypes.LONG => s"$rowTerm.setLong($indexTerm, $fieldTerm)"
-      case InternalTypes.SHORT => s"$rowTerm.setShort($indexTerm, $fieldTerm)"
-      case InternalTypes.BYTE => s"$rowTerm.setByte($indexTerm, $fieldTerm)"
-      case InternalTypes.FLOAT => s"$rowTerm.setFloat($indexTerm, $fieldTerm)"
-      case InternalTypes.DOUBLE => s"$rowTerm.setDouble($indexTerm, $fieldTerm)"
-      case InternalTypes.BOOLEAN => s"$rowTerm.setBoolean($indexTerm, $fieldTerm)"
-      case _: DateType =>  s"$rowTerm.setInt($indexTerm, $fieldTerm)"
-      case InternalTypes.TIME =>  s"$rowTerm.setInt($indexTerm, $fieldTerm)"
-      case _: TimestampType =>  s"$rowTerm.setLong($indexTerm, $fieldTerm)"
+      t: LogicalType): String =
+    t.getTypeRoot match {
+      case INTEGER => s"$rowTerm.setInt($indexTerm, $fieldTerm)"
+      case BIGINT => s"$rowTerm.setLong($indexTerm, $fieldTerm)"
+      case SMALLINT => s"$rowTerm.setShort($indexTerm, $fieldTerm)"
+      case TINYINT => s"$rowTerm.setByte($indexTerm, $fieldTerm)"
+      case FLOAT => s"$rowTerm.setFloat($indexTerm, $fieldTerm)"
+      case DOUBLE => s"$rowTerm.setDouble($indexTerm, $fieldTerm)"
+      case BOOLEAN => s"$rowTerm.setBoolean($indexTerm, $fieldTerm)"
+      case DATE =>  s"$rowTerm.setInt($indexTerm, $fieldTerm)"
+      case TIME_WITHOUT_TIME_ZONE =>  s"$rowTerm.setInt($indexTerm, $fieldTerm)"
+      case TIMESTAMP_WITHOUT_TIME_ZONE =>  s"$rowTerm.setLong($indexTerm, $fieldTerm)"
+      case INTERVAL_YEAR_MONTH => s"$rowTerm.setInt($indexTerm, $fieldTerm)"
+      case INTERVAL_DAY_TIME => s"$rowTerm.setLong($indexTerm, $fieldTerm)"
       case _ => s"$rowTerm.setNonPrimitiveValue($indexTerm, $fieldTerm)"
     }
 
@@ -531,31 +564,33 @@ object CodeGenUtils {
   def binaryArraySetNull(
       index: Int,
       arrayTerm: String,
-      elementType: InternalType): String = elementType match {
-    case InternalTypes.BOOLEAN => s"$arrayTerm.setNullBoolean($index)"
-    case InternalTypes.BYTE => s"$arrayTerm.setNullByte($index)"
-    case InternalTypes.SHORT => s"$arrayTerm.setNullShort($index)"
-    case InternalTypes.INT => s"$arrayTerm.setNullInt($index)"
-    case InternalTypes.LONG => s"$arrayTerm.setNullLong($index)"
-    case InternalTypes.FLOAT => s"$arrayTerm.setNullFloat($index)"
-    case InternalTypes.DOUBLE => s"$arrayTerm.setNullDouble($index)"
-    case InternalTypes.TIME => s"$arrayTerm.setNullInt($index)"
-    case _: DateType => s"$arrayTerm.setNullInt($index)"
-    case _: TimestampType => s"$arrayTerm.setNullLong($index)"
+      t: LogicalType): String = t.getTypeRoot match {
+    case BOOLEAN => s"$arrayTerm.setNullBoolean($index)"
+    case TINYINT => s"$arrayTerm.setNullByte($index)"
+    case SMALLINT => s"$arrayTerm.setNullShort($index)"
+    case INTEGER => s"$arrayTerm.setNullInt($index)"
+    case BIGINT => s"$arrayTerm.setNullLong($index)"
+    case FLOAT => s"$arrayTerm.setNullFloat($index)"
+    case DOUBLE => s"$arrayTerm.setNullDouble($index)"
+    case TIME_WITHOUT_TIME_ZONE => s"$arrayTerm.setNullInt($index)"
+    case DATE => s"$arrayTerm.setNullInt($index)"
+    case TIMESTAMP_WITHOUT_TIME_ZONE => s"$arrayTerm.setNullLong($index)"
+    case INTERVAL_YEAR_MONTH => s"$arrayTerm.setNullInt($index)"
+    case INTERVAL_DAY_TIME => s"$arrayTerm.setNullLong($index)"
     case _ => s"$arrayTerm.setNullLong($index)"
   }
 
   // -------------------------- BinaryWriter Write -------------------------------
 
-  def binaryWriterWriteNull(index: Int, writerTerm: String, t: InternalType): String =
+  def binaryWriterWriteNull(index: Int, writerTerm: String, t: LogicalType): String =
     binaryWriterWriteNull(index.toString, writerTerm, t)
 
   def binaryWriterWriteNull(
       indexTerm: String,
       writerTerm: String,
-      t: InternalType): String = t match {
-    case d: DecimalType if !Decimal.isCompact(d.precision()) =>
-      s"$writerTerm.writeDecimal($indexTerm, null, ${d.precision()})"
+      t: LogicalType): String = t match {
+    case d: DecimalType if !Decimal.isCompact(d.getPrecision) =>
+      s"$writerTerm.writeDecimal($indexTerm, null, ${d.getPrecision})"
     case _ => s"$writerTerm.setNullAt($indexTerm)"
   }
 
@@ -564,7 +599,7 @@ object CodeGenUtils {
       index: Int,
       fieldValTerm: String,
       writerTerm: String,
-      fieldType: InternalType): String =
+      fieldType: LogicalType): String =
     binaryWriterWriteField(ctx, index.toString, fieldValTerm, writerTerm, fieldType)
 
   def binaryWriterWriteField(
@@ -572,48 +607,51 @@ object CodeGenUtils {
       indexTerm: String,
       fieldValTerm: String,
       writerTerm: String,
-      fieldType: InternalType): String =
-    fieldType match {
-      case InternalTypes.INT => s"$writerTerm.writeInt($indexTerm, $fieldValTerm)"
-      case InternalTypes.LONG => s"$writerTerm.writeLong($indexTerm, $fieldValTerm)"
-      case InternalTypes.SHORT => s"$writerTerm.writeShort($indexTerm, $fieldValTerm)"
-      case InternalTypes.BYTE => s"$writerTerm.writeByte($indexTerm, $fieldValTerm)"
-      case InternalTypes.FLOAT => s"$writerTerm.writeFloat($indexTerm, $fieldValTerm)"
-      case InternalTypes.DOUBLE => s"$writerTerm.writeDouble($indexTerm, $fieldValTerm)"
-      case InternalTypes.BOOLEAN => s"$writerTerm.writeBoolean($indexTerm, $fieldValTerm)"
-      case InternalTypes.BINARY => s"$writerTerm.writeBinary($indexTerm, $fieldValTerm)"
-      case InternalTypes.STRING => s"$writerTerm.writeString($indexTerm, $fieldValTerm)"
-      case d: DecimalType =>
-        s"$writerTerm.writeDecimal($indexTerm, $fieldValTerm, ${d.precision()})"
-      case _: DateType => s"$writerTerm.writeInt($indexTerm, $fieldValTerm)"
-      case InternalTypes.TIME => s"$writerTerm.writeInt($indexTerm, $fieldValTerm)"
-      case _: TimestampType => s"$writerTerm.writeLong($indexTerm, $fieldValTerm)"
+      t: LogicalType): String =
+    t.getTypeRoot match {
+      case INTEGER => s"$writerTerm.writeInt($indexTerm, $fieldValTerm)"
+      case BIGINT => s"$writerTerm.writeLong($indexTerm, $fieldValTerm)"
+      case SMALLINT => s"$writerTerm.writeShort($indexTerm, $fieldValTerm)"
+      case TINYINT => s"$writerTerm.writeByte($indexTerm, $fieldValTerm)"
+      case FLOAT => s"$writerTerm.writeFloat($indexTerm, $fieldValTerm)"
+      case DOUBLE => s"$writerTerm.writeDouble($indexTerm, $fieldValTerm)"
+      case BOOLEAN => s"$writerTerm.writeBoolean($indexTerm, $fieldValTerm)"
+      case VARBINARY => s"$writerTerm.writeBinary($indexTerm, $fieldValTerm)"
+      case VARCHAR => s"$writerTerm.writeString($indexTerm, $fieldValTerm)"
+      case DECIMAL =>
+        val dt = t.asInstanceOf[DecimalType]
+        s"$writerTerm.writeDecimal($indexTerm, $fieldValTerm, ${dt.getPrecision})"
+      case DATE => s"$writerTerm.writeInt($indexTerm, $fieldValTerm)"
+      case TIME_WITHOUT_TIME_ZONE => s"$writerTerm.writeInt($indexTerm, $fieldValTerm)"
+      case TIMESTAMP_WITHOUT_TIME_ZONE => s"$writerTerm.writeLong($indexTerm, $fieldValTerm)"
+      case INTERVAL_YEAR_MONTH => s"$writerTerm.writeInt($indexTerm, $fieldValTerm)"
+      case INTERVAL_DAY_TIME => s"$writerTerm.writeLong($indexTerm, $fieldValTerm)"
 
       // complex types
-      case _: ArrayType => s"$writerTerm.writeArray($indexTerm, $fieldValTerm)"
-      case _: MapType => s"$writerTerm.writeMap($indexTerm, $fieldValTerm)"
-      case _: RowType =>
-        val serializerTerm = ctx.addReusableTypeSerializer(fieldType)
-        s"$writerTerm.writeRow($indexTerm, $fieldValTerm, $serializerTerm)"
+      case ARRAY => s"$writerTerm.writeArray($indexTerm, $fieldValTerm)"
+      case MULTISET | MAP => s"$writerTerm.writeMap($indexTerm, $fieldValTerm)"
+      case ROW =>
+        val typeTerm = ctx.addReusableObject(t, "rowType")
+        s"$writerTerm.writeRow($indexTerm, $fieldValTerm, $typeTerm)"
 
-      case _: GenericType[_] => s"$writerTerm.writeGeneric($indexTerm, $fieldValTerm)"
+      case ANY => s"$writerTerm.writeGeneric($indexTerm, $fieldValTerm)"
     }
 
-  private def isConverterIdentity(t: TypeInformation[_]): Boolean = {
-    DataFormatConverters.getConverterForTypeInfo(t).isInstanceOf[IdentityConverter[_]]
+  private def isConverterIdentity(t: DataType): Boolean = {
+    DataFormatConverters.getConverterForDataType(t).isInstanceOf[IdentityConverter[_]]
   }
 
-  def genToInternal(ctx: CodeGeneratorContext, t: TypeInformation[_], term: String): String =
+  def genToInternal(ctx: CodeGeneratorContext, t: DataType, term: String): String =
     genToInternal(ctx, t)(term)
 
-  def genToInternal(ctx: CodeGeneratorContext, t: TypeInformation[_]): String => String = {
-    val iTerm = boxedTypeTermForType(createInternalTypeFromTypeInfo(t))
+  def genToInternal(ctx: CodeGeneratorContext, t: DataType): String => String = {
+    val iTerm = boxedTypeTermForType(fromDataTypeToLogicalType(t))
     if (isConverterIdentity(t)) {
       term => s"($iTerm) $term"
     } else {
       val eTerm = boxedTypeTermForExternalType(t)
       val converter = ctx.addReusableObject(
-        DataFormatConverters.getConverterForTypeInfo(t),
+        DataFormatConverters.getConverterForDataType(t),
         "converter")
       term => s"($iTerm) $converter.toInternal(($eTerm) $term)"
     }
@@ -621,24 +659,24 @@ object CodeGenUtils {
 
   def genToInternalIfNeeded(
       ctx: CodeGeneratorContext,
-      t: TypeInformation[_],
+      t: DataType,
       clazz: Class[_],
       term: String): String = {
     if (isInternalClass(clazz, t)) {
-      s"(${boxedTypeTermForType(createInternalTypeFromTypeInfo(t))}) $term"
+      s"(${boxedTypeTermForType(fromDataTypeToLogicalType(t))}) $term"
     } else {
       genToInternal(ctx, t, term)
     }
   }
 
-  def genToExternal(ctx: CodeGeneratorContext, t: TypeInformation[_], term: String): String = {
-    val iTerm = boxedTypeTermForType(createInternalTypeFromTypeInfo(t))
+  def genToExternal(ctx: CodeGeneratorContext, t: DataType, term: String): String = {
+    val iTerm = boxedTypeTermForType(fromDataTypeToLogicalType(t))
     if (isConverterIdentity(t)) {
       s"($iTerm) $term"
     } else {
       val eTerm = boxedTypeTermForExternalType(t)
       val converter = ctx.addReusableObject(
-        DataFormatConverters.getConverterForTypeInfo(t),
+        DataFormatConverters.getConverterForDataType(t),
         "converter")
       s"($eTerm) $converter.toExternal(($iTerm) $term)"
     }
@@ -646,11 +684,11 @@ object CodeGenUtils {
 
   def genToExternalIfNeeded(
       ctx: CodeGeneratorContext,
-      t: TypeInformation[_],
+      t: DataType,
       clazz: Class[_],
       term: String): String = {
     if (isInternalClass(clazz, t)) {
-      s"(${boxedTypeTermForType(createInternalTypeFromTypeInfo(t))}) $term"
+      s"(${boxedTypeTermForType(fromDataTypeToLogicalType(t))}) $term"
     } else {
       genToExternal(ctx, t, term)
     }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CodeGeneratorContext.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CodeGeneratorContext.scala
index 59cb2b3..cd66414 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CodeGeneratorContext.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CodeGeneratorContext.scala
@@ -21,7 +21,6 @@ package org.apache.flink.table.codegen
 import org.apache.flink.api.common.ExecutionConfig
 import org.apache.flink.api.common.functions.{Function, RuntimeContext}
 import org.apache.flink.api.common.typeutils.TypeSerializer
-import org.apache.flink.table.`type`.{InternalType, InternalTypes, RowType, TypeConverters}
 import org.apache.flink.table.api.TableConfig
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.GenerateUtils.generateRecordStatement
@@ -29,6 +28,9 @@ import org.apache.flink.table.dataformat.GenericRow
 import org.apache.flink.table.functions.{FunctionContext, UserDefinedFunction}
 import org.apache.flink.table.runtime.TableStreamOperator
 import org.apache.flink.table.runtime.util.collections._
+import org.apache.flink.table.types.InternalSerializers
+import org.apache.flink.table.types.logical.LogicalTypeRoot._
+import org.apache.flink.table.types.logical._
 import org.apache.flink.util.InstantiationUtil
 
 import org.apache.calcite.avatica.util.DateTimeUtils
@@ -99,9 +101,9 @@ class CodeGeneratorContext(val tableConfig: TableConfig) {
   private val reusableStringConstants: mutable.Map[String, String] = mutable.Map[String,  String]()
 
   // map of type serializer that will be added only once
-  // InternalType -> reused_term
-  private val reusableTypeSerializers: mutable.Map[InternalType, String] =
-    mutable.Map[InternalType,  String]()
+  // LogicalType -> reused_term
+  private val reusableTypeSerializers: mutable.Map[LogicalType, String] =
+    mutable.Map[LogicalType,  String]()
 
   /**
     * The current method name for [[reusableLocalVariableStatements]]. You can start a new
@@ -363,7 +365,7 @@ class CodeGeneratorContext(val tableConfig: TableConfig) {
     * Adds a reusable output record statement to member area.
     */
   def addReusableOutputRecord(
-      t: InternalType,
+      t: LogicalType,
       clazz: Class[_],
       outRecordTerm: String,
       outRecordWriterTerm: Option[String] = None): Unit = {
@@ -376,7 +378,7 @@ class CodeGeneratorContext(val tableConfig: TableConfig) {
     */
   def addReusableNullRow(rowTerm: String, arity: Int): Unit = {
     addReusableOutputRecord(
-      new RowType((0 until arity).map(_ => InternalTypes.INT): _*),
+      RowType.of((0 until arity).map(_ => new IntType()): _*),
       classOf[GenericRow],
       rowTerm)
   }
@@ -384,16 +386,16 @@ class CodeGeneratorContext(val tableConfig: TableConfig) {
   /**
     * Adds a reusable internal hash set to the member area of the generated class.
     */
-  def addReusableHashSet(elements: Seq[GeneratedExpression], elementType: InternalType): String = {
+  def addReusableHashSet(elements: Seq[GeneratedExpression], elementType: LogicalType): String = {
     val fieldTerm = newName("set")
 
-    val setTypeTerm = elementType match {
-      case InternalTypes.BYTE => className[ByteHashSet]
-      case InternalTypes.SHORT => className[ShortHashSet]
-      case InternalTypes.INT => className[IntHashSet]
-      case InternalTypes.LONG => className[LongHashSet]
-      case InternalTypes.FLOAT => className[FloatHashSet]
-      case InternalTypes.DOUBLE => className[DoubleHashSet]
+    val setTypeTerm = elementType.getTypeRoot match {
+      case TINYINT => className[ByteHashSet]
+      case SMALLINT => className[ShortHashSet]
+      case INTEGER => className[IntHashSet]
+      case BIGINT => className[LongHashSet]
+      case FLOAT => className[FloatHashSet]
+      case DOUBLE => className[DoubleHashSet]
       case _ => className[ObjectHashSet[_]]
     }
 
@@ -631,7 +633,7 @@ class CodeGeneratorContext(val tableConfig: TableConfig) {
     * @param t the internal type which used to generate internal type serializer
     * @return member variable term
     */
-  def addReusableTypeSerializer(t: InternalType): String = {
+  def addReusableTypeSerializer(t: LogicalType): String = {
     // if type serializer has been used before, we can reuse the code that
     // has already been generated
     reusableTypeSerializers.get(t) match {
@@ -639,8 +641,7 @@ class CodeGeneratorContext(val tableConfig: TableConfig) {
 
       case None =>
         val term = newName("typeSerializer")
-        val ser = TypeConverters.createInternalTypeInfoFromInternalType(t)
-          .createSerializer(new ExecutionConfig)
+        val ser = InternalSerializers.create(t, new ExecutionConfig)
         addReusableObjectInternal(ser, term, ser.getClass.getCanonicalName)
         reusableTypeSerializers(t) = term
         term
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CollectorCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CollectorCodeGenerator.scala
index 2beab0d..9b6e67a 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CollectorCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CollectorCodeGenerator.scala
@@ -18,11 +18,11 @@
 package org.apache.flink.table.codegen
 
 import org.apache.flink.configuration.Configuration
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.Indenter.toISC
 import org.apache.flink.table.generated.GeneratedCollector
 import org.apache.flink.table.runtime.collector.TableFunctionCollector
+import org.apache.flink.table.types.logical.LogicalType
 
 /**
   * A code generator for generating [[org.apache.flink.util.Collector]]s.
@@ -46,8 +46,8 @@ object CollectorCodeGenerator {
       ctx: CodeGeneratorContext,
       name: String,
       bodyCode: String,
-      inputType: InternalType,
-      collectedType: InternalType,
+      inputType: LogicalType,
+      collectedType: LogicalType,
       inputTerm: String = CodeGenUtils.DEFAULT_INPUT1_TERM,
       collectedTerm: String = CodeGenUtils.DEFAULT_INPUT2_TERM,
       converter: String => String = (a) => a): GeneratedCollector[TableFunctionCollector[_]] = {
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CorrelateCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CorrelateCodeGenerator.scala
index 9f2ba27..d0f778c 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CorrelateCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/CorrelateCodeGenerator.scala
@@ -22,12 +22,9 @@ import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.rex._
 import org.apache.calcite.sql.SemiJoinType
 import org.apache.flink.api.common.functions.Function
-import org.apache.flink.api.common.typeinfo.TypeInformation
 import org.apache.flink.configuration.Configuration
 import org.apache.flink.streaming.api.functions.ProcessFunction
 import org.apache.flink.streaming.api.transformations.{OneInputTransformation, StreamTransformation}
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
-import org.apache.flink.table.`type`.{InternalType, InternalTypeUtils, RowType}
 import org.apache.flink.table.api.{TableConfig, TableEnvironment, TableException}
 import org.apache.flink.table.calcite.FlinkTypeFactory
 import org.apache.flink.table.codegen.CodeGenUtils._
@@ -41,6 +38,10 @@ import org.apache.flink.table.plan.util.RelExplainUtil
 import org.apache.flink.table.runtime.CodeGenOperatorFactory
 import org.apache.flink.table.runtime.collector.TableFunctionCollector
 import org.apache.flink.table.runtime.util.StreamRecordCollector
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
+import org.apache.flink.table.types.{DataType, PlannerTypeUtils}
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
+import org.apache.flink.table.typeutils.BaseRowTypeInfo
 
 import scala.collection.JavaConversions._
 
@@ -70,13 +71,13 @@ object CorrelateCodeGenerator {
       sqlFunction.getTableFunction,
       rexCall.operands
         .map(_.getType)
-        .map(FlinkTypeFactory.toInternalType).toArray)
+        .map(FlinkTypeFactory.toLogicalType).toArray)
     val udtfExternalType = sqlFunction
         .getFunction
         .asInstanceOf[FlinkTableFunction]
         .getExternalResultType(arguments, argTypes)
     val pojoFieldMapping = Some(UserDefinedFunctionUtils.getFieldInfo(udtfExternalType)._2)
-    val inputType = FlinkTypeFactory.toInternalRowType(inputRelType)
+    val inputType = FlinkTypeFactory.toLogicalRowType(inputRelType)
     val (returnType, swallowInputOnly ) = if (projectProgram.isDefined) {
       val program = projectProgram.get
       val selects = program.getProjectList.map(_.getIndex)
@@ -84,10 +85,10 @@ object CorrelateCodeGenerator {
       val swallowInputOnly = selects.head > inputFieldCnt &&
         (inputFieldCnt - outDataType.getFieldCount == inputRelType.getFieldCount)
       // partial output or output right only
-      (FlinkTypeFactory.toInternalRowType(outDataType), swallowInputOnly)
+      (FlinkTypeFactory.toLogicalRowType(outDataType), swallowInputOnly)
     } else {
       // completely output left input + right
-      (FlinkTypeFactory.toInternalRowType(outDataType), false)
+      (FlinkTypeFactory.toLogicalRowType(outDataType), false)
     }
     // adjust indicies of InputRefs to adhere to schema expected by generator
     val changeInputRefIndexShuttle = new RexShuttle {
@@ -116,7 +117,7 @@ object CorrelateCodeGenerator {
       inputType,
       projectProgram,
       swallowInputOnly,
-      createInternalTypeFromTypeInfo(udtfExternalType),
+      fromDataTypeToLogicalType(udtfExternalType),
       returnType,
       joinType,
       rexCall,
@@ -135,7 +136,7 @@ object CorrelateCodeGenerator {
         outDataType,
         expression),
       substituteStreamOperator,
-      returnType.toTypeInfo,
+      BaseRowTypeInfo.of(returnType),
       parallelism)
   }
 
@@ -149,7 +150,7 @@ object CorrelateCodeGenerator {
       inputType: RowType,
       projectProgram: Option[RexProgram],
       swallowInputOnly: Boolean = false,
-      udtfType: InternalType,
+      udtfType: LogicalType,
       returnType: RowType,
       joinType: SemiJoinType,
       rexCall: RexCall,
@@ -195,8 +196,8 @@ object CorrelateCodeGenerator {
         // and the returned row table function is empty, collect a null
         val nullRowTerm = CodeGenUtils.newName("nullRow")
         ctx.addReusableOutputRecord(
-          InternalTypeUtils.toRowType(udtfType), classOf[GenericRow], nullRowTerm)
-        ctx.addReusableNullRow(nullRowTerm, InternalTypeUtils.getArity(udtfType))
+          PlannerTypeUtils.toRowType(udtfType), classOf[GenericRow], nullRowTerm)
+        ctx.addReusableNullRow(nullRowTerm, PlannerTypeUtils.getArity(udtfType))
         val header = if (retainHeader) {
           s"$nullRowTerm.setHeader(${exprGenerator.input1Term}.getHeader());"
         } else {
@@ -248,7 +249,7 @@ object CorrelateCodeGenerator {
         val joinedRowTerm = CodeGenUtils.newName("joinedRow")
         val nullRowTerm = CodeGenUtils.newName("nullRow")
         ctx.addReusableOutputRecord(returnType, classOf[JoinedRow], joinedRowTerm)
-        ctx.addReusableNullRow(nullRowTerm, InternalTypeUtils.getArity(udtfType))
+        ctx.addReusableNullRow(nullRowTerm, PlannerTypeUtils.getArity(udtfType))
         val header = if (retainHeader) {
           s"$joinedRowTerm.setHeader(${exprGenerator.input1Term}.getHeader());"
         } else {
@@ -283,7 +284,7 @@ object CorrelateCodeGenerator {
       ctx: CodeGeneratorContext,
       config: TableConfig,
       input1Type: RowType,
-      udtfType: InternalType,
+      udtfType: LogicalType,
       udtfPojoFieldMapping: Option[Array[Int]],
       udtfAlwaysNull: Boolean,
       returnType: RowType,
@@ -293,10 +294,10 @@ object CorrelateCodeGenerator {
       .bindInput(input1Type, CodeGenUtils.DEFAULT_INPUT1_TERM)
     if (udtfAlwaysNull) {
       val udtfNullRow = CodeGenUtils.newName("udtfNullRow")
-      ctx.addReusableNullRow(udtfNullRow, InternalTypeUtils.getArity(udtfType))
+      ctx.addReusableNullRow(udtfNullRow, PlannerTypeUtils.getArity(udtfType))
 
       projectExprGenerator.bindSecondInput(
-        InternalTypeUtils.toRowType(udtfType),
+        PlannerTypeUtils.toRowType(udtfType),
         udtfNullRow,
         inputFieldMapping = udtfPojoFieldMapping)
     } else {
@@ -319,7 +320,7 @@ object CorrelateCodeGenerator {
       inputType: RowType,
       projectProgram: Option[RexProgram],
       swallowInputOnly: Boolean,
-      udtfExternalType: TypeInformation[_],
+      udtfExternalType: DataType,
       resultType: RowType,
       condition: Option[RexNode],
       pojoFieldMapping: Option[Array[Int]],
@@ -327,11 +328,11 @@ object CorrelateCodeGenerator {
     val inputTerm = CodeGenUtils.DEFAULT_INPUT1_TERM
     val udtfInputTerm = CodeGenUtils.DEFAULT_INPUT2_TERM
 
-    val udtfType = createInternalTypeFromTypeInfo(udtfExternalType)
+    val udtfType = fromDataTypeToLogicalType(udtfExternalType)
     val exprGenerator = new ExprCodeGenerator(ctx, false).bindInput(
       udtfType, inputTerm = udtfInputTerm, inputFieldMapping = pojoFieldMapping)
 
-    val udtfBaseRowType = InternalTypeUtils.toRowType(udtfType)
+    val udtfBaseRowType = PlannerTypeUtils.toRowType(udtfType)
     val udtfResultExpr = exprGenerator.generateConverterResultExpression(
       udtfBaseRowType, classOf[GenericRow])
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/EqualiserCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/EqualiserCodeGenerator.scala
index 0965866..5c1f43f 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/EqualiserCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/EqualiserCodeGenerator.scala
@@ -21,10 +21,13 @@ import org.apache.flink.table.api.TableConfig
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.Indenter.toISC
 import org.apache.flink.table.generated.{GeneratedRecordEqualiser, RecordEqualiser}
-import org.apache.flink.table.`type`.{DateType, InternalType, PrimitiveType, RowType, TimeType,
-TimestampType}
+import org.apache.flink.table.types.PlannerTypeUtils
+import org.apache.flink.table.types.logical.LogicalTypeRoot._
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
 
-class EqualiserCodeGenerator(fieldTypes: Seq[InternalType]) {
+import scala.collection.JavaConversions._
+
+class EqualiserCodeGenerator(fieldTypes: Seq[LogicalType]) {
 
   private val RECORD_EQUALISER = className[RecordEqualiser]
   private val LEFT_INPUT = "left"
@@ -53,7 +56,7 @@ class EqualiserCodeGenerator(fieldTypes: Seq[InternalType]) {
         s"$leftFieldTerm == $rightFieldTerm"
       } else if (isBaseRow(fieldType)) {
         val equaliserGenerator =
-          new EqualiserCodeGenerator(fieldType.asInstanceOf[RowType].getFieldTypes)
+          new EqualiserCodeGenerator(fieldType.asInstanceOf[RowType].getChildren)
         val generatedEqualiser = equaliserGenerator
           .generateRecordEqualiser("field$" + i + "GeneratedEqualiser")
         val generatedEqualiserTerm = ctx.addReusableObject(
@@ -129,17 +132,19 @@ class EqualiserCodeGenerator(fieldTypes: Seq[InternalType]) {
     new GeneratedRecordEqualiser(className, functionCode, ctx.references.toArray)
   }
 
-  private def isInternalPrimitive(t: InternalType): Boolean = t match {
-    case _: PrimitiveType => true
+  private def isInternalPrimitive(t: LogicalType): Boolean = t.getTypeRoot match {
+    case _ if PlannerTypeUtils.isPrimitive(t) => true
 
-    case _: DateType => true
-    case TimeType.INSTANCE => true
-    case _: TimestampType => true
+    case DATE => true
+    case TIME_WITHOUT_TIME_ZONE => true
+    case TIMESTAMP_WITHOUT_TIME_ZONE => true
+    case INTERVAL_YEAR_MONTH => true
+    case INTERVAL_DAY_TIME => true
 
     case _ => false
   }
 
-  private def isBaseRow(t: InternalType): Boolean = t match {
+  private def isBaseRow(t: LogicalType): Boolean = t match {
     case _: RowType => true
     case _ => false
   }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExpandCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExpandCodeGenerator.scala
index 7cd8ee5..9b2cdba 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExpandCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExpandCodeGenerator.scala
@@ -18,10 +18,10 @@
 
 package org.apache.flink.table.codegen
 
-import org.apache.flink.table.`type`.RowType
 import org.apache.flink.table.api.TableConfig
 import org.apache.flink.table.dataformat.{BaseRow, BoxedWrapperRow}
 import org.apache.flink.table.runtime.CodeGenOperatorFactory
+import org.apache.flink.table.types.logical.RowType
 
 import org.apache.calcite.rex.RexNode
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExprCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExprCodeGenerator.scala
index 960479e..16d0f54 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExprCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExprCodeGenerator.scala
@@ -22,7 +22,6 @@ import org.apache.calcite.rex._
 import org.apache.calcite.sql.SqlOperator
 import org.apache.calcite.sql.`type`.{ReturnTypes, SqlTypeName}
 import org.apache.flink.streaming.api.functions.ProcessFunction
-import org.apache.flink.table.`type`._
 import org.apache.flink.table.api.TableException
 import org.apache.flink.table.calcite.{FlinkTypeFactory, RexAggLocalVariable, RexDistinctKeyVariable}
 import org.apache.flink.table.codegen.CodeGenUtils.{requireTemporal, requireTimeInterval, _}
@@ -33,6 +32,9 @@ import org.apache.flink.table.codegen.calls.ScalarOperatorGens._
 import org.apache.flink.table.dataformat._
 import org.apache.flink.table.functions.sql.FlinkSqlOperatorTable._
 import org.apache.flink.table.functions.utils.{ScalarSqlFunction, TableSqlFunction}
+import org.apache.flink.table.types.PlannerTypeUtils.isInteroperable
+import org.apache.flink.table.types.logical.LogicalTypeRoot.{VARBINARY, VARCHAR}
+import org.apache.flink.table.types.logical._
 import org.apache.flink.table.typeutils.TypeCheckUtils.{isNumeric, isTemporal, isTimeInterval}
 import org.apache.flink.table.typeutils.{TimeIndicatorTypeInfo, TypeCheckUtils}
 
@@ -58,14 +60,14 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
   /**
     * information of the first input
     */
-  var input1Type: InternalType = _
+  var input1Type: LogicalType = _
   var input1Term: String = _
   var input1FieldMapping: Option[Array[Int]] = None
 
   /**
     * information of the optional second input
     */
-  var input2Type: Option[InternalType] = None
+  var input2Type: Option[LogicalType] = None
   var input2Term: Option[String] = None
   var input2FieldMapping: Option[Array[Int]] = None
 
@@ -73,7 +75,7 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
     * Bind the input information, should be called before generating expression.
     */
   def bindInput(
-      inputType: InternalType,
+      inputType: LogicalType,
       inputTerm: String = DEFAULT_INPUT1_TERM,
       inputFieldMapping: Option[Array[Int]] = None): ExprCodeGenerator = {
     input1Type = inputType
@@ -87,7 +89,7 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
     * bind second input information before use.
     */
   def bindSecondInput(
-      inputType: InternalType,
+      inputType: LogicalType,
       inputTerm: String = DEFAULT_INPUT2_TERM,
       inputFieldMapping: Option[Array[Int]] = None): ExprCodeGenerator = {
     input2Type = Some(inputType)
@@ -109,8 +111,8 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
     }
   }
   
-  private def fieldIndices(t: InternalType): Array[Int] = t match {
-    case rt: RowType => (0 until rt.getArity).toArray
+  private def fieldIndices(t: LogicalType): Array[Int] = t match {
+    case rt: RowType => (0 until rt.getFieldCount).toArray
     case _ => Array(0)
   }
  
@@ -158,7 +160,9 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
       case TimeIndicatorTypeInfo.PROCTIME_STREAM_MARKER =>
         // attribute is proctime indicator.
         // we use a null literal and generate a timestamp when we need it.
-        generateNullLiteral(InternalTypes.PROCTIME_INDICATOR, ctx.nullCheck)
+        generateNullLiteral(
+          new TimestampType(true, TimestampKind.PROCTIME, 3),
+          ctx.nullCheck)
       case TimeIndicatorTypeInfo.PROCTIME_BATCH_MARKER =>
         // attribute is proctime field in a batch query.
         // it is initialized with the current time.
@@ -248,29 +252,29 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
     outRowAlreadyExists: Boolean)
   : GeneratedExpression = {
     // initial type check
-    if (returnType.getArity != fieldExprs.length) {
+    if (returnType.getFieldCount != fieldExprs.length) {
       throw new CodeGenException(
-        s"Arity [${returnType.getArity}] of result type [$returnType] does not match " +
+        s"Arity [${returnType.getFieldCount}] of result type [$returnType] does not match " +
           s"number [${fieldExprs.length}] of expressions [$fieldExprs].")
     }
     if (fieldExprIdxToOutputRowPosMap.size != fieldExprs.length) {
       throw new CodeGenException(
-        s"Size [${returnType.getArity}] of fieldExprIdxToOutputRowPosMap does not match " +
+        s"Size [${returnType.getFieldCount}] of fieldExprIdxToOutputRowPosMap does not match " +
           s"number [${fieldExprs.length}] of expressions [$fieldExprs].")
     }
     // type check
     fieldExprs.zipWithIndex foreach {
       // timestamp type(Include TimeIndicator) and generic type can compatible with each other.
       case (fieldExpr, i)
-        if fieldExpr.resultType.isInstanceOf[GenericType[_]] ||
+        if fieldExpr.resultType.isInstanceOf[TypeInformationAnyType[_]] ||
           fieldExpr.resultType.isInstanceOf[TimestampType] =>
         if (returnType.getTypeAt(i).getClass != fieldExpr.resultType.getClass
-          && !returnType.getTypeAt(i).isInstanceOf[GenericType[_]]) {
+          && !returnType.getTypeAt(i).isInstanceOf[TypeInformationAnyType[_]]) {
           throw new CodeGenException(
             s"Incompatible types of expression and result type, Expression[$fieldExpr] type is " +
               s"[${fieldExpr.resultType}], result type is [${returnType.getTypeAt(i)}]")
         }
-      case (fieldExpr, i) if fieldExpr.resultType != returnType.getTypeAt(i) =>
+      case (fieldExpr, i) if !isInteroperable(fieldExpr.resultType, returnType.getTypeAt(i)) =>
         throw new CodeGenException(
           s"Incompatible types of expression and result type. Expression[$fieldExpr] type is " +
             s"[${fieldExpr.resultType}], result type is [${returnType.getTypeAt(i)}]")
@@ -315,8 +319,12 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
   }
 
   override def visitInputRef(inputRef: RexInputRef): GeneratedExpression = {
+    val input1Arity = input1Type match {
+      case r: RowType => r.getFieldCount
+      case _ => 1
+    }
     // if inputRef index is within size of input1 we work with input1, input2 otherwise
-    val input = if (inputRef.getIndex < InternalTypeUtils.getArity(input1Type)) {
+    val input = if (inputRef.getIndex < input1Arity) {
       (input1Type, input1Term)
     } else {
       (input2Type.getOrElse(throw new CodeGenException("Invalid input access.")),
@@ -326,7 +334,7 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
     val index = if (input._2 == input1Term) {
       inputRef.getIndex
     } else {
-      inputRef.getIndex - InternalTypeUtils.getArity(input1Type)
+      inputRef.getIndex - input1Arity
     }
 
     generateInputAccess(ctx, input._1, input._2, index, nullableInput, ctx.nullCheck)
@@ -375,7 +383,7 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
   }
 
   override def visitLiteral(literal: RexLiteral): GeneratedExpression = {
-    val resultType = FlinkTypeFactory.toInternalType(literal.getType)
+    val resultType = FlinkTypeFactory.toLogicalType(literal.getType)
     val value = literal.getValue3
     generateLiteral(ctx, resultType, value)
   }
@@ -421,7 +429,7 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
 
   override def visitCall(call: RexCall): GeneratedExpression = {
 
-    val resultType = FlinkTypeFactory.toInternalType(call.getType)
+    val resultType = FlinkTypeFactory.toLogicalType(call.getType)
 
     // convert operands and help giving untyped NULL literals a type
     val operands = call.getOperands.zipWithIndex.map {
@@ -454,7 +462,7 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
       ctx: CodeGeneratorContext,
       operator: SqlOperator,
       operands: Seq[GeneratedExpression],
-      resultType: InternalType): GeneratedExpression = {
+      resultType: LogicalType): GeneratedExpression = {
     operator match {
       // arithmetic
       case PLUS if isNumeric(resultType) =>
@@ -661,13 +669,13 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
 
       case ITEM =>
         operands.head.resultType match {
-          case t: InternalType if TypeCheckUtils.isArray(t) =>
+          case t: LogicalType if TypeCheckUtils.isArray(t) =>
             val array = operands.head
             val index = operands(1)
             requireInteger(index)
             generateArrayElementAt(ctx, array, index)
 
-          case t: InternalType if TypeCheckUtils.isMap(t) =>
+          case t: LogicalType if TypeCheckUtils.isMap(t) =>
             val key = operands(1)
             generateMapGet(ctx, operands.head, key)
 
@@ -676,11 +684,11 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
 
       case CARDINALITY =>
         operands.head.resultType match {
-          case t: InternalType if TypeCheckUtils.isArray(t) =>
+          case t: LogicalType if TypeCheckUtils.isArray(t) =>
             val array = operands.head
             generateArrayCardinality(ctx, array)
 
-          case t: InternalType if TypeCheckUtils.isMap(t) =>
+          case t: LogicalType if TypeCheckUtils.isMap(t) =>
             val map = operands.head
             generateMapCardinality(ctx, map)
 
@@ -698,7 +706,9 @@ class ExprCodeGenerator(ctx: CodeGeneratorContext, nullableInput: Boolean)
       case PROCTIME =>
         // attribute is proctime indicator.
         // We use a null literal and generate a timestamp when we need it.
-        generateNullLiteral(InternalTypes.PROCTIME_INDICATOR, ctx.nullCheck)
+        generateNullLiteral(
+          new TimestampType(true, TimestampKind.PROCTIME, 3),
+          ctx.nullCheck)
 
       case PROCTIME_MATERIALIZE =>
         generateProctimeTimestamp(ctx, contextTerm)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExpressionReducer.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExpressionReducer.scala
index 2d96eac..95786f3 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExpressionReducer.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ExpressionReducer.scala
@@ -21,12 +21,12 @@ package org.apache.flink.table.codegen
 import org.apache.flink.api.common.functions.{MapFunction, RichMapFunction}
 import org.apache.flink.configuration.Configuration
 import org.apache.flink.metrics.MetricGroup
-import org.apache.flink.table.`type`.RowType
 import org.apache.flink.table.api.{TableConfig, TableException}
 import org.apache.flink.table.calcite.FlinkTypeFactory
 import org.apache.flink.table.codegen.FunctionCodeGenerator.generateFunction
 import org.apache.flink.table.dataformat.{BinaryString, Decimal, GenericRow}
 import org.apache.flink.table.functions.{FunctionContext, UserDefinedFunction}
+import org.apache.flink.table.types.logical.RowType
 
 import org.apache.calcite.avatica.util.ByteString
 import org.apache.calcite.rex.{RexBuilder, RexExecutor, RexNode}
@@ -49,7 +49,7 @@ class ExpressionReducer(
     allowChangeNullability: Boolean = false)
   extends RexExecutor {
 
-  private val EMPTY_ROW_TYPE = new RowType()
+  private val EMPTY_ROW_TYPE = RowType.of()
   private val EMPTY_ROW = new GenericRow(0)
 
   override def reduce(
@@ -69,8 +69,8 @@ class ExpressionReducer(
       case (_, e) => Some(e)
     }
 
-    val literalTypes = literals.map(e => FlinkTypeFactory.toInternalType(e.getType))
-    val resultType =  new RowType(literalTypes: _*)
+    val literalTypes = literals.map(e => FlinkTypeFactory.toLogicalType(e.getType))
+    val resultType = RowType.of(literalTypes: _*)
 
     // generate MapFunction
     val ctx = new ConstantCodeGeneratorContext(config)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/FunctionCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/FunctionCodeGenerator.scala
index 6746c9a..91fd2ff 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/FunctionCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/FunctionCodeGenerator.scala
@@ -21,10 +21,10 @@ import org.apache.flink.api.common.functions._
 import org.apache.flink.configuration.Configuration
 import org.apache.flink.streaming.api.functions.ProcessFunction
 import org.apache.flink.streaming.api.functions.async.{AsyncFunction, RichAsyncFunction}
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.Indenter.toISC
 import org.apache.flink.table.generated.{GeneratedFunction, GeneratedJoinCondition, JoinCondition}
+import org.apache.flink.table.types.logical.LogicalType
 
 /**
   * A code generator for generating Flink [[org.apache.flink.api.common.functions.Function]]s.
@@ -58,10 +58,10 @@ object FunctionCodeGenerator {
     name: String,
     clazz: Class[F],
     bodyCode: String,
-    returnType: InternalType,
-    input1Type: InternalType,
+    returnType: LogicalType,
+    input1Type: LogicalType,
     input1Term: String = DEFAULT_INPUT1_TERM,
-    input2Type: Option[InternalType] = None,
+    input2Type: Option[LogicalType] = None,
     input2Term: Option[String] = Some(DEFAULT_INPUT2_TERM),
     collectorTerm: String = DEFAULT_COLLECTOR_TERM,
     contextTerm: String = DEFAULT_CONTEXT_TERM)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/GenerateUtils.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/GenerateUtils.scala
index 2cd4aac..6a77070d 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/GenerateUtils.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/GenerateUtils.scala
@@ -20,12 +20,15 @@ package org.apache.flink.table.codegen
 
 import org.apache.flink.api.common.ExecutionConfig
 import org.apache.flink.api.common.typeinfo.{AtomicType => AtomicTypeInfo}
-import org.apache.flink.table.`type`._
+import org.apache.flink.api.java.typeutils.GenericTypeInfo
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.GeneratedExpression.{ALWAYS_NULL, NEVER_NULL, NO_CODE}
 import org.apache.flink.table.codegen.calls.CurrentTimePointCallGen
 import org.apache.flink.table.dataformat._
 import org.apache.flink.table.plan.util.SortUtil
+import org.apache.flink.table.types.PlannerTypeUtils
+import org.apache.flink.table.types.logical.LogicalTypeRoot._
+import org.apache.flink.table.types.logical._
 import org.apache.flink.table.typeutils.TypeCheckUtils.{isReference, isTemporal}
 
 import org.apache.calcite.avatica.util.ByteString
@@ -49,7 +52,7 @@ object GenerateUtils {
     */
   def generateCallIfArgsNotNull(
       ctx: CodeGeneratorContext,
-      returnType: InternalType,
+      returnType: LogicalType,
       operands: Seq[GeneratedExpression],
       resultNullable: Boolean = false)
       (call: Seq[String] => String): GeneratedExpression = {
@@ -63,7 +66,7 @@ object GenerateUtils {
     */
   def generateCallWithStmtIfArgsNotNull(
       ctx: CodeGeneratorContext,
-      returnType: InternalType,
+      returnType: LogicalType,
       operands: Seq[GeneratedExpression],
       resultNullable: Boolean = false)
       (call: Seq[String] => (String, String)): GeneratedExpression = {
@@ -123,7 +126,7 @@ object GenerateUtils {
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression])
       (call: Seq[String] => String): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       args => s"$BINARY_STRING.fromString(${call(args)})"
     }
   }
@@ -137,7 +140,7 @@ object GenerateUtils {
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression])
       (call: Seq[String] => (String, String)): GeneratedExpression = {
-    generateCallWithStmtIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallWithStmtIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       args =>
         val (stmt, result) = call(args)
         (stmt, s"$BINARY_STRING.fromString($result)")
@@ -149,7 +152,7 @@ object GenerateUtils {
     */
   def generateCallIfArgsNullable(
       ctx: CodeGeneratorContext,
-      returnType: InternalType,
+      returnType: LogicalType,
       operands: Seq[GeneratedExpression],
       resultNullable: Boolean = false)
       (call: Seq[String] => String): GeneratedExpression = {
@@ -170,7 +173,7 @@ object GenerateUtils {
 
     // TODO: should we also consider other types?
     val parameters = operands.map(x =>
-      if (x.resultType.equals(InternalTypes.STRING)){
+      if (x.resultType.isInstanceOf[VarCharType]){
         "( " + x.nullTerm + " ) ? null : (" + x.resultTerm + ")"
       } else {
         x.resultTerm
@@ -209,7 +212,7 @@ object GenerateUtils {
     * @return the record declaration statement
     */
   def generateRecordStatement(
-      t: InternalType,
+      t: LogicalType,
       clazz: Class[_],
       recordTerm: String,
       recordWriterTerm: Option[String] = None): String = {
@@ -221,12 +224,12 @@ object GenerateUtils {
         val binaryRowWriter = className[BinaryRowWriter]
         val typeTerm = clazz.getCanonicalName
         s"""
-           |final $typeTerm $recordTerm = new $typeTerm(${rt.getArity});
+           |final $typeTerm $recordTerm = new $typeTerm(${rt.getFieldCount});
            |final $binaryRowWriter $writerTerm = new $binaryRowWriter($recordTerm);
            |""".stripMargin.trim
       case rt: RowType if classOf[ObjectArrayRow].isAssignableFrom(clazz) =>
         val typeTerm = clazz.getCanonicalName
-        s"final $typeTerm $recordTerm = new $typeTerm(${rt.getArity});"
+        s"final $typeTerm $recordTerm = new $typeTerm(${rt.getFieldCount});"
       case _: RowType if clazz == classOf[JoinedRow] =>
         val typeTerm = clazz.getCanonicalName
         s"final $typeTerm $recordTerm = new $typeTerm();"
@@ -237,7 +240,7 @@ object GenerateUtils {
   }
 
   def generateNullLiteral(
-      resultType: InternalType,
+      resultType: LogicalType,
       nullCheck: Boolean): GeneratedExpression = {
     val defaultValue = primitiveDefaultValue(resultType)
     val resultTypeTerm = primitiveTypeTermForType(resultType)
@@ -254,7 +257,7 @@ object GenerateUtils {
   }
 
   def generateNonNullLiteral(
-      literalType: InternalType,
+      literalType: LogicalType,
       literalCode: String,
       literalValue: Any): GeneratedExpression = {
     val resultTypeTerm = primitiveTypeTermForType(literalType)
@@ -268,35 +271,35 @@ object GenerateUtils {
 
   def generateLiteral(
       ctx: CodeGeneratorContext,
-      literalType: InternalType,
+      literalType: LogicalType,
       literalValue: Any): GeneratedExpression = {
     if (literalValue == null) {
       return generateNullLiteral(literalType, ctx.nullCheck)
     }
     // non-null values
-    literalType match {
+    literalType.getTypeRoot match {
 
-      case InternalTypes.BOOLEAN =>
+      case BOOLEAN =>
         generateNonNullLiteral(literalType, literalValue.toString, literalValue)
 
-      case InternalTypes.BYTE =>
+      case TINYINT =>
         val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
         generateNonNullLiteral(literalType, decimal.byteValue().toString, decimal.byteValue())
 
-      case InternalTypes.SHORT =>
+      case SMALLINT =>
         val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
         generateNonNullLiteral(literalType, decimal.shortValue().toString, decimal.shortValue())
 
-      case InternalTypes.INT =>
+      case INTEGER =>
         val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
         generateNonNullLiteral(literalType, decimal.intValue().toString, decimal.intValue())
 
-      case InternalTypes.LONG =>
+      case BIGINT =>
         val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
         generateNonNullLiteral(
           literalType, decimal.longValue().toString + "L", decimal.longValue())
 
-      case InternalTypes.FLOAT =>
+      case FLOAT =>
         val floatValue = literalValue.asInstanceOf[JBigDecimal].floatValue()
         floatValue match {
           case Float.NaN => generateNonNullLiteral(
@@ -314,7 +317,7 @@ object GenerateUtils {
             literalType, floatValue.toString + "f", floatValue)
         }
 
-      case InternalTypes.DOUBLE =>
+      case DOUBLE =>
         val doubleValue = literalValue.asInstanceOf[JBigDecimal].doubleValue()
         doubleValue match {
           case Double.NaN => generateNonNullLiteral(
@@ -332,9 +335,10 @@ object GenerateUtils {
           case _ => generateNonNullLiteral(
             literalType, doubleValue.toString + "d", doubleValue)
         }
-      case decimal: DecimalType =>
-        val precision = decimal.precision()
-        val scale = decimal.scale()
+      case DECIMAL =>
+        val dt = literalType.asInstanceOf[DecimalType]
+        val precision = dt.getPrecision
+        val scale = dt.getScale
         val fieldTerm = newName("decimal")
         val decimalClass = className[Decimal]
         val fieldDecimal =
@@ -347,24 +351,24 @@ object GenerateUtils {
           literalValue.asInstanceOf[JBigDecimal], precision, scale)
         generateNonNullLiteral(literalType, fieldTerm, value)
 
-      case InternalTypes.STRING =>
+      case VARCHAR =>
         val escapedValue = StringEscapeUtils.ESCAPE_JAVA.translate(literalValue.toString)
         val field = ctx.addReusableStringConstants(escapedValue)
         generateNonNullLiteral(literalType, field, BinaryString.fromString(escapedValue))
 
-      case InternalTypes.BINARY =>
+      case VARBINARY =>
         val bytesVal = literalValue.asInstanceOf[ByteString].getBytes
         val fieldTerm = ctx.addReusableObject(
           bytesVal, "binary", bytesVal.getClass.getCanonicalName)
         generateNonNullLiteral(literalType, fieldTerm, bytesVal)
 
-      case InternalTypes.DATE =>
+      case DATE =>
         generateNonNullLiteral(literalType, literalValue.toString, literalValue)
 
-      case InternalTypes.TIME =>
+      case TIME_WITHOUT_TIME_ZONE =>
         generateNonNullLiteral(literalType, literalValue.toString, literalValue)
 
-      case InternalTypes.TIMESTAMP =>
+      case TIMESTAMP_WITHOUT_TIME_ZONE =>
         // Hack
         // Currently, in RexLiteral/SqlLiteral(Calcite), TimestampString has no time zone.
         // TimeString, DateString TimestampString are treated as UTC time/(unix time)
@@ -374,7 +378,7 @@ object GenerateUtils {
         val adjustedValue = millis - ctx.tableConfig.getTimeZone.getOffset(millis)
         generateNonNullLiteral(literalType, adjustedValue.toString + "L", adjustedValue)
 
-      case InternalTypes.INTERVAL_MONTHS =>
+      case INTERVAL_YEAR_MONTH =>
         val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
         if (decimal.isValidInt) {
           generateNonNullLiteral(literalType, decimal.intValue().toString, decimal.intValue())
@@ -383,7 +387,7 @@ object GenerateUtils {
             s"Decimal '$decimal' can not be converted to interval of months.")
         }
 
-      case InternalTypes.INTERVAL_MILLIS =>
+      case INTERVAL_DAY_TIME =>
         val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
         if (decimal.isValidLong) {
           generateNonNullLiteral(
@@ -396,7 +400,8 @@ object GenerateUtils {
         }
 
       // Symbol type for special flags e.g. TRIM's BOTH, LEADING, TRAILING
-      case symbol: GenericType[_] if symbol.getTypeClass.isAssignableFrom(classOf[Enum[_]]) =>
+      case ANY if literalType.asInstanceOf[TypeInformationAnyType[_]]
+          .getTypeInformation.getTypeClass.isAssignableFrom(classOf[Enum[_]]) =>
         generateSymbol(literalValue.asInstanceOf[Enum[_]])
 
       case t@_ =>
@@ -409,7 +414,8 @@ object GenerateUtils {
       qualifyEnum(enum),
       NEVER_NULL,
       NO_CODE,
-      new GenericType(enum.getDeclaringClass),
+      new TypeInformationAnyType[AnyRef](new GenericTypeInfo[AnyRef](
+        enum.getDeclaringClass.asInstanceOf[Class[AnyRef]])),
       literalValue = Some(enum))
   }
 
@@ -421,7 +427,7 @@ object GenerateUtils {
     * @return internal unboxed field representation
     */
   private[flink] def generateNonNullField(
-      fieldType: InternalType,
+      fieldType: LogicalType,
       fieldTerm: String)
     : GeneratedExpression = {
     val resultTypeTerm = primitiveTypeTermForType(fieldType)
@@ -437,12 +443,12 @@ object GenerateUtils {
          |$resultTerm = $contextTerm.timerService().currentProcessingTime();
          |""".stripMargin.trim
     // the proctime has been materialized, so it's TIMESTAMP now, not PROCTIME_INDICATOR
-    GeneratedExpression(resultTerm, NEVER_NULL, resultCode, InternalTypes.TIMESTAMP)
+    GeneratedExpression(resultTerm, NEVER_NULL, resultCode, new TimestampType(3))
   }
 
   def generateCurrentTimestamp(
       ctx: CodeGeneratorContext): GeneratedExpression = {
-    new CurrentTimePointCallGen(false).generate(ctx, Seq(), InternalTypes.TIMESTAMP)
+    new CurrentTimePointCallGen(false).generate(ctx, Seq(), new TimestampType(3))
   }
 
   def generateRowtimeAccess(
@@ -463,7 +469,11 @@ object GenerateUtils {
          |$nullTerm = false;
        """.stripMargin.trim
 
-    GeneratedExpression(resultTerm, nullTerm, accessCode, InternalTypes.ROWTIME_INDICATOR)
+    GeneratedExpression(
+      resultTerm,
+      nullTerm,
+      accessCode,
+      new TimestampType(true, TimestampKind.ROWTIME, 3))
   }
 
   /**
@@ -477,7 +487,7 @@ object GenerateUtils {
     */
   def generateInputAccess(
       ctx: CodeGeneratorContext,
-      inputType: InternalType,
+      inputType: LogicalType,
       inputTerm: String,
       index: Int,
       nullableInput: Boolean,
@@ -505,13 +515,13 @@ object GenerateUtils {
 
   def generateNullableInputFieldAccess(
     ctx: CodeGeneratorContext,
-    inputType: InternalType,
+    inputType: LogicalType,
     inputTerm: String,
     index: Int,
     deepCopy: Boolean = false): GeneratedExpression = {
 
     val fieldType = inputType match {
-      case ct: RowType => ct.getFieldTypes()(index)
+      case ct: RowType => ct.getTypeAt(index)
       case _ => inputType
     }
     val resultTypeTerm = primitiveTypeTermForType(fieldType)
@@ -548,7 +558,7 @@ object GenerateUtils {
     */
   def generateInputFieldUnboxing(
       ctx: CodeGeneratorContext,
-      fieldType: InternalType,
+      fieldType: LogicalType,
       fieldTerm: String): GeneratedExpression = {
 
     val resultTypeTerm = primitiveTypeTermForType(fieldType)
@@ -585,7 +595,7 @@ object GenerateUtils {
     */
   def generateFieldAccess(
     ctx: CodeGeneratorContext,
-    inputType: InternalType,
+    inputType: LogicalType,
     inputTerm: String,
     index: Int,
     deepCopy: Boolean): GeneratedExpression = {
@@ -599,12 +609,12 @@ object GenerateUtils {
 
   def generateFieldAccess(
       ctx: CodeGeneratorContext,
-      inputType: InternalType,
+      inputType: LogicalType,
       inputTerm: String,
       index: Int): GeneratedExpression =
     inputType match {
       case ct: RowType =>
-        val fieldType = ct.getFieldTypes()(index)
+        val fieldType = ct.getTypeAt(index)
         val resultTypeTerm = primitiveTypeTermForType(fieldType)
         val defaultValue = primitiveDefaultValue(fieldType)
         val readCode = baseRowFieldReadAccess(ctx, index.toString, inputTerm, fieldType)
@@ -634,23 +644,25 @@ object GenerateUtils {
         generateInputFieldUnboxing(ctx, inputType, inputCode)
     }
 
-
   /**
     * Generates code for comparing two field.
     */
   def generateCompare(
       ctx: CodeGeneratorContext,
-      t: InternalType,
+      t: LogicalType,
       nullsIsLast: Boolean,
       leftTerm: String,
-      rightTerm: String): String = t match {
-    case InternalTypes.BOOLEAN => s"($leftTerm == $rightTerm ? 0 : ($leftTerm ? 1 : -1))"
-    case _: PrimitiveType | _: DateType | _: TimeType | _: TimestampType =>
+      rightTerm: String): String = t.getTypeRoot match {
+    case BOOLEAN => s"($leftTerm == $rightTerm ? 0 : ($leftTerm ? 1 : -1))"
+    case DATE | TIME_WITHOUT_TIME_ZONE | TIMESTAMP_WITHOUT_TIME_ZONE =>
+      s"($leftTerm > $rightTerm ? 1 : $leftTerm < $rightTerm ? -1 : 0)"
+    case _ if PlannerTypeUtils.isPrimitive(t) =>
       s"($leftTerm > $rightTerm ? 1 : $leftTerm < $rightTerm ? -1 : 0)"
-    case InternalTypes.BINARY =>
+    case VARBINARY =>
       val sortUtil = classOf[org.apache.flink.table.runtime.sort.SortUtil].getCanonicalName
       s"$sortUtil.compareBinary($leftTerm, $rightTerm)"
-    case at: ArrayType =>
+    case ARRAY =>
+      val at = t.asInstanceOf[ArrayType]
       val compareFunc = newName("compareArray")
       val compareCode = generateArrayCompare(
         ctx,
@@ -664,12 +676,13 @@ object GenerateUtils {
         """
       ctx.addReusableMember(funcCode)
       s"$compareFunc($leftTerm, $rightTerm)"
-    case rowType: RowType =>
-      val orders = rowType.getFieldTypes.map(_ => true)
+    case ROW =>
+      val rowType = t.asInstanceOf[RowType]
+      val orders = (0 until rowType.getFieldCount).map(_ => true).toArray
       val comparisons = generateRowCompare(
         ctx,
-        rowType.getFieldTypes.indices.toArray,
-        rowType.getFieldTypes,
+        (0 until rowType.getFieldCount).toArray,
+        rowType.getChildren.toArray(Array[LogicalType]()),
         orders,
         SortUtil.getNullDefaultOrders(orders),
         "a",
@@ -684,10 +697,13 @@ object GenerateUtils {
         """
       ctx.addReusableMember(funcCode)
       s"$compareFunc($leftTerm, $rightTerm)"
-    case gt: GenericType[_] =>
-      val ser = ctx.addReusableObject(gt.getSerializer, "serializer")
+    case ANY =>
+      val anyType = t.asInstanceOf[TypeInformationAnyType[_]]
+      val ser = ctx.addReusableObject(
+        anyType.getTypeInformation.createSerializer(new ExecutionConfig), "serializer")
       val comp = ctx.addReusableObject(
-        gt.getTypeInfo.asInstanceOf[AtomicTypeInfo[_]].createComparator(true, new ExecutionConfig),
+        anyType.getTypeInformation.asInstanceOf[AtomicTypeInfo[_]]
+            .createComparator(true, new ExecutionConfig),
         "comparator")
       s"""
          |$comp.compare(
@@ -695,7 +711,7 @@ object GenerateUtils {
          |  $BINARY_GENERIC.getJavaObjectFromBinaryGeneric($rightTerm, $ser)
          |)
        """.stripMargin
-    case other if other.isInstanceOf[AtomicType] => s"$leftTerm.compareTo($rightTerm)"
+    case other => s"$leftTerm.compareTo($rightTerm)"
   }
 
   /**
@@ -757,7 +773,7 @@ object GenerateUtils {
   def generateRowCompare(
     ctx: CodeGeneratorContext,
     keys: Array[Int],
-    keyTypes: Array[InternalType],
+    keyTypes: Array[LogicalType],
     orders: Array[Boolean],
     nullsIsLast: Array[Boolean],
     leftTerm: String,
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/GeneratedExpression.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/GeneratedExpression.scala
index aa404bd..cd5e5ca 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/GeneratedExpression.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/GeneratedExpression.scala
@@ -18,8 +18,8 @@
 
 package org.apache.flink.table.codegen
 
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.CodeGenUtils.{boxedTypeTermForType, newName}
+import org.apache.flink.table.types.logical.LogicalType
 import org.apache.flink.table.typeutils.TypeCheckUtils
 
 /**
@@ -36,7 +36,7 @@ case class GeneratedExpression(
   resultTerm: String,
   nullTerm: String,
   code: String,
-  resultType: InternalType,
+  resultType: LogicalType,
   literalValue: Option[Any] = None) {
 
   /**
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/HashCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/HashCodeGenerator.scala
index d20f1c5..88fdccf 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/HashCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/HashCodeGenerator.scala
@@ -18,11 +18,11 @@
 
 package org.apache.flink.table.codegen
 
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.CodeGenUtils.{BASE_ROW, hashCodeForType, newName}
 import org.apache.flink.table.codegen.Indenter.toISC
 import org.apache.flink.table.dataformat.BaseRow
 import org.apache.flink.table.generated.{GeneratedHashFunction, HashFunction}
+import org.apache.flink.table.types.logical.LogicalType
 import org.apache.flink.util.MathUtils
 
 /**
@@ -48,7 +48,7 @@ object HashCodeGenerator {
 
   def generateRowHash(
       ctx: CodeGeneratorContext,
-      input: InternalType,
+      input: LogicalType,
       name: String,
       hashFields: Array[Int]): GeneratedHashFunction = {
     val className = newName(name)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/InputFormatCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/InputFormatCodeGenerator.scala
index 7a41f13..ecf750e 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/InputFormatCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/InputFormatCodeGenerator.scala
@@ -22,7 +22,7 @@ import org.apache.flink.table.codegen.CodeGenUtils.newName
 import org.apache.flink.table.codegen.Indenter.toISC
 import org.apache.flink.table.dataformat.GenericRow
 import org.apache.flink.table.generated.GeneratedInput
-import org.apache.flink.table.`type`.InternalType
+import org.apache.flink.table.types.logical.LogicalType
 
 /**
   * A code generator for generating Flink [[GenericInputFormat]]s.
@@ -45,7 +45,7 @@ object InputFormatCodeGenerator {
       ctx: CodeGeneratorContext,
       name: String,
       records: Seq[String],
-      returnType: InternalType,
+      returnType: LogicalType,
       outRecordTerm: String = CodeGenUtils.DEFAULT_OUT_RECORD_TERM,
       outRecordWriterTerm: String = CodeGenUtils.DEFAULT_OUT_RECORD_WRITER_TERM)
     : GeneratedInput[GenericInputFormat[T]] = {
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/LongHashJoinGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/LongHashJoinGenerator.scala
index 7defe5d..98286e4 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/LongHashJoinGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/LongHashJoinGenerator.scala
@@ -19,7 +19,6 @@
 package org.apache.flink.table.codegen
 
 import org.apache.flink.metrics.Gauge
-import org.apache.flink.table.`type`.{DateType, InternalType, InternalTypes, RowType, TimestampType}
 import org.apache.flink.table.api.TableConfig
 import org.apache.flink.table.codegen.CodeGenUtils.{BASE_ROW, BINARY_ROW, baseRowFieldReadAccess, newName}
 import org.apache.flink.table.codegen.OperatorCodeGenerator.generateCollect
@@ -28,6 +27,8 @@ import org.apache.flink.table.generated.{GeneratedJoinCondition, GeneratedProjec
 import org.apache.flink.table.runtime.CodeGenOperatorFactory
 import org.apache.flink.table.runtime.hashtable.{LongHashPartition, LongHybridHashTable}
 import org.apache.flink.table.runtime.join.HashJoinType
+import org.apache.flink.table.types.logical.LogicalTypeRoot._
+import org.apache.flink.table.types.logical._
 import org.apache.flink.table.typeutils.BinaryRowSerializer
 
 /**
@@ -44,11 +45,12 @@ object LongHashJoinGenerator {
         joinType == HashJoinType.ANTI ||
         joinType == HashJoinType.PROBE_OUTER) &&
         filterNulls.forall(b => b) &&
-        keyType.getFieldTypes.length == 1 && {
-      val t = keyType.getTypeAt(0)
-      t == InternalTypes.LONG || t == InternalTypes.INT || t == InternalTypes.SHORT ||
-          t == InternalTypes.BYTE || t == InternalTypes.FLOAT || t == InternalTypes.DOUBLE ||
-          t.isInstanceOf[DateType] || t.isInstanceOf[TimestampType] || t == InternalTypes.TIME
+        keyType.getFieldCount == 1 && {
+      keyType.getTypeAt(0).getTypeRoot match {
+        case BIGINT | INTEGER | SMALLINT | TINYINT | FLOAT | DOUBLE | DATE |
+             TIME_WITHOUT_TIME_ZONE | TIMESTAMP_WITHOUT_TIME_ZONE => true
+        case _ => false
+      }
       // TODO decimal and multiKeys support.
       // TODO All HashJoinType support.
     }
@@ -59,11 +61,11 @@ object LongHashJoinGenerator {
       keyType: RowType,
       keyMapping: Array[Int],
       rowTerm: String): String = {
-    val singleType = keyType.getFieldTypes()(0)
+    val singleType = keyType.getTypeAt(0)
     val getCode = baseRowFieldReadAccess(ctx, keyMapping(0), rowTerm, singleType)
-    val term = singleType match {
-      case InternalTypes.FLOAT => s"Float.floatToIntBits($getCode)"
-      case InternalTypes.DOUBLE => s"Double.doubleToLongBits($getCode)"
+    val term = singleType.getTypeRoot match {
+      case FLOAT => s"Float.floatToIntBits($getCode)"
+      case DOUBLE => s"Double.doubleToLongBits($getCode)"
       case _ => getCode
     }
     s"return $term;"
@@ -81,8 +83,8 @@ object LongHashJoinGenerator {
      """.stripMargin, anyNullTerm)
   }
 
-  def genProjection(conf: TableConfig, types: Array[InternalType]): GeneratedProjection = {
-    val rowType = new RowType(types: _*)
+  def genProjection(conf: TableConfig, types: Array[LogicalType]): GeneratedProjection = {
+    val rowType = RowType.of(types: _*)
     ProjectionCodeGenerator.generateProjection(
       CodeGeneratorContext.apply(conf),
       "Projection",
@@ -107,17 +109,17 @@ object LongHashJoinGenerator {
       reverseJoinFunction: Boolean,
       condFunc: GeneratedJoinCondition): CodeGenOperatorFactory[BaseRow] = {
 
-    val buildSer = new BinaryRowSerializer(buildType.getArity)
-    val probeSer = new BinaryRowSerializer(probeType.getArity)
+    val buildSer = new BinaryRowSerializer(buildType.getFieldCount)
+    val probeSer = new BinaryRowSerializer(probeType.getFieldCount)
 
     val tableTerm = newName("LongHashTable")
     val ctx = CodeGeneratorContext(conf)
     val buildSerTerm = ctx.addReusableObject(buildSer, "buildSer")
     val probeSerTerm = ctx.addReusableObject(probeSer, "probeSer")
 
-    val bGenProj = genProjection(conf, buildType.getFieldTypes)
+    val bGenProj = genProjection(conf, buildType.getChildren.toArray(Array[LogicalType]()))
     ctx.addReusableInnerClass(bGenProj.getClassName, bGenProj.getCode)
-    val pGenProj = genProjection(conf, probeType.getFieldTypes)
+    val pGenProj = genProjection(conf, probeType.getChildren.toArray(Array[LogicalType]()))
     ctx.addReusableInnerClass(pGenProj.getClassName, pGenProj.getCode)
     ctx.addReusableInnerClass(condFunc.getClassName, condFunc.getCode)
 
@@ -195,7 +197,7 @@ object LongHashJoinGenerator {
     ctx.addReusableInnerClass(tableTerm, tableCode)
 
     ctx.addReusableNullRow("buildSideNullRow", buildSer.getArity)
-    ctx.addReusableOutputRecord(new RowType(), classOf[JoinedRow], "joinedRow")
+    ctx.addReusableOutputRecord(RowType.of(), classOf[JoinedRow], "joinedRow")
     ctx.addReusableMember(s"$tableTerm table;")
     ctx.addReusableOpenStatement(s"table = new $tableTerm();")
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/LookupJoinCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/LookupJoinCodeGenerator.scala
index 67dfac6..7ffe5a8 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/LookupJoinCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/LookupJoinCodeGenerator.scala
@@ -17,27 +17,30 @@
  */
 package org.apache.flink.table.codegen
 
-import org.apache.calcite.rex.{RexNode, RexProgram}
 import org.apache.flink.api.common.functions.FlatMapFunction
 import org.apache.flink.api.common.typeinfo.TypeInformation
 import org.apache.flink.api.java.typeutils.RowTypeInfo
 import org.apache.flink.configuration.Configuration
 import org.apache.flink.streaming.api.functions.async.AsyncFunction
-import org.apache.flink.table.`type`.{InternalType, RowType, TypeConverters}
 import org.apache.flink.table.api.TableConfig
 import org.apache.flink.table.calcite.FlinkTypeFactory
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.GenerateUtils._
 import org.apache.flink.table.codegen.Indenter.toISC
-import org.apache.flink.table.dataformat.DataFormatConverters.RowConverter
-import org.apache.flink.table.dataformat.{BaseRow, GenericRow, JoinedRow}
+import org.apache.flink.table.dataformat.DataFormatConverters.DataFormatConverter
+import org.apache.flink.table.dataformat.{BaseRow, DataFormatConverters, GenericRow, JoinedRow}
 import org.apache.flink.table.functions.{AsyncTableFunction, TableFunction}
 import org.apache.flink.table.generated.{GeneratedCollector, GeneratedFunction, GeneratedResultFuture}
 import org.apache.flink.table.plan.util.LookupJoinUtil.{ConstantLookupKey, FieldRefLookupKey, LookupKey}
 import org.apache.flink.table.runtime.collector.{TableFunctionCollector, TableFunctionResultFuture}
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromLogicalTypeToDataType
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
+import org.apache.flink.table.types.utils.TypeConversions
 import org.apache.flink.types.Row
 import org.apache.flink.util.Collector
 
+import org.apache.calcite.rex.{RexNode, RexProgram}
+
 import java.util
 
 object LookupJoinCodeGenerator {
@@ -50,8 +53,8 @@ object LookupJoinCodeGenerator {
   def generateLookupFunction(
       config: TableConfig,
       typeFactory: FlinkTypeFactory,
-      inputType: InternalType,
-      returnType: InternalType,
+      inputType: LogicalType,
+      returnType: LogicalType,
       tableReturnTypeInfo: TypeInformation[_],
       lookupKeyInOrder: Array[Int],
       // index field position -> lookup key
@@ -105,8 +108,8 @@ object LookupJoinCodeGenerator {
   def generateAsyncLookupFunction(
       config: TableConfig,
       typeFactory: FlinkTypeFactory,
-      inputType: InternalType,
-      returnType: InternalType,
+      inputType: LogicalType,
+      returnType: LogicalType,
       tableReturnTypeInfo: TypeInformation[_],
       lookupKeyInOrder: Array[Int],
       allLookupFields: Map[Int, LookupKey],
@@ -146,7 +149,7 @@ object LookupJoinCodeGenerator {
   private def prepareParameters(
       ctx: CodeGeneratorContext,
       typeFactory: FlinkTypeFactory,
-      inputType: InternalType,
+      inputType: LogicalType,
       lookupKeyInOrder: Array[Int],
       allLookupFields: Map[Int, LookupKey],
       isExternalArgs: Boolean,
@@ -170,14 +173,14 @@ object LookupJoinCodeGenerator {
     }
     val codeAndArg = inputFieldExprs
       .map { e =>
-        val externalTypeInfo = TypeConverters.createExternalTypeInfoFromInternalType(e.resultType)
+        val dataType = fromLogicalTypeToDataType(e.resultType)
         val bType = if (isExternalArgs) {
-          boxedTypeTermForExternalType(externalTypeInfo)
+          boxedTypeTermForExternalType(dataType)
         } else {
           boxedTypeTermForType(e.resultType)
         }
         val assign = if (isExternalArgs) {
-          CodeGenUtils.genToExternal(ctx, externalTypeInfo, e.resultTerm)
+          CodeGenUtils.genToExternal(ctx, dataType, e.resultTerm)
         } else {
           e.resultTerm
         }
@@ -423,7 +426,7 @@ object LookupJoinCodeGenerator {
     CalcCodeGenerator.generateFunction(
       tableSourceRowType,
       "TableCalcMapFunction",
-      FlinkTypeFactory.toInternalRowType(program.getOutputRowType),
+      FlinkTypeFactory.toLogicalRowType(program.getOutputRowType),
       classOf[GenericRow],
       program,
       condition,
@@ -438,7 +441,9 @@ object LookupJoinCodeGenerator {
   class RowToBaseRowCollector(rowTypeInfo: RowTypeInfo)
     extends TableFunctionCollector[Row] with Serializable {
 
-    private val converter = new RowConverter(rowTypeInfo)
+    private val converter = DataFormatConverters.getConverterForDataType(
+      TypeConversions.fromLegacyInfoToDataType(rowTypeInfo))
+        .asInstanceOf[DataFormatConverter[BaseRow, Row]]
 
     override def collect(record: Row): Unit = {
       val result = converter.toInternal(record)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/OperatorCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/OperatorCodeGenerator.scala
index c406f97..8d5ea53 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/OperatorCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/OperatorCodeGenerator.scala
@@ -21,11 +21,11 @@ import org.apache.flink.streaming.api.graph.StreamConfig
 import org.apache.flink.streaming.api.operators.{OneInputStreamOperator, Output, StreamOperator, TwoInputStreamOperator}
 import org.apache.flink.streaming.runtime.streamrecord.StreamRecord
 import org.apache.flink.streaming.runtime.tasks.StreamTask
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.api.TableConfig
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.Indenter.toISC
 import org.apache.flink.table.generated.GeneratedOperator
+import org.apache.flink.table.types.logical.LogicalType
 import org.apache.flink.table.util.Logging
 
 /**
@@ -47,7 +47,7 @@ object OperatorCodeGenerator extends Logging {
       name: String,
       processCode: String,
       endInputCode: String,
-      inputType: InternalType,
+      inputType: LogicalType,
       config: TableConfig,
       inputTerm: String = CodeGenUtils.DEFAULT_INPUT1_TERM,
       lazyInputUnboxingCode: Boolean = false,
@@ -128,8 +128,8 @@ object OperatorCodeGenerator extends Logging {
       endInputCode1: String,
       processCode2: String,
       endInputCode2: String,
-      input1Type: InternalType,
-      input2Type: InternalType,
+      input1Type: LogicalType,
+      input2Type: LogicalType,
       input1Term: String = CodeGenUtils.DEFAULT_INPUT1_TERM,
       input2Term: String = CodeGenUtils.DEFAULT_INPUT2_TERM,
       useTimeCollect: Boolean = false)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ProjectionCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ProjectionCodeGenerator.scala
index 04207cd..82c918f 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ProjectionCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ProjectionCodeGenerator.scala
@@ -18,12 +18,12 @@
 
 package org.apache.flink.table.codegen
 
-import org.apache.flink.table.`type`.{InternalType, RowType}
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.GenerateUtils.generateRecordStatement
 import org.apache.flink.table.codegen.GeneratedExpression.{NEVER_NULL, NO_CODE}
 import org.apache.flink.table.dataformat._
 import org.apache.flink.table.generated.{GeneratedProjection, Projection}
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
 
 import scala.collection.mutable
 
@@ -56,7 +56,7 @@ object ProjectionCodeGenerator {
     // instead of generating separated code for each field.
     // when the number of fields of the same type is large, this can improve performance.
     def generateLoop(
-        fieldType: InternalType,
+        fieldType: LogicalType,
         inIdxs: mutable.ArrayBuffer[Int],
         outIdxs: mutable.ArrayBuffer[Int]): String = {
       // this array contains the indices of the fields
@@ -88,14 +88,14 @@ object ProjectionCodeGenerator {
        """.stripMargin
     }
 
-    val outFieldTypes = outType.getFieldTypes
+    val outFieldTypes = outType.getChildren
     val typeIdxs = new mutable.HashMap[
-      InternalType,
+      LogicalType,
       (mutable.ArrayBuffer[Int], mutable.ArrayBuffer[Int])]()
 
-    for (i <- outFieldTypes.indices) {
+    for (i <- 0 until outFieldTypes.size()) {
       val (inIdxs, outIdxs) = typeIdxs.getOrElseUpdate(
-        outFieldTypes(i), (mutable.ArrayBuffer.empty[Int], mutable.ArrayBuffer.empty[Int]))
+        outFieldTypes.get(i), (mutable.ArrayBuffer.empty[Int], mutable.ArrayBuffer.empty[Int]))
       inIdxs.append(inputMapping(i))
       outIdxs.append(i)
     }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/SinkCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/SinkCodeGenerator.scala
index 6006ec1..2559a0a 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/SinkCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/SinkCodeGenerator.scala
@@ -26,8 +26,6 @@ import org.apache.flink.api.java.typeutils.{GenericTypeInfo, PojoTypeInfo, RowTy
 import org.apache.flink.api.scala.createTuple2TypeInformation
 import org.apache.flink.api.scala.typeutils.CaseClassTypeInfo
 import org.apache.flink.streaming.api.datastream.DataStream
-import org.apache.flink.table.`type`.RowType
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
 import org.apache.flink.table.api.{Table, TableConfig, TableException, Types}
 import org.apache.flink.table.codegen.CodeGenUtils.genToExternal
 import org.apache.flink.table.codegen.OperatorCodeGenerator.generateCollect
@@ -35,6 +33,8 @@ import org.apache.flink.table.dataformat.util.BaseRowUtil
 import org.apache.flink.table.dataformat.{BaseRow, GenericRow}
 import org.apache.flink.table.runtime.CodeGenOperatorFactory
 import org.apache.flink.table.sinks.{DataStreamTableSink, TableSink}
+import org.apache.flink.table.types.TypeInfoLogicalTypeConverter.fromTypeInfoToLogicalType
+import org.apache.flink.table.types.utils.TypeConversions.fromLegacyInfoToDataType
 import org.apache.flink.table.typeutils.{BaseRowTypeInfo, TimeIndicatorTypeInfo}
 import org.apache.flink.types.Row
 
@@ -96,7 +96,7 @@ object SinkCodeGenerator {
           inputTypeInfo.getFieldNames)
       case gt: GenericTypeInfo[BaseRow] if gt.getTypeClass == classOf[BaseRow] =>
         new BaseRowTypeInfo(
-          inputTypeInfo.getInternalTypes,
+          inputTypeInfo.getLogicalTypes,
           inputTypeInfo.getFieldNames)
       case _ => requestedTypeInfo
     }
@@ -122,8 +122,8 @@ object SinkCodeGenerator {
     val inputTerm = CodeGenUtils.DEFAULT_INPUT1_TERM
     var afterIndexModify = inputTerm
     val fieldIndexProcessCode =
-      if (getCompositeTypes(convertOutputType).map(createInternalTypeFromTypeInfo) sameElements
-          inputTypeInfo.getFieldTypes.map(createInternalTypeFromTypeInfo)) {
+      if (getCompositeTypes(convertOutputType).map(fromTypeInfoToLogicalType) sameElements
+          inputTypeInfo.getFieldTypes.map(fromTypeInfoToLogicalType)) {
         ""
       } else {
         // field index change (pojo)
@@ -141,13 +141,13 @@ object SinkCodeGenerator {
         }
 
         val resultGenerator = new ExprCodeGenerator(ctx, false).bindInput(
-          createInternalTypeFromTypeInfo(inputTypeInfo),
+          fromTypeInfoToLogicalType(inputTypeInfo),
           inputTerm,
           inputFieldMapping = Option(mapping))
         val outputBaseRowType = new BaseRowTypeInfo(
-          getCompositeTypes(convertOutputType).map(createInternalTypeFromTypeInfo): _*)
+            getCompositeTypes(convertOutputType).map(fromTypeInfoToLogicalType): _*)
         val conversion = resultGenerator.generateConverterResultExpression(
-          createInternalTypeFromTypeInfo(outputBaseRowType).asInstanceOf[RowType],
+          outputBaseRowType.toRowType,
           classOf[GenericRow])
         afterIndexModify = CodeGenUtils.newName("afterIndexModify")
         s"""
@@ -157,7 +157,8 @@ object SinkCodeGenerator {
       }
 
     val retractProcessCode = if (!withChangeFlag) {
-      generateCollect(genToExternal(ctx, outputTypeInfo, afterIndexModify))
+      generateCollect(
+        genToExternal(ctx, fromLegacyInfoToDataType(outputTypeInfo), afterIndexModify))
     } else {
       val flagResultTerm =
         s"${classOf[BaseRowUtil].getCanonicalName}.isAccumulateMsg($afterIndexModify)"
@@ -167,7 +168,8 @@ object SinkCodeGenerator {
          |$genericRowField $resultTerm = new $genericRowField(2);
          |$resultTerm.setField(0, $flagResultTerm);
          |$resultTerm.setField(1, $afterIndexModify);
-         |${generateCollect(genToExternal(ctx, outputTypeInfo, resultTerm))}
+         |${generateCollect(
+        genToExternal(ctx, fromLegacyInfoToDataType(outputTypeInfo), resultTerm))}
           """.stripMargin
     }
 
@@ -180,7 +182,7 @@ object SinkCodeGenerator {
          |$retractProcessCode
          |""".stripMargin,
       endInputCode,
-      createInternalTypeFromTypeInfo(inputTypeInfo),
+      fromTypeInfoToLogicalType(inputTypeInfo),
       config)
     (new CodeGenOperatorFactory[OUT](generated), outputTypeInfo.asInstanceOf[TypeInformation[OUT]])
   }
@@ -238,8 +240,8 @@ object SinkCodeGenerator {
           case (fieldTypeInfo, i) =>
             val requestedTypeInfo = tt.getTypeAt(i)
             validateFieldType(requestedTypeInfo)
-            if (createInternalTypeFromTypeInfo(fieldTypeInfo) !=
-                createInternalTypeFromTypeInfo(requestedTypeInfo) &&
+            if (fromTypeInfoToLogicalType(fieldTypeInfo) !=
+                fromTypeInfoToLogicalType(requestedTypeInfo) &&
                 !requestedTypeInfo.isInstanceOf[GenericTypeInfo[Object]]) {
               val fieldNames = tt.getFieldNames
               throw new TableException(s"Result field '${fieldNames(i)}' does not match requested" +
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ValuesCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ValuesCodeGenerator.scala
index 86b79a9..8578b8e 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ValuesCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/ValuesCodeGenerator.scala
@@ -22,10 +22,10 @@ import org.apache.flink.table.api.TableEnvironment
 import org.apache.flink.table.calcite.FlinkTypeFactory
 import org.apache.flink.table.dataformat.{BaseRow, GenericRow}
 import org.apache.flink.table.runtime.values.ValuesInputFormat
+import org.apache.flink.table.typeutils.BaseRowTypeInfo
 
 import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.rex.RexLiteral
-
 import com.google.common.collect.ImmutableList
 
 import scala.collection.JavaConversions._
@@ -38,7 +38,7 @@ object ValuesCodeGenerator {
     tuples: ImmutableList[ImmutableList[RexLiteral]],
     description: String): ValuesInputFormat = {
     val config = tableEnv.getConfig
-    val outputType = FlinkTypeFactory.toInternalRowType(rowType)
+    val outputType = FlinkTypeFactory.toLogicalRowType(rowType)
 
     val ctx = CodeGeneratorContext(config)
     val exprGenerator = new ExprCodeGenerator(ctx, false)
@@ -55,7 +55,7 @@ object ValuesCodeGenerator {
       generatedRecords.map(_.code),
       outputType)
 
-    new ValuesInputFormat(generatedFunction, outputType.toTypeInfo)
+    new ValuesInputFormat(generatedFunction, BaseRowTypeInfo.of(outputType))
   }
 
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/AggsHandlerCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/AggsHandlerCodeGenerator.scala
index e5a9b7b..f77810b 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/AggsHandlerCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/AggsHandlerCodeGenerator.scala
@@ -17,9 +17,6 @@
  */
 package org.apache.flink.table.codegen.agg
 
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
-import org.apache.flink.table.`type`.{InternalType, InternalTypes, RowType}
 import org.apache.flink.table.api.TableException
 import org.apache.flink.table.codegen.CodeGenUtils.{BASE_ROW, _}
 import org.apache.flink.table.codegen.Indenter.toISC
@@ -32,6 +29,13 @@ import org.apache.flink.table.functions.AggregateFunction
 import org.apache.flink.table.functions.aggfunctions.DeclarativeAggregateFunction
 import org.apache.flink.table.generated.{AggsHandleFunction, GeneratedAggsHandleFunction, GeneratedNamespaceAggsHandleFunction, NamespaceAggsHandleFunction}
 import org.apache.flink.table.plan.util.AggregateInfoList
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
+import org.apache.flink.table.types.{DataType, LogicalTypeDataTypeConverter}
+import org.apache.flink.table.types.TypeInfoLogicalTypeConverter.fromTypeInfoToLogicalType
+import org.apache.flink.table.types.logical.{BooleanType, IntType, LogicalType, RowType}
+import org.apache.flink.table.types.utils.TypeConversions
+import org.apache.flink.table.types.utils.TypeConversions.fromLegacyInfoToDataType
+
 import org.apache.calcite.rex.RexLiteral
 import org.apache.calcite.tools.RelBuilder
 
@@ -44,10 +48,10 @@ import org.apache.calcite.tools.RelBuilder
 class AggsHandlerCodeGenerator(
     ctx: CodeGeneratorContext,
     relBuilder: RelBuilder,
-    inputFieldTypes: Seq[InternalType],
+    inputFieldTypes: Seq[LogicalType],
     copyInputField: Boolean) {
 
-  private val inputType = new RowType(inputFieldTypes: _*)
+  private val inputType = RowType.of(inputFieldTypes: _*)
 
   /** constant expressions that act like a second input in the parameter indices. */
   private var constantExprs: Seq[GeneratedExpression] = Seq()
@@ -61,7 +65,7 @@ class AggsHandlerCodeGenerator(
   private var accTypeInfo: RowType = _
   private var aggBufferSize: Int = _
 
-  private var mergedAccExternalTypes: Array[TypeInformation[_]] = _
+  private var mergedAccExternalTypes: Array[DataType] = _
   private var mergedAccOffset: Int = 0
   private var mergedAccOnHeap: Boolean = false
 
@@ -166,7 +170,7 @@ class AggsHandlerCodeGenerator(
   def needMerge(
       mergedAccOffset: Int,
       mergedAccOnHeap: Boolean,
-      mergedAccExternalTypes: Array[TypeInformation[_]] = null): AggsHandlerCodeGenerator = {
+      mergedAccExternalTypes: Array[DataType] = null): AggsHandlerCodeGenerator = {
     this.mergedAccOffset = mergedAccOffset
     this.mergedAccOnHeap = mergedAccOnHeap
     this.mergedAccExternalTypes = mergedAccExternalTypes
@@ -190,9 +194,9 @@ class AggsHandlerCodeGenerator(
     */
   private def initialAggregateInformation(aggInfoList: AggregateInfoList): Unit = {
 
-    this.accTypeInfo = new RowType(
-      aggInfoList.getAccTypes.map(createInternalTypeFromTypeInfo): _*)
-    this.aggBufferSize = accTypeInfo.getArity
+    this.accTypeInfo = RowType.of(
+      aggInfoList.getAccTypes.map(fromDataTypeToLogicalType): _*)
+    this.aggBufferSize = accTypeInfo.getFieldCount
     var aggBufferOffset: Int = 0
 
     if (mergedAccExternalTypes == null) {
@@ -292,7 +296,7 @@ class AggsHandlerCodeGenerator(
     if (filterArg > 0) {
       val name = s"agg_${aggIndex}_filter"
       val filterType = inputFieldTypes(filterArg)
-      if (filterType != InternalTypes.BOOLEAN) {
+      if (!filterType.isInstanceOf[BooleanType]) {
         throw new TableException(s"filter arg must be boolean, but is $filterType, " +
             s"the aggregate is $aggName.")
       }
@@ -617,14 +621,14 @@ class AggsHandlerCodeGenerator(
       ctx.startNewLocalVariableStatement(methodName)
 
       // the mergedAcc is partial of mergedInput, such as <key, acc> in local-global, ignore keys
-      val internalAccTypes = mergedAccExternalTypes.map(createInternalTypeFromTypeInfo)
+      val internalAccTypes = mergedAccExternalTypes.map(fromDataTypeToLogicalType)
       val mergedAccType = if (mergedAccOffset > 0) {
         // concat padding types and acc types, use int type as padding
         // the padding types will be ignored
-        val padding = Array.range(0, mergedAccOffset).map(_ => InternalTypes.INT)
-        new RowType(padding ++ internalAccTypes: _*)
+        val padding = Array.range(0, mergedAccOffset).map(_ => new IntType())
+        RowType.of(padding ++ internalAccTypes: _*)
       } else {
-        new RowType(internalAccTypes: _*)
+        RowType.of(internalAccTypes: _*)
       }
 
       // bind input1 as otherAcc
@@ -679,7 +683,7 @@ class AggsHandlerCodeGenerator(
     }
 
     val aggValueTerm = newName("aggValue")
-    valueType = new RowType(valueExprs.map(_.resultType): _*)
+    valueType = RowType.of(valueExprs.map(_.resultType): _*)
 
     // always create a new result row
     val resultExpr = exprGenerator.generateResultExpression(
@@ -783,7 +787,8 @@ object AggsHandlerCodeGenerator {
       val openCode =
         s"""
            |$viewFieldTerm = ($viewTypeTerm) $STORE_TERM.$registerCall($parameters);
-           |$viewFieldInternalTerm = ${genToInternal(ctx, spec.dataViewTypeInfo, viewFieldTerm)};
+           |$viewFieldInternalTerm = ${genToInternal(
+                ctx, fromLegacyInfoToDataType(spec.dataViewTypeInfo), viewFieldTerm)};
          """.stripMargin
       ctx.addReusableOpenStatement(openCode)
 
@@ -811,7 +816,7 @@ object AggsHandlerCodeGenerator {
           s"""
              |$backupViewTerm = ($viewTypeTerm) $STORE_TERM.$registerCall($parameters);
              |$backupViewInternalTerm = ${genToInternal(
-                ctx, spec.dataViewTypeInfo, backupViewTerm)};
+                ctx, fromLegacyInfoToDataType(spec.dataViewTypeInfo), backupViewTerm)};
            """.stripMargin
         ctx.addReusableOpenStatement(backupOpenCode)
       }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/DeclarativeAggCodeGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/DeclarativeAggCodeGen.scala
index f980dd2..2d4b46e 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/DeclarativeAggCodeGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/DeclarativeAggCodeGen.scala
@@ -17,15 +17,16 @@
  */
 package org.apache.flink.table.codegen.agg
 
-import org.apache.flink.table.`type`.InternalType
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
 import org.apache.flink.table.codegen.CodeGenUtils.primitiveTypeTermForType
+import org.apache.flink.table.codegen.agg.AggsHandlerCodeGenerator.DISTINCT_KEY_TERM
 import org.apache.flink.table.codegen.{CodeGeneratorContext, ExprCodeGenerator, GeneratedExpression}
 import org.apache.flink.table.expressions.{ResolvedDistinctKeyReference, _}
 import org.apache.flink.table.functions.aggfunctions.DeclarativeAggregateFunction
 import org.apache.flink.table.plan.util.AggregateInfo
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
+import org.apache.flink.table.types.logical.LogicalType
+
 import org.apache.calcite.tools.RelBuilder
-import org.apache.flink.table.codegen.agg.AggsHandlerCodeGenerator.DISTINCT_KEY_TERM
 
 import scala.collection.JavaConverters._
 
@@ -51,14 +52,14 @@ class DeclarativeAggCodeGen(
     mergedAccOffset: Int,
     aggBufferOffset: Int,
     aggBufferSize: Int,
-    inputTypes: Seq[InternalType],
+    inputTypes: Seq[LogicalType],
     constantExprs: Seq[GeneratedExpression],
     relBuilder: RelBuilder)
   extends AggCodeGen {
 
   private val function = aggInfo.function.asInstanceOf[DeclarativeAggregateFunction]
 
-  private val bufferTypes = aggInfo.externalAccTypes.map(createInternalTypeFromTypeInfo)
+  private val bufferTypes = aggInfo.externalAccTypes.map(fromDataTypeToLogicalType)
   private val bufferIndexes = Array.range(aggBufferOffset, aggBufferOffset + bufferTypes.length)
   private val bufferTerms = function.aggBufferAttributes
       .map(a => s"agg${aggInfo.aggIndex}_${a.getName}")
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/DistinctAggCodeGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/DistinctAggCodeGen.scala
index 45ca64e..2898bc6 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/DistinctAggCodeGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/DistinctAggCodeGen.scala
@@ -18,9 +18,6 @@
 
 package org.apache.flink.table.codegen.agg
 
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
-import org.apache.flink.table.`type`.{InternalType, RowType}
 import org.apache.flink.table.api.TableException
 import org.apache.flink.table.api.dataview.MapView
 import org.apache.flink.table.codegen.CodeGenUtils.{newName, _}
@@ -31,8 +28,12 @@ import org.apache.flink.table.codegen.{CodeGeneratorContext, ExprCodeGenerator,
 import org.apache.flink.table.dataformat.GenericRow
 import org.apache.flink.table.expressions.{Expression, RexNodeConverter}
 import org.apache.flink.table.plan.util.DistinctInfo
+import org.apache.flink.table.types.DataType
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
 import org.apache.flink.util.Preconditions
 import org.apache.flink.util.Preconditions.checkArgument
+
 import org.apache.calcite.tools.RelBuilder
 
 import java.lang.{Long => JLong}
@@ -78,11 +79,11 @@ class DistinctAggCodeGen(
   val ITERABLE: String = className[java.lang.Iterable[_]]
 
   val aggCount: Int = innerAggCodeGens.length
-  val externalAccType: TypeInformation[_] = distinctInfo.accType
-  val internalAccType: InternalType = createInternalTypeFromTypeInfo(externalAccType)
-  val keyType: TypeInformation[_] = distinctInfo.keyType
-  val internalKeyType: InternalType = createInternalTypeFromTypeInfo(keyType)
-  val keyTypeTerm: String = keyType.getTypeClass.getCanonicalName
+  val externalAccType: DataType = distinctInfo.accType
+  val internalAccType: LogicalType = fromDataTypeToLogicalType(externalAccType)
+  val keyType: DataType = distinctInfo.keyType
+  val internalKeyType: LogicalType = fromDataTypeToLogicalType(keyType)
+  val keyTypeTerm: String = keyType.getConversionClass.getCanonicalName
   val distinctAccTerm: String = s"distinct_view_$distinctIndex"
   val distinctBackupAccTerm: String = s"distinct_backup_view_$distinctIndex"
 
@@ -377,7 +378,7 @@ class DistinctAggCodeGen(
     // the key expression of MapView
     if (fieldExprs.length > 1) {
       val keyTerm = newName(DISTINCT_KEY_TERM)
-      val valueType = new RowType(
+      val valueType = RowType.of(
         fieldExprs.map(_.resultType): _*)
 
       // always create a new result row
@@ -409,7 +410,7 @@ class DistinctAggCodeGen(
     */
   private def generateAccumulatorAccess(
     ctx: CodeGeneratorContext,
-    inputType: InternalType,
+    inputType: LogicalType,
     inputTerm: String,
     index: Int,
     useStateDataView: Boolean,
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/ImperativeAggCodeGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/ImperativeAggCodeGen.scala
index a40f79a..5d0c7ee 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/ImperativeAggCodeGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/ImperativeAggCodeGen.scala
@@ -17,20 +17,20 @@
  */
 package org.apache.flink.table.codegen.agg
 
-import org.apache.flink.api.common.typeinfo.TypeInformation
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
-import org.apache.flink.table.`type`.{InternalType, InternalTypeUtils, RowType}
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.GenerateUtils.generateFieldAccess
 import org.apache.flink.table.codegen.agg.AggsHandlerCodeGenerator._
 import org.apache.flink.table.codegen.{CodeGenException, CodeGeneratorContext, ExprCodeGenerator, GeneratedExpression}
-import org.apache.flink.table.dataformat.{GenericRow, UpdatableRow}
+import org.apache.flink.table.dataformat.{BaseRow, GenericRow, UpdatableRow}
 import org.apache.flink.table.dataview.DataViewSpec
 import org.apache.flink.table.expressions.{Expression, ResolvedAggInputReference, ResolvedDistinctKeyReference, RexNodeConverter}
 import org.apache.flink.table.functions.AggregateFunction
 import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils.{getAggFunctionUDIMethod, getAggUserDefinedInputTypes, getUserDefinedMethod, internalTypesToClasses, signatureToString}
 import org.apache.flink.table.plan.util.AggregateInfo
-import org.apache.flink.table.typeutils.BaseRowTypeInfo
+import org.apache.flink.table.types.ClassLogicalTypeConverter.getInternalClassForType
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
+import org.apache.flink.table.types.{ClassDataTypeConverter, DataType, PlannerTypeUtils}
 import org.apache.flink.table.util.SingleElementIterator
 
 import org.apache.calcite.tools.RelBuilder
@@ -65,12 +65,12 @@ class ImperativeAggCodeGen(
     mergedAccOffset: Int,
     aggBufferOffset: Int,
     aggBufferSize: Int,
-    inputTypes: Seq[InternalType],
+    inputTypes: Seq[LogicalType],
     constantExprs: Seq[GeneratedExpression],
     relBuilder: RelBuilder,
     hasNamespace: Boolean,
     mergedAccOnHeap: Boolean,
-    mergedAccExternalType: TypeInformation[_],
+    mergedAccExternalType: DataType,
     inputFieldCopy: Boolean)
   extends AggCodeGen {
 
@@ -84,32 +84,29 @@ class ImperativeAggCodeGen(
   val aggIndex: Int = aggInfo.aggIndex
 
   val externalAccType = aggInfo.externalAccTypes(0)
-  private val internalAccType = createInternalTypeFromTypeInfo(externalAccType)
+  private val internalAccType = fromDataTypeToLogicalType(externalAccType)
 
   /** whether the acc type is an internal type.
     * Currently we only support GenericRow as internal acc type */
-  val isAccTypeInternal: Boolean = externalAccType match {
-    // current we only support GenericRow as internal ACC type
-    case t: BaseRowTypeInfo => true
-    case _ => false
-  }
+  val isAccTypeInternal: Boolean =
+    classOf[BaseRow].isAssignableFrom(externalAccType.getConversionClass)
 
   val accInternalTerm: String = s"agg${aggIndex}_acc_internal"
   val accExternalTerm: String = s"agg${aggIndex}_acc_external"
   val accTypeInternalTerm: String = if (isAccTypeInternal) {
     GENERIC_ROW
   } else {
-    boxedTypeTermForType(createInternalTypeFromTypeInfo(externalAccType))
+    boxedTypeTermForType(fromDataTypeToLogicalType(externalAccType))
   }
   val accTypeExternalTerm: String = boxedTypeTermForExternalType(externalAccType)
 
-  val argTypes: Array[InternalType] = {
+  val argTypes: Array[LogicalType] = {
     val types = inputTypes ++ constantExprs.map(_.resultType)
     aggInfo.argIndexes.map(types(_))
   }
 
   private val externalResultType = aggInfo.externalResultType
-  private val internalResultType = createInternalTypeFromTypeInfo(externalResultType)
+  private val internalResultType = fromDataTypeToLogicalType(externalResultType)
 
   private val rexNodeGen = new RexNodeConverter(relBuilder)
 
@@ -312,7 +309,7 @@ class ImperativeAggCodeGen(
     */
   def generateAccumulatorAccess(
     ctx: CodeGeneratorContext,
-    inputType: InternalType,
+    inputType: LogicalType,
     inputTerm: String,
     index: Int,
     viewSpecs: Array[DataViewSpec],
@@ -376,7 +373,7 @@ class ImperativeAggCodeGen(
                    |$fieldTerm = null;
                    |if (!${newExpr.nullTerm}) {
                    |  $fieldTerm = new $UPDATABLE_ROW(${newExpr.resultTerm}, ${
-                        InternalTypeUtils.getArity(fieldType)});
+                        PlannerTypeUtils.getArity(fieldType)});
                    |  ${generateDataViewFieldSetter(fieldTerm, viewSpecs, useBackupDataView)}
                    |}
                 """.stripMargin
@@ -467,7 +464,7 @@ class ImperativeAggCodeGen(
     }
 
     if (needMerge) {
-      val iterType = TypeInformation.of(classOf[JIterable[Any]])
+      val iterType = ClassDataTypeConverter.fromClassToDataType(classOf[JIterable[Any]])
       val methods =
         getUserDefinedMethod(function, "merge", Array(externalAccType, iterType))
           .getOrElse(
@@ -484,14 +481,15 @@ class ImperativeAggCodeGen(
         case _ =>
       }
 
-      if (iterableTypeClass != externalAccType.getTypeClass &&
+      val clazz = externalAccType.getConversionClass
+      if (iterableTypeClass != externalAccType.getConversionClass &&
           // iterableTypeClass can be GenericRow, so classOf[BaseRow] is assignable from it.
-          !InternalTypeUtils.getInternalClassForType(internalAccType).isAssignableFrom(
+          !getInternalClassForType(internalAccType).isAssignableFrom(
             iterableTypeClass.asInstanceOf[Class[_]])) {
         throw new CodeGenException(
           s"merge method in AggregateFunction ${function.getClass.getCanonicalName} does not " +
             s"have the correct Iterable type. Actually: $iterableTypeClass. " +
-            s"Expected: ${externalAccType.getTypeClass}")
+            s"Expected: $clazz")
       }
     }
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/AggCodeGenHelper.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/AggCodeGenHelper.scala
index 98b4c2a..5483c44 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/AggCodeGenHelper.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/AggCodeGenHelper.scala
@@ -19,21 +19,22 @@
 package org.apache.flink.table.codegen.agg.batch
 
 import org.apache.flink.api.common.ExecutionConfig
-import org.apache.flink.api.common.typeinfo.TypeInformation
 import org.apache.flink.runtime.util.SingleElementIterator
 import org.apache.flink.streaming.api.operators.OneInputStreamOperator
-import org.apache.flink.table.`type`.TypeConverters.{createInternalTypeFromTypeInfo, createInternalTypeInfoFromInternalType}
-import org.apache.flink.table.`type`.{ArrayType, InternalType, MapType, RowType, StringType}
 import org.apache.flink.table.codegen.CodeGenUtils.{boxedTypeTermForExternalType, genToExternal, genToInternal, newName, primitiveTypeTermForType}
 import org.apache.flink.table.codegen.OperatorCodeGenerator.STREAM_RECORD
 import org.apache.flink.table.codegen.{CodeGenUtils, CodeGeneratorContext, ExprCodeGenerator, GenerateUtils, GeneratedExpression, OperatorCodeGenerator}
 import org.apache.flink.table.dataformat.{BaseRow, GenericRow}
 import org.apache.flink.table.expressions.{CallExpression, Expression, ExpressionVisitor, FieldReferenceExpression, ResolvedAggInputReference, ResolvedAggLocalReference, RexNodeConverter, TypeLiteralExpression, UnresolvedReferenceExpression, ValueLiteralExpression}
 import org.apache.flink.table.functions.aggfunctions.DeclarativeAggregateFunction
-import org.apache.flink.table.functions.{AggregateFunction, UserDefinedFunction}
 import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils.{getAccumulatorTypeOfAggregateFunction, getAggUserDefinedInputTypes}
+import org.apache.flink.table.functions.{AggregateFunction, UserDefinedFunction}
 import org.apache.flink.table.generated.{GeneratedAggsHandleFunction, GeneratedOperator}
 import org.apache.flink.table.runtime.context.ExecutionContextImpl
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
+import org.apache.flink.table.types.logical.LogicalTypeRoot._
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
+import org.apache.flink.table.types.{DataType, InternalSerializers}
 
 import org.apache.calcite.rel.core.AggregateCall
 import org.apache.calcite.rex.RexNode
@@ -62,14 +63,14 @@ object AggCodeGenHelper {
 
   def getAggBufferTypes(
       inputType: RowType, auxGrouping: Array[Int], aggregates: Seq[UserDefinedFunction])
-    : Array[Array[InternalType]] = {
+    : Array[Array[LogicalType]] = {
     auxGrouping.map { index =>
-      Array(inputType.getFieldTypes()(index))
+      Array(inputType.getTypeAt(index))
     } ++ aggregates.map {
-      case a: DeclarativeAggregateFunction => a.getAggBufferTypes
+      case a: DeclarativeAggregateFunction => a.getAggBufferTypes.map(_.getLogicalType)
       case a: AggregateFunction[_, _] =>
-        Array(createInternalTypeFromTypeInfo(getAccumulatorTypeOfAggregateFunction(a)))
-    }.toArray[Array[InternalType]]
+        Array(fromDataTypeToLogicalType(getAccumulatorTypeOfAggregateFunction(a)))
+    }.toArray[Array[LogicalType]]
   }
 
   def getUdaggs(
@@ -81,7 +82,7 @@ object AggCodeGenHelper {
   }
 
   def projectRowType(rowType: RowType, mapping: Array[Int]): RowType = {
-    new RowType(mapping.map(rowType.getTypeAt), mapping.map(rowType.getFieldNames()(_)))
+    RowType.of(mapping.map(rowType.getTypeAt), mapping.map(rowType.getFieldNames.get(_)))
   }
 
   /**
@@ -131,12 +132,12 @@ object AggCodeGenHelper {
       aggCallToAggFunction: Seq[(AggregateCall, UserDefinedFunction)],
       aggArgs: Array[Array[Int]],
       aggregates: Seq[UserDefinedFunction],
-      aggResultTypes: Seq[TypeInformation[_]],
+      aggResultTypes: Seq[DataType],
       udaggs: Map[AggregateFunction[_, _], String],
       inputTerm: String,
       inputType: RowType,
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]],
+      aggBufferTypes: Array[Array[LogicalType]],
       outputType: RowType,
       forHashAgg: Boolean = false): (String, String, GeneratedExpression) = {
     // gen code to apply aggregate functions to grouping elements
@@ -214,9 +215,9 @@ object AggCodeGenHelper {
       inputType: RowType,
       auxGrouping: Array[Int],
       aggArgs: Array[Array[Int]],
-      aggBufferTypes: Array[Array[InternalType]]): Array[Array[(Int, InternalType)]] = {
+      aggBufferTypes: Array[Array[LogicalType]]): Array[Array[(Int, LogicalType)]] = {
     val auxGroupingMapping = auxGrouping.indices.map {
-      i => Array[(Int, InternalType)]((i, aggBufferTypes(i)(0)))
+      i => Array[(Int, LogicalType)]((i, aggBufferTypes(i)(0)))
     }.toArray
 
     val aggCallMapping = if (isMerge) {
@@ -236,7 +237,7 @@ object AggCodeGenHelper {
   def newLocalReference(
       ctx: CodeGeneratorContext,
       resultTerm: String,
-      resultType: InternalType): ResolvedAggLocalReference = {
+      resultType: LogicalType): ResolvedAggLocalReference = {
     val nullTerm = resultTerm + "IsNull"
     ctx.addReusableMember(s"${primitiveTypeTermForType(resultType)} $resultTerm;")
     ctx.addReusableMember(s"boolean $nullTerm;")
@@ -253,8 +254,8 @@ object AggCodeGenHelper {
       isMerge: Boolean,
       agg: DeclarativeAggregateFunction,
       aggIndex: Int,
-      argsMapping: Array[Array[(Int, InternalType)]],
-      aggBufferTypes: Array[Array[InternalType]]) extends ExpressionVisitor[Expression] {
+      argsMapping: Array[Array[(Int, LogicalType)]],
+      aggBufferTypes: Array[Array[LogicalType]]) extends ExpressionVisitor[Expression] {
 
     override def visitCall(call: CallExpression): Expression = {
       new CallExpression(
@@ -312,9 +313,9 @@ object AggCodeGenHelper {
       builder: RelBuilder,
       auxGrouping: Array[Int],
       aggregates: Seq[UserDefinedFunction],
-      argsMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]]): Seq[GeneratedExpression] = {
+      aggBufferTypes: Array[Array[LogicalType]]): Seq[GeneratedExpression] = {
     val exprCodegen = new ExprCodeGenerator(ctx, false)
     val converter = new RexNodeConverter(builder)
 
@@ -383,7 +384,7 @@ object AggCodeGenHelper {
           genToInternal(ctx, resultType, resultTerm),
           nullTerm,
           "",
-          createInternalTypeFromTypeInfo(resultType))
+          fromDataTypeToLogicalType(resultType))
     }
 
     val initAggBufferExprs = initAuxGroupingExprs ++ initAggCallBufferExprs
@@ -391,10 +392,10 @@ object AggCodeGenHelper {
 
     aggBufferExprs.zip(initAggBufferExprs).map {
       case (aggBufVar, initExpr) =>
-        val resultCode = aggBufVar.resultType match {
-          case _: StringType | _: RowType | _: ArrayType | _: MapType =>
-            val serializer = createInternalTypeInfoFromInternalType(aggBufVar.resultType)
-                .createSerializer(new ExecutionConfig)
+        val resultCode = aggBufVar.resultType.getTypeRoot match {
+          case VARCHAR | ROW | ARRAY | MULTISET | MAP =>
+            val serializer = InternalSerializers.create(
+              aggBufVar.resultType, new ExecutionConfig)
             val term = ctx.addReusableObject(
               serializer, "serializer", serializer.getClass.getCanonicalName)
             s"$term.copy(${initExpr.resultTerm})"
@@ -418,9 +419,9 @@ object AggCodeGenHelper {
       aggCallToAggFunction: Seq[(AggregateCall, UserDefinedFunction)],
       aggregates: Seq[UserDefinedFunction],
       udaggs: Map[AggregateFunction[_, _], String],
-      argsMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]],
+      aggBufferTypes: Array[Array[LogicalType]],
       aggBufferExprs: Seq[GeneratedExpression]): String = {
     if (isMerge) {
       genMergeFlatAggregateBuffer(
@@ -459,11 +460,11 @@ object AggCodeGenHelper {
       grouping: Array[Int],
       auxGrouping: Array[Int],
       aggregates: Seq[UserDefinedFunction],
-      aggResultTypes: Seq[TypeInformation[_]],
+      aggResultTypes: Seq[DataType],
       udaggs: Map[AggregateFunction[_, _], String],
-      argsMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]],
+      aggBufferTypes: Array[Array[LogicalType]],
       aggBufferExprs: Seq[GeneratedExpression],
       outputType: RowType): GeneratedExpression = {
     val valueRow = CodeGenUtils.newName("valueRow")
@@ -481,11 +482,11 @@ object AggCodeGenHelper {
         aggBufferNames,
         aggBufferTypes,
         outputType)
-      val valueRowType = new RowType(getValueExprs.map(_.resultType): _*)
+      val valueRowType = RowType.of(getValueExprs.map(_.resultType): _*)
       resultCodegen.generateResultExpression(
         getValueExprs, valueRowType, classOf[GenericRow], valueRow)
     } else {
-      val valueRowType = new RowType(aggBufferExprs.map(_.resultType): _*)
+      val valueRowType = RowType.of(aggBufferExprs.map(_.resultType): _*)
       resultCodegen.generateResultExpression(
         aggBufferExprs, valueRowType, classOf[GenericRow], valueRow)
     }
@@ -500,11 +501,11 @@ object AggCodeGenHelper {
       builder: RelBuilder,
       auxGrouping: Array[Int],
       aggregates: Seq[UserDefinedFunction],
-      aggResultTypes: Seq[TypeInformation[_]],
+      aggResultTypes: Seq[DataType],
       udaggs: Map[AggregateFunction[_, _], String],
-      argsMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]],
+      aggBufferTypes: Array[Array[LogicalType]],
       outputType: RowType): Seq[GeneratedExpression] = {
     val exprCodegen = new ExprCodeGenerator(ctx, false)
 
@@ -533,7 +534,7 @@ object AggCodeGenHelper {
         val resultTerm = genToInternal(ctx, resultType,
           s"${udaggs(agg)}.getValue(${genToExternal(ctx, accType, aggBufferNames(aggIndex)(0))})")
         val nullTerm = s"${aggBufferNames(aggIndex)(0)}IsNull"
-        GeneratedExpression(resultTerm, nullTerm, "", createInternalTypeFromTypeInfo(resultType))
+        GeneratedExpression(resultTerm, nullTerm, "", fromDataTypeToLogicalType(resultType))
     }
 
     auxGroupingExprs ++ aggExprs
@@ -550,9 +551,9 @@ object AggCodeGenHelper {
       auxGrouping: Array[Int],
       aggregates: Seq[UserDefinedFunction],
       udaggs: Map[AggregateFunction[_, _], String],
-      argsMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]],
+      aggBufferTypes: Array[Array[LogicalType]],
       aggBufferExprs: Seq[GeneratedExpression]): String = {
     val exprCodegen = new ExprCodeGenerator(ctx, false).bindInput(inputType, inputTerm = inputTerm)
 
@@ -609,9 +610,9 @@ object AggCodeGenHelper {
       auxGrouping: Array[Int],
       aggCallToAggFunction: Seq[(AggregateCall, UserDefinedFunction)],
       udaggs: Map[AggregateFunction[_, _], String],
-      argsMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]],
+      aggBufferTypes: Array[Array[LogicalType]],
       aggBufferExprs: Seq[GeneratedExpression]): String = {
     val exprCodegen = new ExprCodeGenerator(ctx, false).bindInput(inputType, inputTerm = inputTerm)
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/AggWithoutKeysCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/AggWithoutKeysCodeGenerator.scala
index 0b5f71b..f4bd20f 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/AggWithoutKeysCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/AggWithoutKeysCodeGenerator.scala
@@ -19,7 +19,6 @@
 package org.apache.flink.table.codegen.agg.batch
 
 import org.apache.flink.streaming.api.operators.OneInputStreamOperator
-import org.apache.flink.table.`type`.RowType
 import org.apache.flink.table.codegen.{CodeGenUtils, CodeGeneratorContext}
 import org.apache.flink.table.codegen.OperatorCodeGenerator.generateCollect
 import org.apache.flink.table.codegen.agg.batch.AggCodeGenHelper.genSortAggCodes
@@ -28,6 +27,7 @@ import org.apache.flink.table.functions.AggregateFunction
 import org.apache.flink.table.generated.GeneratedOperator
 import org.apache.flink.table.plan.util.AggregateInfoList
 import org.apache.flink.table.runtime.TableStreamOperator
+import org.apache.flink.table.types.logical.RowType
 
 import org.apache.calcite.tools.RelBuilder
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashAggCodeGenHelper.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashAggCodeGenHelper.scala
index e1336ca..598efb9 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashAggCodeGenHelper.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashAggCodeGenHelper.scala
@@ -18,10 +18,8 @@
 
 package org.apache.flink.table.codegen.agg.batch
 
-import org.apache.flink.api.common.typeinfo.TypeInformation
 import org.apache.flink.api.java.tuple.{Tuple2 => JTuple2}
 import org.apache.flink.metrics.Gauge
-import org.apache.flink.table.`type`.{InternalType, RowType}
 import org.apache.flink.table.codegen.CodeGenUtils.{binaryRowFieldSetAccess, binaryRowSetNull}
 import org.apache.flink.table.codegen.agg.batch.AggCodeGenHelper.buildAggregateArgsMapping
 import org.apache.flink.table.codegen.sort.SortCodeGenerator
@@ -34,6 +32,8 @@ import org.apache.flink.table.generated.{NormalizedKeyComputer, RecordComparator
 import org.apache.flink.table.plan.util.SortUtil
 import org.apache.flink.table.runtime.aggregate.{BytesHashMap, BytesHashMapSpillMemorySegmentPool}
 import org.apache.flink.table.runtime.sort.BufferedKVExternalSorter
+import org.apache.flink.table.types.DataType
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
 import org.apache.flink.table.typeutils.BinaryRowSerializer
 
 import org.apache.calcite.rel.core.AggregateCall
@@ -49,8 +49,12 @@ object HashAggCodeGenHelper {
       aggBufferTypesTerm: String,
       aggMapKeyType: RowType,
       aggBufferType: RowType): Unit = {
-    ctx.addReusableObjectWithName(aggMapKeyType.getFieldTypes, aggMapKeyTypesTerm)
-    ctx.addReusableObjectWithName(aggBufferType.getFieldTypes, aggBufferTypesTerm)
+    ctx.addReusableObjectWithName(
+      aggMapKeyType.getChildren.toArray(Array[LogicalType]()),
+      aggMapKeyTypesTerm)
+    ctx.addReusableObjectWithName(
+      aggBufferType.getChildren.toArray(Array[LogicalType]()),
+      aggBufferTypesTerm)
   }
 
   private[flink] def prepareHashAggMap(
@@ -93,10 +97,10 @@ object HashAggCodeGenHelper {
     ctx.addReusableOutputRecord(outputType, outputClass, outputTerm)
     ctx.addReusableMember(
       s"private transient $binaryRow $reuseAggMapKeyTerm = " +
-          s"new $binaryRow(${aggMapKeyType.getArity});")
+          s"new $binaryRow(${aggMapKeyType.getFieldCount});")
     ctx.addReusableMember(
       s"private transient $binaryRow $reuseAggBufferTerm = " +
-          s"new $binaryRow(${aggBufferType.getArity});")
+          s"new $binaryRow(${aggBufferType.getFieldCount});")
     ctx.addReusableMember(
       s"private transient $mapEntryTypeTerm $reuseAggMapEntryTerm = " +
           s"new $mapEntryTypeTerm($reuseAggMapKeyTerm, $reuseAggBufferTerm);"
@@ -117,7 +121,7 @@ object HashAggCodeGenHelper {
       aggregates: Seq[UserDefinedFunction],
       currentAggBufferTerm: String,
       aggBufferRowType: RowType,
-      aggBufferTypes: Array[Array[InternalType]],
+      aggBufferTypes: Array[Array[LogicalType]],
       outputTerm: String,
       outputType: RowType,
       groupKeyTerm: String,
@@ -170,7 +174,7 @@ object HashAggCodeGenHelper {
   }
 
   private[flink] def buildAggregateAggBuffMapping(
-      aggBufferTypes: Array[Array[InternalType]]): Array[Array[(Int, InternalType)]] = {
+      aggBufferTypes: Array[Array[LogicalType]]): Array[Array[(Int, LogicalType)]] = {
     var aggBuffOffset = 0
     val mapping = for (aggIndex <- aggBufferTypes.indices) yield {
       val types = aggBufferTypes(aggIndex)
@@ -227,8 +231,8 @@ object HashAggCodeGenHelper {
       auxGrouping: Array[Int],
       aggregates: Seq[UserDefinedFunction],
       aggCallToAggFunction: Seq[(AggregateCall, UserDefinedFunction)],
-      argsMapping: Array[Array[(Int, InternalType)]],
-      aggBuffMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
+      aggBuffMapping: Array[Array[(Int, LogicalType)]],
       currentAggBufferTerm: String,
       aggBufferRowType: RowType): GeneratedExpression = {
     if (isMerge) {
@@ -265,8 +269,8 @@ object HashAggCodeGenHelper {
       builder: RelBuilder,
       auxGrouping: Array[Int],
       aggregates: Seq[UserDefinedFunction],
-      argsMapping: Array[Array[(Int, InternalType)]],
-      aggBuffMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
+      aggBuffMapping: Array[Array[(Int, LogicalType)]],
       outputTerm: String,
       outputType: RowType,
       inputTerm: String,
@@ -279,7 +283,7 @@ object HashAggCodeGenHelper {
         .bindInput(inputType, inputTerm = inputTerm)
         .bindSecondInput(aggBufferType, inputTerm = aggBufferTerm)
     val resultExpr = if (isFinal) {
-      val bindRefOffset = inputType.getArity
+      val bindRefOffset = inputType.getFieldCount
       val getAuxGroupingExprs = auxGrouping.indices.map { idx =>
         val (_, resultType) = aggBuffMapping(idx)(0)
         new ResolvedAggInputReference("aux_group", bindRefOffset + idx, resultType)
@@ -294,7 +298,7 @@ object HashAggCodeGenHelper {
 
       val getValueExprs = getAuxGroupingExprs ++ getAggValueExprs
       val aggValueTerm = CodeGenUtils.newName("aggVal")
-      val valueType = new RowType(getValueExprs.map(_.resultType): _*)
+      val valueType = RowType.of(getValueExprs.map(_.resultType): _*)
       exprCodegen.generateResultExpression(
         getValueExprs,
         valueType,
@@ -327,8 +331,8 @@ object HashAggCodeGenHelper {
       offset: Int,
       agg: DeclarativeAggregateFunction,
       aggIndex: Int,
-      argsMapping: Array[Array[(Int, InternalType)]],
-      aggBuffMapping: Array[Array[(Int, InternalType)]]) extends ExpressionVisitor[Expression] {
+      argsMapping: Array[Array[(Int, LogicalType)]],
+      aggBuffMapping: Array[Array[(Int, LogicalType)]]) extends ExpressionVisitor[Expression] {
 
     override def visitCall(call: CallExpression): Expression = {
       new CallExpression(
@@ -386,8 +390,8 @@ object HashAggCodeGenHelper {
       currentAggBufferTerm: String,
       auxGrouping: Array[Int],
       aggregates: Seq[UserDefinedFunction],
-      argsMapping: Array[Array[(Int, InternalType)]],
-      aggBuffMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
+      aggBuffMapping: Array[Array[(Int, LogicalType)]],
       aggBufferType: RowType): GeneratedExpression = {
     val exprCodegen = new ExprCodeGenerator(ctx, false)
         .bindInput(inputType, inputTerm = inputTerm)
@@ -396,7 +400,7 @@ object HashAggCodeGenHelper {
     val mergeExprs = aggregates.zipWithIndex.flatMap {
       case (agg: DeclarativeAggregateFunction, aggIndex) =>
         val idx = auxGrouping.length + aggIndex
-        val bindRefOffset = inputType.getArity
+        val bindRefOffset = inputType.getFieldCount
         agg.mergeExpressions.map(
           _.accept(ResolveReference(
             ctx, isMerge = true, bindRefOffset, agg, idx, argsMapping, aggBuffMapping)))
@@ -404,9 +408,11 @@ object HashAggCodeGenHelper {
 
     val aggBufferTypeWithoutAuxGrouping = if (auxGrouping.nonEmpty) {
       // auxGrouping does not need merge-code
-      new RowType(
-        aggBufferType.getFieldTypes.slice(auxGrouping.length, aggBufferType.getArity),
-        aggBufferType.getFieldNames.slice(auxGrouping.length, aggBufferType.getArity))
+      RowType.of(
+        aggBufferType.getChildren.slice(auxGrouping.length, aggBufferType.getFieldCount)
+            .toArray[LogicalType],
+        aggBufferType.getFieldNames.slice(auxGrouping.length, aggBufferType.getFieldCount)
+            .toArray[String])
     } else {
       aggBufferType
     }
@@ -440,8 +446,8 @@ object HashAggCodeGenHelper {
       currentAggBufferTerm: String,
       auxGrouping: Array[Int],
       aggCallToAggFunction: Seq[(AggregateCall, UserDefinedFunction)],
-      argsMapping: Array[Array[(Int, InternalType)]],
-      aggBuffMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
+      aggBuffMapping: Array[Array[(Int, LogicalType)]],
       aggBufferType: RowType): GeneratedExpression = {
     val exprCodegen = new ExprCodeGenerator(ctx, false)
         .bindInput(inputType, inputTerm = inputTerm)
@@ -450,7 +456,7 @@ object HashAggCodeGenHelper {
     val accumulateExprsWithFilterArgs = aggCallToAggFunction.zipWithIndex.flatMap {
       case (aggCallToAggFun, aggIndex) =>
         val idx = auxGrouping.length + aggIndex
-        val bindRefOffset = inputType.getArity
+        val bindRefOffset = inputType.getFieldCount
         val aggCall = aggCallToAggFun._1
         aggCallToAggFun._2 match {
           case agg: DeclarativeAggregateFunction =>
@@ -552,14 +558,14 @@ object HashAggCodeGenHelper {
       groupingAndAuxGrouping: (Array[Int], Array[Int]),
       aggCallToAggFunction: Seq[(AggregateCall, UserDefinedFunction)],
       aggArgs: Array[Array[Int]],
-      aggResultTypes: Seq[TypeInformation[_]],
+      aggResultTypes: Seq[DataType],
       udaggs: Map[AggregateFunction[_, _], String],
       logTerm: String,
       aggregateMapTerm: String,
       aggMapKVTypesTerm: (String, String),
       aggMapKVRowType: (RowType, RowType),
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]],
+      aggBufferTypes: Array[Array[LogicalType]],
       outputTerm: String,
       outputType: RowType,
       outputResultFromMap: String,
@@ -713,7 +719,7 @@ object HashAggCodeGenHelper {
       aggCallToAggFunction: Seq[(AggregateCall, UserDefinedFunction)],
       aggArgs: Array[Array[Int]],
       aggregates: Seq[UserDefinedFunction],
-      aggResultTypes: Seq[TypeInformation[_]],
+      aggResultTypes: Seq[DataType],
       udaggs: Map[AggregateFunction[_, _], String],
       mapTerm: String,
       mapKVRowTypes: (RowType, RowType),
@@ -722,7 +728,7 @@ object HashAggCodeGenHelper {
       outputTerm: String,
       outputType: RowType,
       aggBufferNames: Array[Array[String]],
-      aggBufferTypes: Array[Array[InternalType]]): String = {
+      aggBufferTypes: Array[Array[LogicalType]]): String = {
     val (groupKeyRowType, aggBufferRowType) = mapKVRowTypes
     val keyTerm = CodeGenUtils.newName("key")
     val lastKeyTerm = CodeGenUtils.newName("lastKey")
@@ -730,9 +736,9 @@ object HashAggCodeGenHelper {
 
     val joinedRow = classOf[JoinedRow].getName
     val fallbackInputTerm = ctx.addReusableLocalVariable(joinedRow, "fallbackInput")
-    val fallbackInputType = new RowType(
-      groupKeyRowType.getFieldTypes ++ aggBufferRowType.getFieldTypes,
-      groupKeyRowType.getFieldNames ++ aggBufferRowType.getFieldNames)
+    val fallbackInputType = RowType.of(
+      (groupKeyRowType.getChildren ++ aggBufferRowType.getChildren).toArray,
+      (groupKeyRowType.getFieldNames ++ aggBufferRowType.getFieldNames).toArray)
 
     val (initAggBufferCode, updateAggBufferCode, resultExpr) = AggCodeGenHelper.genSortAggCodes(
       isMerge = true,
@@ -807,7 +813,7 @@ object HashAggCodeGenHelper {
       keyComputerTerm: String,
       recordComparatorTerm: String,
       aggMapKeyType: RowType) : String = {
-    val keyFieldTypes = aggMapKeyType.getFieldTypes
+    val keyFieldTypes = aggMapKeyType.getChildren.toArray(Array[LogicalType]())
     val keys = keyFieldTypes.indices.toArray
     val orders = keys.map((_) => true)
     val nullsIsLast = SortUtil.getNullDefaultOrders(orders)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashAggCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashAggCodeGenerator.scala
index 0f99acf..1f58a11 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashAggCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashAggCodeGenerator.scala
@@ -19,7 +19,6 @@
 package org.apache.flink.table.codegen.agg.batch
 
 import org.apache.flink.streaming.api.operators.OneInputStreamOperator
-import org.apache.flink.table.`type`.RowType
 import org.apache.flink.table.codegen.{CodeGenUtils, CodeGeneratorContext, ProjectionCodeGenerator}
 import org.apache.flink.table.dataformat.{BaseRow, BinaryRow, GenericRow, JoinedRow}
 import org.apache.flink.table.functions.UserDefinedFunction
@@ -28,6 +27,7 @@ import org.apache.flink.table.generated.GeneratedOperator
 import org.apache.flink.table.plan.util.AggregateInfoList
 import org.apache.flink.table.runtime.TableStreamOperator
 import org.apache.flink.table.runtime.aggregate.{BytesHashMap, BytesHashMapSpillMemorySegmentPool}
+import org.apache.flink.table.types.logical.RowType
 
 import org.apache.calcite.tools.RelBuilder
 
@@ -58,7 +58,7 @@ class HashAggCodeGenerator(
   private lazy val aggBufferNames = AggCodeGenHelper.getAggBufferNames(auxGrouping, aggregates)
   private lazy val aggBufferTypes =
     AggCodeGenHelper.getAggBufferTypes(inputType, auxGrouping, aggregates)
-  private lazy val aggBufferRowType = new RowType(aggBufferTypes.flatten, aggBufferNames.flatten)
+  private lazy val aggBufferRowType = RowType.of(aggBufferTypes.flatten, aggBufferNames.flatten)
 
   def genWithKeys(
       reservedManagedMemory: Long, maxManagedMemory: Long)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashWindowCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashWindowCodeGenerator.scala
index aaa39d9..b3903aa 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashWindowCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/HashWindowCodeGenerator.scala
@@ -22,8 +22,6 @@ import org.apache.flink.api.java.tuple.{Tuple2 => JTuple2}
 import org.apache.flink.api.java.typeutils.ListTypeInfo
 import org.apache.flink.runtime.operators.sort.QuickSort
 import org.apache.flink.streaming.api.operators.OneInputStreamOperator
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
-import org.apache.flink.table.`type`.{InternalType, RowType}
 import org.apache.flink.table.api.Types
 import org.apache.flink.table.api.window.TimeWindow
 import org.apache.flink.table.calcite.FlinkRelBuilder.NamedWindowProperty
@@ -39,6 +37,8 @@ import org.apache.flink.table.plan.util.AggregateInfoList
 import org.apache.flink.table.runtime.TableStreamOperator
 import org.apache.flink.table.runtime.aggregate.{BytesHashMap, BytesHashMapSpillMemorySegmentPool}
 import org.apache.flink.table.runtime.sort.BinaryKVInMemorySortBuffer
+import org.apache.flink.table.types.TypeInfoLogicalTypeConverter.fromTypeInfoToLogicalType
+import org.apache.flink.table.types.logical.{LogicalType, RowType}
 import org.apache.flink.table.typeutils.BinaryRowSerializer
 import org.apache.flink.util.MutableObjectIterator
 
@@ -46,6 +46,8 @@ import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.tools.RelBuilder
 import org.apache.commons.math3.util.ArithmeticUtils
 
+import scala.collection.JavaConversions._
+
 /**
   * Tumbling window: like [[HashAggCodeGenerator]].
   *
@@ -88,11 +90,11 @@ class HashWindowCodeGenerator(
     isMerge,
     isFinal) {
 
-  private lazy val aggBufferRowType = new RowType(aggBufferTypes.flatten, aggBufferNames.flatten)
+  private lazy val aggBufferRowType = RowType.of(aggBufferTypes.flatten, aggBufferNames.flatten)
 
-  private lazy val aggMapKeyRowType = new RowType(
-    groupKeyRowType.getFieldTypes :+ timestampInternalType,
-    groupKeyRowType.getFieldNames :+ "assignedTs")
+  private lazy val aggMapKeyRowType = RowType.of(
+    (groupKeyRowType.getChildren :+ timestampInternalType).toArray,
+    (groupKeyRowType.getFieldNames :+ "assignedTs").toArray)
 
   def gen(
       inputType: RowType,
@@ -222,7 +224,7 @@ class HashWindowCodeGenerator(
                """.stripMargin
           val assignTimestampExpr =
             new GeneratedExpression(assignedWindows, "false", code,
-              createInternalTypeFromTypeInfo(new ListTypeInfo(Types.LONG)))
+              fromTypeInfoToLogicalType(new ListTypeInfo(Types.LONG)))
 
           // gen code to filter invalid overlapping windows
           val assignedTimestamp = newName("assignedTimestamp")
@@ -316,7 +318,7 @@ class HashWindowCodeGenerator(
 
   private def prepareAggMapKeyExpr(
       inputTerm: String,
-      inputType: InternalType,
+      inputType: LogicalType,
       assignedTimestampExpr: Option[GeneratedExpression],
       currentKeyType: RowType,
       currentKeyTerm: String,
@@ -429,8 +431,8 @@ class HashWindowCodeGenerator(
       bufferLimitSize: Int,
       outputType: RowType,
       aggregateMapTerm: String,
-      argsMapping: Array[Array[(Int, InternalType)]],
-      aggBuffMapping: Array[Array[(Int, InternalType)]],
+      argsMapping: Array[Array[(Int, LogicalType)]],
+      aggBuffMapping: Array[Array[(Int, LogicalType)]],
       aggKeyTypeTerm: String,
       aggBufferTypeTerm: String,
       aggMapKeyType: RowType,
@@ -466,9 +468,9 @@ class HashWindowCodeGenerator(
     val binaryRow = classOf[BinaryRow].getName
     val kvType = classOf[JTuple2[_,_]].getName
     ctx.addReusableMember(
-      s"transient $binaryRow $reuseAggMapKeyTerm = new $binaryRow(${aggMapKeyType.getArity});")
+      s"transient $binaryRow $reuseAggMapKeyTerm = new $binaryRow(${aggMapKeyType.getFieldCount});")
     ctx.addReusableMember(
-      s"transient $binaryRow $reuseAggBufferTerm = new $binaryRow(${aggBufferType.getArity});")
+      s"transient $binaryRow $reuseAggBufferTerm = new $binaryRow(${aggBufferType.getFieldCount});")
     ctx.addReusableMember(
       s"transient $kvType<$binaryRow, $binaryRow> $reuseKVTerm = " +
           s"new  $kvType<$binaryRow, $binaryRow>($reuseAggMapKeyTerm, $reuseAggBufferTerm);"
@@ -482,15 +484,15 @@ class HashWindowCodeGenerator(
     val bufferWindowElementWriterTerm = newName("prepareWinElementWriter")
     val exprCodegen = new ExprCodeGenerator(ctx, false)
     // TODO refine this. Is it possible to reuse grouping key projection?
-    val accessKeyExprs = for (idx <- 0 until aggMapKeyType.getArity - 1) yield
+    val accessKeyExprs = for (idx <- 0 until aggMapKeyType.getFieldCount - 1) yield
       GenerateUtils.generateFieldAccess(
         ctx, aggMapKeyType, reuseAggMapKeyTerm, idx)
     val accessTimestampExpr = GenerateUtils.generateFieldAccess(
       ctx,
       aggMapKeyType,
       reuseAggMapKeyTerm,
-      aggMapKeyType.getArity - 1)
-    val accessValExprs = for (idx <- 0 until aggBufferType.getArity) yield
+      aggMapKeyType.getFieldCount - 1)
+    val accessValExprs = for (idx <- 0 until aggBufferType.getFieldCount) yield
       GenerateUtils.generateFieldAccess(ctx, aggBufferType, reuseAggBufferTerm, idx)
     val accessExprs = (accessKeyExprs :+ GeneratedExpression(
       accessTimestampExpr.resultTerm,
@@ -619,8 +621,8 @@ class HashWindowCodeGenerator(
       inputType: RowType,
       outputType: RowType,
       aggregateMapTerm: String,
-      argsMapping: Array[Array[(Int, InternalType)]],
-      aggBuffMapping: Array[Array[(Int, InternalType)]]): String = {
+      argsMapping: Array[Array[(Int, LogicalType)]],
+      aggBuffMapping: Array[Array[(Int, LogicalType)]]): String = {
     val outputTerm = "hashAggOutput"
     ctx.addReusableOutputRecord(outputType, getOutputRowClass, outputTerm)
     val (reuseAggMapEntryTerm, reuseAggMapKeyTerm, reuseAggBufferTerm) =
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/SortAggCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/SortAggCodeGenerator.scala
index 0694e9f..7a6a9f0 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/SortAggCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/SortAggCodeGenerator.scala
@@ -19,7 +19,6 @@
 package org.apache.flink.table.codegen.agg.batch
 
 import org.apache.flink.streaming.api.operators.OneInputStreamOperator
-import org.apache.flink.table.`type`.RowType
 import org.apache.flink.table.codegen.OperatorCodeGenerator.generateCollect
 import org.apache.flink.table.codegen.{CodeGenUtils, CodeGeneratorContext, ProjectionCodeGenerator}
 import org.apache.flink.table.dataformat.{BaseRow, BinaryRow, JoinedRow}
@@ -27,6 +26,7 @@ import org.apache.flink.table.functions.AggregateFunction
 import org.apache.flink.table.generated.GeneratedOperator
 import org.apache.flink.table.plan.util.AggregateInfoList
 import org.apache.flink.table.runtime.TableStreamOperator
+import org.apache.flink.table.types.logical.RowType
 
 import org.apache.calcite.tools.RelBuilder
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/SortWindowCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/SortWindowCodeGenerator.scala
index 844006d..c99e850 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/SortWindowCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/SortWindowCodeGenerator.scala
@@ -19,7 +19,6 @@
 package org.apache.flink.table.codegen.agg.batch
 
 import org.apache.flink.streaming.api.operators.OneInputStreamOperator
-import org.apache.flink.table.`type`.RowType
 import org.apache.flink.table.api.window.TimeWindow
 import org.apache.flink.table.calcite.FlinkRelBuilder.NamedWindowProperty
 import org.apache.flink.table.codegen.CodeGenUtils.BINARY_ROW
@@ -31,6 +30,7 @@ import org.apache.flink.table.generated.GeneratedOperator
 import org.apache.flink.table.plan.logical.{LogicalWindow, SlidingGroupWindow, TumblingGroupWindow}
 import org.apache.flink.table.plan.util.AggregateInfoList
 import org.apache.flink.table.runtime.TableStreamOperator
+import org.apache.flink.table.types.logical.RowType
 
 import org.apache.calcite.rel.`type`.RelDataType
 import org.apache.calcite.tools.RelBuilder
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/WindowCodeGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/WindowCodeGenerator.scala
index fd9d83f..df2549f 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/WindowCodeGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/agg/batch/WindowCodeGenerator.scala
@@ -18,15 +18,8 @@
 
 package org.apache.flink.table.codegen.agg.batch
 
-import org.apache.calcite.avatica.util.DateTimeUtils
-import org.apache.calcite.rel.`type`.RelDataType
-import org.apache.calcite.rel.core.AggregateCall
-import org.apache.calcite.tools.RelBuilder
-import org.apache.commons.math3.util.ArithmeticUtils
 import org.apache.flink.table.JLong
-import org.apache.flink.table.`type`.TypeConverters.createInternalTypeFromTypeInfo
-import org.apache.flink.table.`type`.{InternalType, InternalTypes, RowType}
-import org.apache.flink.table.api.Types
+import org.apache.flink.table.api.DataTypes
 import org.apache.flink.table.api.window.TimeWindow
 import org.apache.flink.table.calcite.FlinkRelBuilder.NamedWindowProperty
 import org.apache.flink.table.calcite.FlinkTypeFactory
@@ -48,9 +41,19 @@ import org.apache.flink.table.plan.logical.{LogicalWindow, SlidingGroupWindow, T
 import org.apache.flink.table.plan.util.{AggregateInfoList, AggregateUtil}
 import org.apache.flink.table.runtime.util.RowIterator
 import org.apache.flink.table.runtime.window.grouping.{HeapWindowsGrouping, WindowsGrouping}
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromDataTypeToLogicalType
 import org.apache.flink.table.types.logical.LogicalTypeRoot.INTERVAL_DAY_TIME
+import org.apache.flink.table.types.logical._
 import org.apache.flink.table.types.logical.utils.LogicalTypeChecks.hasRoot
 
+import org.apache.calcite.avatica.util.DateTimeUtils
+import org.apache.calcite.rel.`type`.RelDataType
+import org.apache.calcite.rel.core.AggregateCall
+import org.apache.calcite.tools.RelBuilder
+import org.apache.commons.math3.util.ArithmeticUtils
+
+import scala.collection.JavaConversions._
+
 abstract class WindowCodeGenerator(
     relBuilder: RelBuilder,
     window: LogicalWindow,
@@ -66,8 +69,8 @@ abstract class WindowCodeGenerator(
     val isFinal: Boolean) {
 
   lazy val builder: RelBuilder = relBuilder.values(inputRowType)
-  lazy val timestampInternalType: InternalType =
-    if (inputTimeIsDate) InternalTypes.INT else InternalTypes.LONG
+  lazy val timestampInternalType: LogicalType =
+    if (inputTimeIsDate) new IntType() else new BigIntType()
   lazy val timestampInternalTypeName: String = if (inputTimeIsDate) "Int" else "Long"
   lazy val aggCallToAggFunction: Array[(AggregateCall, UserDefinedFunction)] =
     aggInfoList.aggInfos.map(info => (info.agg, info.function))
@@ -88,17 +91,17 @@ abstract class WindowCodeGenerator(
       Array(s"agg$idx")
   }
 
-  lazy val aggBufferTypes: Array[Array[InternalType]] = auxGrouping.map { index =>
-    Array(FlinkTypeFactory.toInternalType(inputRowType.getFieldList.get(index).getType))
+  lazy val aggBufferTypes: Array[Array[LogicalType]] = auxGrouping.map { index =>
+    Array(FlinkTypeFactory.toLogicalType(inputRowType.getFieldList.get(index).getType))
   } ++ aggregates.map {
-    case a: DeclarativeAggregateFunction => a.getAggBufferTypes
+    case a: DeclarativeAggregateFunction => a.getAggBufferTypes.map(_.getLogicalType)
     case a: AggregateFunction[_, _] =>
-      Array(getAccumulatorTypeOfAggregateFunction(a)).map(createInternalTypeFromTypeInfo)
-  }.toArray[Array[InternalType]]
+      Array(getAccumulatorTypeOfAggregateFunction(a)).map(fromDataTypeToLogicalType)
+  }.toArray[Array[LogicalType]]
 
-  lazy val groupKeyRowType = new RowType(
+  lazy val groupKeyRowType: RowType = RowType.of(
     grouping.map { index =>
-      FlinkTypeFactory.toInternalType(inputRowType.getFieldList.get(index).getType)
+      FlinkTypeFactory.toLogicalType(inputRowType.getFieldList.get(index).getType)
     }, grouping.map(inputRowType.getFieldNames.get(_)))
 
   // get udagg instance names
@@ -107,9 +110,9 @@ abstract class WindowCodeGenerator(
       .map(a => a -> CodeGenUtils.udfFieldName(a)).toMap
       .asInstanceOf[Map[AggregateFunction[_, _], String]]
 
-  lazy val windowedGroupKeyType: RowType = new RowType(
-    groupKeyRowType.getFieldTypes :+ timestampInternalType,
-    groupKeyRowType.getFieldNames :+ "assignedTs$")
+  lazy val windowedGroupKeyType: RowType = RowType.of(
+    (groupKeyRowType.getChildren :+ timestampInternalType).toArray,
+    (groupKeyRowType.getFieldNames :+ "assignedTs$").toArray)
 
   def getOutputRowClass: Class[_ <: BaseRow] =
     if (namedProperties.isEmpty && grouping.isEmpty) classOf[GenericRow] else classOf[JoinedRow]
@@ -118,14 +121,14 @@ abstract class WindowCodeGenerator(
       enablePreAccumulate: Boolean = true): RowType = {
     if (enablePreAccumulate) {
       val (groupKeyNames, groupKeyTypes) =
-        (groupKeyRowType.getFieldNames, groupKeyRowType.getFieldTypes)
+        (groupKeyRowType.getFieldNames, groupKeyRowType.getChildren.toArray(Array[LogicalType]()))
       val (aggBuffNames, aggBuffTypes) =
         (aggBufferNames.flatten, aggBufferTypes.flatten)
-      new RowType(
+      RowType.of(
         (groupKeyTypes :+ timestampInternalType) ++ aggBuffTypes,
-        (groupKeyNames :+ "assignedTs$") ++ aggBuffNames)
+        ((groupKeyNames :+ "assignedTs$") ++ aggBuffNames).toArray)
     } else {
-      FlinkTypeFactory.toInternalRowType(inputRowType)
+      FlinkTypeFactory.toLogicalRowType(inputRowType)
     }
   }
 
@@ -270,7 +273,7 @@ abstract class WindowCodeGenerator(
         outputType)
     } else {
       // output assigned window and agg buffer
-      val valueRowType = new RowType(
+      val valueRowType = RowType.of(
         timestampInternalType +: aggBufferExprs.map(_.resultType): _*)
       val wStartCode = if (inputTimeIsDate) {
         convertToIntValue(s"$currentWindow.getStart()")
@@ -377,7 +380,7 @@ abstract class WindowCodeGenerator(
           ctx,
           windowedGroupKeyType,
           inputTerm,
-          windowedGroupKeyType.getArity - 1)
+          windowedGroupKeyType.getFieldCount - 1)
         if (inputTimeIsDate) {
           val timestamp = ctx.addReusableLocalVariable("long", "timestamp")
           val convertToLongCode =
@@ -385,7 +388,7 @@ abstract class WindowCodeGenerator(
                |  ${ret.code}
                |  $timestamp = ${convertToLongValue(ret.resultTerm)};
            """.stripMargin
-          GeneratedExpression(timestamp, ret.nullTerm, convertToLongCode, InternalTypes.LONG)
+          GeneratedExpression(timestamp, ret.nullTerm, convertToLongCode, new BigIntType())
         } else {
           ret
         }
@@ -471,7 +474,7 @@ abstract class WindowCodeGenerator(
         val setResultExprs = grouping.indices.map(
           generateFieldAccess(
             ctx, groupKeyRowType, lastKey.get, _)) ++
-            (GeneratedExpression(lastTimestampTerm, NEVER_NULL, NO_CODE, InternalTypes.LONG)
+            (GeneratedExpression(lastTimestampTerm, NEVER_NULL, NO_CODE, new BigIntType())
                 +: aggBufferExprs)
         val setPanedAggResultExpr = exprCodegen.generateResultExpression(
           setResultExprs,
@@ -607,11 +610,11 @@ abstract class WindowCodeGenerator(
     } else {
       // window property fields always added at last when building the LogicalWindowAggregate
       val propOutputType = {
-        val outputFields = outputType.getFieldTypes
+        val outputFields = outputType.getChildren
         val lastFieldPos = outputFields.size - 1
         val propFields =
           for (offset <- lastFieldPos - propSize + 1 to lastFieldPos) yield outputFields(offset)
-        new RowType(propFields: _*)
+        RowType.of(propFields: _*)
       }
 
       // reusable row to set window property fields
@@ -679,7 +682,7 @@ abstract class WindowCodeGenerator(
       index: Int = 0): GeneratedExpression = {
     val exprCodegen = new ExprCodeGenerator(ctx, nullableInput = false)
         .bindInput(inputType, inputTerm = inputTerm)
-    val timeStampInLong = reinterpretCast(timeField, typeLiteral(Types.LONG), false)
+    val timeStampInLong = reinterpretCast(timeField, typeLiteral(DataTypes.BIGINT()), false)
     val millValue: Long = if (inputTimeIsDate) DateTimeUtils.MILLIS_PER_DAY else 1L
     val timeStampValue = times(timeStampInLong, literal(millValue))
     val remainder = mod(minus(timeStampValue, literal(windowStart)), literal(slideSize))
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/BinaryStringCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/BinaryStringCallGen.scala
index b2fa21f..6761f3a 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/BinaryStringCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/BinaryStringCallGen.scala
@@ -20,7 +20,7 @@ package org.apache.flink.table.codegen.calls
 
 import org.apache.flink.api.common.typeinfo.Types
 import org.apache.flink.api.java.typeutils.MapTypeInfo
-import org.apache.flink.table.`type`.{InternalType, InternalTypes}
+import org.apache.flink.table.api.DataTypes
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.GenerateUtils.{generateCallIfArgsNotNull, generateCallIfArgsNullable, generateStringResultCallIfArgsNotNull}
 import org.apache.flink.table.codegen.calls.ScalarOperatorGens._
@@ -28,6 +28,8 @@ import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression
 import org.apache.flink.table.dataformat.DataFormatConverters
 import org.apache.flink.table.functions.sql.FlinkSqlOperatorTable._
 import org.apache.flink.table.runtime.functions.SqlFunctionUtils
+import org.apache.flink.table.types.logical.{BooleanType, IntType, LogicalType, MapType, VarBinaryType, VarCharType}
+
 import org.apache.calcite.runtime.SqlFunctions
 import org.apache.calcite.sql.SqlOperator
 import org.apache.calcite.sql.fun.SqlTrimFunction.Flag.{BOTH, LEADING, TRAILING}
@@ -46,14 +48,14 @@ object BinaryStringCallGen {
       ctx: CodeGeneratorContext,
       operator: SqlOperator,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): Option[GeneratedExpression] = {
+      returnType: LogicalType): Option[GeneratedExpression] = {
     val generator = operator match {
 
       case LIKE =>
-        new LikeCallGen().generate(ctx, operands, InternalTypes.BOOLEAN)
+        new LikeCallGen().generate(ctx, operands, new BooleanType())
 
       case NOT_LIKE =>
-        generateNot(ctx, new LikeCallGen().generate(ctx, operands, InternalTypes.BOOLEAN))
+        generateNot(ctx, new LikeCallGen().generate(ctx, operands, new BooleanType()))
 
       case SUBSTRING | SUBSTR => generateSubString(ctx, operands)
 
@@ -103,7 +105,7 @@ object BinaryStringCallGen {
 
       case KEYVALUE => generateKeyValue(ctx, operands)
 
-      case HASH_CODE if operands.head.resultType == InternalTypes.STRING =>
+      case HASH_CODE if operands.head.resultType.isInstanceOf[VarCharType] =>
         generateHashCode(ctx, operands)
 
       case MD5 => generateMd5(ctx, operands)
@@ -174,7 +176,7 @@ object BinaryStringCallGen {
 
   private def toStringTerms(terms: Seq[String], operands: Seq[GeneratedExpression]) = {
     terms.zipWithIndex.map { case (term, index) =>
-      if (operands(index).resultType == InternalTypes.STRING) {
+      if (operands(index).resultType.isInstanceOf[VarCharType]) {
         s"$term.toString()"
       } else {
         term
@@ -184,7 +186,7 @@ object BinaryStringCallGen {
 
   private def safeToStringTerms(terms: Seq[String], operands: Seq[GeneratedExpression]) = {
     terms.zipWithIndex.map { case (term, index) =>
-      if (operands(index).resultType == InternalTypes.STRING) {
+      if (operands(index).resultType.isInstanceOf[VarCharType]) {
         s"$BINARY_STRING.safeToString($term)"
       } else {
         term
@@ -195,7 +197,7 @@ object BinaryStringCallGen {
   def generateConcat(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNullable(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNullable(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms => s"$BINARY_STRING.concat(${terms.mkString(", ")})"
     }
   }
@@ -203,7 +205,7 @@ object BinaryStringCallGen {
   def generateConcatWs(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNullable(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNullable(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms => s"$BINARY_STRING.concatWs(${terms.mkString(", ")})"
     }
   }
@@ -215,7 +217,7 @@ object BinaryStringCallGen {
       ctx: CodeGeneratorContext,
       left: GeneratedExpression,
       right: GeneratedExpression): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.BOOLEAN, Seq(left, right)) {
+    generateCallIfArgsNotNull(ctx, new BooleanType(), Seq(left, right)) {
       terms => s"(${terms.head}.equals(${terms(1)}))"
     }
   }
@@ -227,7 +229,7 @@ object BinaryStringCallGen {
       ctx: CodeGeneratorContext,
       left: GeneratedExpression,
       right: GeneratedExpression): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.BOOLEAN, Seq(left, right)) {
+    generateCallIfArgsNotNull(ctx, new BooleanType(), Seq(left, right)) {
       terms => s"!(${terms.head}.equals(${terms(1)}))"
     }
   }
@@ -235,7 +237,7 @@ object BinaryStringCallGen {
   def generateSubString(
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms => s"${terms.head}.substringSQL(${terms.drop(1).mkString(", ")})"
     }
   }
@@ -244,7 +246,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     str: GeneratedExpression,
     len: GeneratedExpression): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, Seq(str, len)) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), Seq(str, len)) {
       val emptyString = s"$BINARY_STRING.EMPTY_UTF8"
       terms => s"${terms(1)} <= 0 ? $emptyString : ${terms.head}.substringSQL(1, ${terms(1)})"
     }
@@ -254,7 +256,7 @@ object BinaryStringCallGen {
       ctx: CodeGeneratorContext,
       str: GeneratedExpression,
       len: GeneratedExpression): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, Seq(str, len)) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), Seq(str, len)) {
       terms =>
         s"""
            |${terms(1)} <= 0 ?
@@ -269,7 +271,7 @@ object BinaryStringCallGen {
   def generateCharLength(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.INT, operands) {
+    generateCallIfArgsNotNull(ctx, new IntType(), operands) {
       terms => s"${terms.head}.numChars()"
     }
   }
@@ -278,7 +280,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctions].getCanonicalName
-    generateCallIfArgsNotNull(ctx, InternalTypes.BOOLEAN, operands) {
+    generateCallIfArgsNotNull(ctx, new BooleanType(), operands) {
       terms => s"$className.similar(${toStringTerms(terms, operands)})"
     }
   }
@@ -305,7 +307,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNullable(ctx, InternalTypes.BOOLEAN, operands) {
+    generateCallIfArgsNullable(ctx, new BooleanType(), operands) {
       terms => s"$className.isDecimal(${safeToStringTerms(terms, operands)})"
     }
   }
@@ -314,7 +316,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNullable(ctx, InternalTypes.BOOLEAN, operands) {
+    generateCallIfArgsNullable(ctx, new BooleanType(), operands) {
       terms => s"$className.isDigit(${safeToStringTerms(terms, operands)})"
     }
   }
@@ -322,7 +324,7 @@ object BinaryStringCallGen {
   def generateAscii(
     ctx: CodeGeneratorContext,
     str: GeneratedExpression): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.INT, Seq(str)) {
+    generateCallIfArgsNotNull(ctx, new IntType(), Seq(str)) {
       terms => s"${terms.head}.getSizeInBytes() <= 0 ? 0 : (int) ${terms.head}.getByte(0)"
     }
   }
@@ -331,7 +333,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNullable(ctx, InternalTypes.BOOLEAN, operands) {
+    generateCallIfArgsNullable(ctx, new BooleanType(), operands) {
       terms => s"$className.isAlpha(${safeToStringTerms(terms, operands)})"
     }
   }
@@ -339,7 +341,7 @@ object BinaryStringCallGen {
   def generateUpper(
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms => s"${terms.head}.toUpperCase()"
     }
   }
@@ -347,7 +349,7 @@ object BinaryStringCallGen {
   def generateLower(
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms => s"${terms.head}.toLowerCase()"
     }
   }
@@ -365,7 +367,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNotNull(ctx, InternalTypes.INT, operands) {
+    generateCallIfArgsNotNull(ctx, new IntType(), operands) {
       terms => s"$className.position(${terms.mkString(",")})"
     }
   }
@@ -374,7 +376,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNotNull(ctx, InternalTypes.INT, operands) {
+    generateCallIfArgsNotNull(ctx, new IntType(), operands) {
       terms => s"$className.position(${terms.mkString(",")})"
     }
   }
@@ -383,7 +385,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNotNull(ctx, InternalTypes.INT, operands) {
+    generateCallIfArgsNotNull(ctx, new IntType(), operands) {
       terms =>
         val startPosition = if (operands.length < 3) 1 else terms(2)
         val nthAppearance = if (operands.length < 4) 1 else terms(3)
@@ -442,7 +444,7 @@ object BinaryStringCallGen {
   def generateReverse(
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms => s"${terms.head}.reverse()"
     }
   }
@@ -469,7 +471,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNullable(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNullable(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms =>
         s"$className.keyValue(${terms.mkString(",")})"
     }
@@ -479,7 +481,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNotNull(ctx, InternalTypes.INT, operands) {
+    generateCallIfArgsNotNull(ctx, new IntType(), operands) {
       terms => s"$className.hashCode(${terms.head}.toString())"
     }
   }
@@ -495,7 +497,7 @@ object BinaryStringCallGen {
       operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val digestTerm = ctx.addReusableMessageDigest(algorithm)
     if (operands.length == 1) {
-      generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+      generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
         terms =>s"${terms.head}.hash($digestTerm)"
       }
     } else {
@@ -538,7 +540,7 @@ object BinaryStringCallGen {
     if (operands.last.literal) {
       val digestTerm = ctx.addReusableSha2MessageDigest(operands.last)
       if (operands.length == 2) {
-        generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+        generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
           terms =>s"${terms.head}.hash($digestTerm)"
         }
       } else {
@@ -550,7 +552,7 @@ object BinaryStringCallGen {
       }
     } else {
       if (operands.length == 2) {
-        generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+        generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
           terms =>
             s"""${terms.head}.hash("SHA-" + ${terms.last})"""
         }
@@ -578,7 +580,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNotNull(ctx, InternalTypes.BINARY, operands) {
+    generateCallIfArgsNotNull(ctx, new VarBinaryType(VarBinaryType.MAX_LENGTH), operands) {
       terms => s"$className.fromBase64(${terms.head})"
     }
   }
@@ -605,7 +607,7 @@ object BinaryStringCallGen {
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    generateCallIfArgsNotNull(ctx, InternalTypes.BOOLEAN, operands) {
+    generateCallIfArgsNotNull(ctx, new BooleanType(), operands) {
       terms => s"$className.regExp(${toStringTerms(terms, operands)})"
     }
   }
@@ -631,7 +633,7 @@ object BinaryStringCallGen {
   def generateTrim(
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms =>
         val leading = compareEnum(terms.head, BOTH) || compareEnum(terms.head, LEADING)
         val trailing = compareEnum(terms.head, BOTH) || compareEnum(terms.head, TRAILING)
@@ -643,7 +645,7 @@ object BinaryStringCallGen {
   def generateTrimLeft(
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms => s"${terms.head}.trimLeft(${terms.drop(1).mkString(", ")})"
     }
   }
@@ -651,7 +653,7 @@ object BinaryStringCallGen {
   def generateTrimRight(
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.STRING, operands) {
+    generateCallIfArgsNotNull(ctx, new VarCharType(VarCharType.MAX_LENGTH), operands) {
       terms => s"${terms.head}.trimRight(${terms.drop(1).mkString(", ")})"
     }
   }
@@ -669,9 +671,10 @@ object BinaryStringCallGen {
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression]): GeneratedExpression = {
     val className = classOf[SqlFunctionUtils].getCanonicalName
-    val t = InternalTypes.createMapType(InternalTypes.STRING, InternalTypes.STRING)
-    val typeInfo = new MapTypeInfo[String, String](Types.STRING, Types.STRING)
-    val converter = DataFormatConverters.getConverterForTypeInfo(typeInfo)
+    val t = new MapType(
+      new VarCharType(VarCharType.MAX_LENGTH), new VarCharType(VarCharType.MAX_LENGTH))
+    val converter = DataFormatConverters.getConverterForDataType(
+      DataTypes.MAP(DataTypes.STRING(), DataTypes.STRING()))
     val converterTerm = ctx.addReusableObject(converter, "mapConverter")
     generateCallIfArgsNotNull(ctx, t, operands) {
       terms =>
@@ -684,7 +687,8 @@ object BinaryStringCallGen {
       ctx: CodeGeneratorContext,
       str: GeneratedExpression,
       charset: GeneratedExpression): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.BINARY, Seq(str, charset)) {
+    generateCallIfArgsNotNull(
+      ctx, new VarBinaryType(VarBinaryType.MAX_LENGTH), Seq(str, charset)) {
       terms => s"${terms.head}.toString().getBytes(${terms(1)}.toString())"
     }
   }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/CallGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/CallGenerator.scala
index a35bc5d..f7402eb 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/CallGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/CallGenerator.scala
@@ -18,8 +18,8 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
+import org.apache.flink.table.types.logical.LogicalType
 
 /**
   * Generator to generate a call expression. It is usually used when the generation
@@ -30,6 +30,6 @@ trait CallGenerator {
   def generate(
     ctx: CodeGeneratorContext,
     operands: Seq[GeneratedExpression],
-    returnType: InternalType): GeneratedExpression
+    returnType: LogicalType): GeneratedExpression
 
 }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ConstantCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ConstantCallGen.scala
index d51674a..682ab72 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ConstantCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ConstantCallGen.scala
@@ -18,9 +18,9 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
 import org.apache.flink.table.codegen.GenerateUtils.generateNonNullLiteral
+import org.apache.flink.table.types.logical.LogicalType
 
 /**
   * Generates a function call which returns a constant.
@@ -30,7 +30,7 @@ class ConstantCallGen(constantCode: String, constantValue: Any) extends CallGene
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = {
+      returnType: LogicalType): GeneratedExpression = {
     generateNonNullLiteral(returnType, constantCode, constantValue)
   }
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/CurrentTimePointCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/CurrentTimePointCallGen.scala
index 6b81d9d..e4dd220 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/CurrentTimePointCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/CurrentTimePointCallGen.scala
@@ -18,9 +18,10 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.{InternalType, InternalTypes}
-import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
 import org.apache.flink.table.codegen.GenerateUtils.generateNonNullField
+import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
+import org.apache.flink.table.types.logical.LogicalType
+import org.apache.flink.table.types.logical.LogicalTypeRoot.{DATE, TIMESTAMP_WITHOUT_TIME_ZONE, TIME_WITHOUT_TIME_ZONE}
 
 /**
   * Generates function call to determine current time point (as date/time/timestamp) in
@@ -31,24 +32,24 @@ class CurrentTimePointCallGen(local: Boolean) extends CallGenerator {
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = returnType match {
-    case InternalTypes.TIME if local =>
+      returnType: LogicalType): GeneratedExpression = returnType.getTypeRoot match {
+    case TIME_WITHOUT_TIME_ZONE if local =>
       val time = ctx.addReusableLocalTime()
       generateNonNullField(returnType, time)
 
-    case InternalTypes.TIMESTAMP if local =>
+    case TIMESTAMP_WITHOUT_TIME_ZONE if local =>
       val timestamp = ctx.addReusableLocalTimestamp()
       generateNonNullField(returnType, timestamp)
 
-    case InternalTypes.DATE =>
+    case DATE =>
       val date = ctx.addReusableDate()
       generateNonNullField(returnType, date)
 
-    case InternalTypes.TIME =>
+    case TIME_WITHOUT_TIME_ZONE =>
       val time = ctx.addReusableTime()
       generateNonNullField(returnType, time)
 
-    case InternalTypes.TIMESTAMP =>
+    case TIMESTAMP_WITHOUT_TIME_ZONE =>
       val timestamp = ctx.addReusableTimestamp()
       generateNonNullField(returnType, timestamp)
   }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/DivCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/DivCallGen.scala
index 41d3786..5b95f5c 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/DivCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/DivCallGen.scala
@@ -18,10 +18,10 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.{DecimalType, InternalType}
-import org.apache.flink.table.codegen.CodeGenUtils.DECIMAL
+import org.apache.flink.table.codegen.CodeGenUtils.DECIMAL_TERM
 import org.apache.flink.table.codegen.GenerateUtils.generateCallIfArgsNotNull
 import org.apache.flink.table.codegen.{CodeGenUtils, CodeGeneratorContext, GeneratedExpression}
+import org.apache.flink.table.types.logical.{DecimalType, LogicalType}
 import org.apache.flink.table.typeutils.TypeCheckUtils.isNumeric
 
 // DIV(T1, T2) - return integral part of the division; fractional truncated.
@@ -34,14 +34,14 @@ class DivCallGen extends CallGenerator {
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = {
+      returnType: LogicalType): GeneratedExpression = {
 
     val (arg1, type1) = (operands.head.resultTerm, operands.head.resultType)
     val (arg2, type2) = (operands(1).resultTerm, operands(1).resultType)
-    def toDec(arg: String) = s"$DECIMAL.castFrom($arg, 19, 0)"
+    def toDec(arg: String) = s"$DECIMAL_TERM.castFrom($arg, 19, 0)"
     def decDiv(arg1: String, arg2: String) = {
       val dt = returnType.asInstanceOf[DecimalType]
-      s"$DECIMAL.divideToIntegralValue($arg1, $arg2, ${dt.precision}, ${dt.scale})"
+      s"$DECIMAL_TERM.divideToIntegralValue($arg1, $arg2, ${dt.getPrecision}, ${dt.getScale})"
     }
 
     val code = (type1, type2) match {
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/FloorCeilCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/FloorCeilCallGen.scala
index b9ff8b2..f29b38f 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/FloorCeilCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/FloorCeilCallGen.scala
@@ -18,12 +18,13 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.calcite.avatica.util.TimeUnitRange
-import org.apache.calcite.avatica.util.TimeUnitRange._
-import org.apache.flink.table.`type`.{DecimalType, InternalType, InternalTypes}
 import org.apache.flink.table.codegen.CodeGenUtils.{getEnum, primitiveTypeTermForType, qualifyMethod}
-import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
 import org.apache.flink.table.codegen.GenerateUtils.generateCallIfArgsNotNull
+import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
+import org.apache.flink.table.types.logical.{LogicalType, LogicalTypeRoot}
+
+import org.apache.calcite.avatica.util.TimeUnitRange
+import org.apache.calcite.avatica.util.TimeUnitRange._
 
 import java.lang.reflect.Method
 import java.util.TimeZone
@@ -39,13 +40,13 @@ class FloorCeilCallGen(
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = operands.size match {
+      returnType: LogicalType): GeneratedExpression = operands.size match {
     // arithmetic
     case 1 =>
-      operands.head.resultType match {
-        case InternalTypes.FLOAT | InternalTypes.DOUBLE =>
+      operands.head.resultType.getTypeRoot match {
+        case LogicalTypeRoot.FLOAT | LogicalTypeRoot.DOUBLE =>
           super.generate(ctx, operands, returnType)
-        case _: DecimalType =>
+        case LogicalTypeRoot.DECIMAL =>
           generateCallIfArgsNotNull(ctx, returnType, operands) {
             operandResultTerms =>
               s"${qualifyMethod(arithmeticMethod)}(${operandResultTerms.mkString(", ")})"
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala
index 3de7ab6..9cc1e72 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/FunctionGenerator.scala
@@ -18,11 +18,13 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.calcite.avatica.util.{TimeUnit, TimeUnitRange}
+import org.apache.flink.table.functions.sql.FlinkSqlOperatorTable._
+import org.apache.flink.table.types.PlannerTypeUtils.isPrimitive
+import org.apache.flink.table.types.logical.LogicalTypeRoot._
+import org.apache.flink.table.types.logical.{LogicalType, LogicalTypeRoot}
+
 import org.apache.calcite.sql.SqlOperator
 import org.apache.calcite.util.BuiltInMethod
-import org.apache.flink.table.`type`._
-import org.apache.flink.table.functions.sql.FlinkSqlOperatorTable._
 
 import java.lang.reflect.Method
 
@@ -30,18 +32,15 @@ import scala.collection.mutable
 
 object FunctionGenerator {
 
-  // as a key to match any Decimal(p,s)
-  val ANY_DEC_TYPE: DecimalType = DecimalType.SYSTEM_DEFAULT
-
   val INTEGRAL_TYPES = Array(
-    InternalTypes.BYTE,
-    InternalTypes.SHORT,
-    InternalTypes.INT,
-    InternalTypes.LONG)
+    INTEGER,
+    SMALLINT,
+    INTEGER,
+    BIGINT)
 
-  val FRACTIONAL_TYPES = Array(InternalTypes.FLOAT, InternalTypes.DOUBLE)
+  val FRACTIONAL_TYPES = Array(FLOAT, DOUBLE)
 
-  private val sqlFunctions: mutable.Map[(SqlOperator, Seq[InternalType]), CallGenerator] =
+  private val sqlFunctions: mutable.Map[(SqlOperator, Seq[LogicalTypeRoot]), CallGenerator] =
     mutable.Map()
   // ----------------------------------------------------------------------------------------------
   // Arithmetic functions
@@ -49,243 +48,243 @@ object FunctionGenerator {
 
   addSqlFunctionMethod(
     LOG10,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.LOG10)
 
   addSqlFunctionMethod(
     LOG10,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.LOG10_DEC)
 
   addSqlFunctionMethod(
     LN,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.LN)
 
   addSqlFunctionMethod(
     LN,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.LN_DEC)
 
   addSqlFunctionMethod(
     EXP,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.EXP)
 
   addSqlFunctionMethod(
     EXP,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.EXP_DEC)
 
   addSqlFunctionMethod(
     POWER,
-    Seq(InternalTypes.DOUBLE, InternalTypes.DOUBLE),
+    Seq(DOUBLE, DOUBLE),
     BuiltInMethods.POWER_NUM_NUM)
 
   addSqlFunctionMethod(
     POWER,
-    Seq(InternalTypes.DOUBLE, ANY_DEC_TYPE),
+    Seq(DOUBLE, DECIMAL),
     BuiltInMethods.POWER_NUM_DEC)
 
   addSqlFunctionMethod(
     POWER,
-    Seq(ANY_DEC_TYPE, ANY_DEC_TYPE),
+    Seq(DECIMAL, DECIMAL),
     BuiltInMethods.POWER_DEC_DEC)
 
   addSqlFunctionMethod(
     POWER,
-    Seq(ANY_DEC_TYPE, InternalTypes.DOUBLE),
+    Seq(DECIMAL, DOUBLE),
     BuiltInMethods.POWER_DEC_NUM)
 
   addSqlFunctionMethod(
     ABS,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.ABS)
 
   addSqlFunctionMethod(
     ABS,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.ABS_DEC)
 
   addSqlFunction(
     FLOOR,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     new FloorCeilCallGen(BuiltInMethod.FLOOR.method))
 
   addSqlFunction(
     FLOOR,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     new FloorCeilCallGen(BuiltInMethods.FLOOR_DEC))
 
   addSqlFunction(
     CEIL,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     new FloorCeilCallGen(BuiltInMethod.CEIL.method))
 
   addSqlFunction(
     CEIL,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     new FloorCeilCallGen(BuiltInMethods.CEIL_DEC))
 
   addSqlFunctionMethod(
     SIN,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.SIN)
 
   addSqlFunctionMethod(
     SIN,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.SIN_DEC)
 
   addSqlFunctionMethod(
     COS,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.COS)
 
   addSqlFunctionMethod(
     COS,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.COS_DEC)
 
   addSqlFunctionMethod(
     TAN,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.TAN)
 
   addSqlFunctionMethod(
     TAN,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.TAN_DEC)
 
   addSqlFunctionMethod(
     COT,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.COT)
 
   addSqlFunctionMethod(
     COT,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.COT_DEC)
 
   addSqlFunctionMethod(
     ASIN,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.ASIN)
 
   addSqlFunctionMethod(
     ASIN,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.ASIN_DEC)
 
   addSqlFunctionMethod(
     ACOS,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.ACOS)
 
   addSqlFunctionMethod(
     ACOS,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.ACOS_DEC)
 
   addSqlFunctionMethod(
     ATAN,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.ATAN)
 
   addSqlFunctionMethod(
     ATAN,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.ATAN_DEC)
 
   addSqlFunctionMethod(
     ATAN2,
-    Seq(InternalTypes.DOUBLE, InternalTypes.DOUBLE),
+    Seq(DOUBLE, DOUBLE),
     BuiltInMethods.ATAN2_DOUBLE_DOUBLE)
 
   addSqlFunctionMethod(
     ATAN2,
-    Seq(ANY_DEC_TYPE, ANY_DEC_TYPE),
+    Seq(DECIMAL, DECIMAL),
     BuiltInMethods.ATAN2_DEC_DEC)
 
   addSqlFunctionMethod(
     DEGREES,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.DEGREES)
 
   addSqlFunctionMethod(
     DEGREES,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.DEGREES_DEC)
 
   addSqlFunctionMethod(
     RADIANS,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.RADIANS)
 
   addSqlFunctionMethod(
     RADIANS,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.RADIANS_DEC)
 
   addSqlFunctionMethod(
     SIGN,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.SIGN_DOUBLE)
 
   addSqlFunctionMethod(
     SIGN,
-    Seq(InternalTypes.INT),
+    Seq(INTEGER),
     BuiltInMethods.SIGN_INT)
 
   addSqlFunctionMethod(
     SIGN,
-    Seq(InternalTypes.LONG),
+    Seq(BIGINT),
     BuiltInMethods.SIGN_LONG)
 
   // note: calcite: SIGN(Decimal(p,s)) => Decimal(p,s). may return e.g. 1.0000
   addSqlFunctionMethod(
     SIGN,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.SIGN_DEC)
 
   addSqlFunctionMethod(
     ROUND,
-    Seq(InternalTypes.LONG, InternalTypes.INT),
+    Seq(BIGINT, INTEGER),
     BuiltInMethods.ROUND_LONG)
 
   addSqlFunctionMethod(
     ROUND,
-    Seq(InternalTypes.INT, InternalTypes.INT),
+    Seq(INTEGER, INTEGER),
     BuiltInMethods.ROUND_INT)
 
   addSqlFunctionMethod(
     ROUND,
-    Seq(ANY_DEC_TYPE, InternalTypes.INT),
+    Seq(DECIMAL, INTEGER),
     BuiltInMethods.ROUND_DEC)
 
   addSqlFunctionMethod(
     ROUND,
-    Seq(InternalTypes.DOUBLE, InternalTypes.INT),
+    Seq(DOUBLE, INTEGER),
     BuiltInMethods.ROUND_DOUBLE)
 
   addSqlFunctionMethod(
     ROUND,
-    Seq(InternalTypes.LONG),
+    Seq(BIGINT),
     BuiltInMethods.ROUND_LONG_0)
 
   addSqlFunctionMethod(
     ROUND,
-    Seq(InternalTypes.INT),
+    Seq(INTEGER),
     BuiltInMethods.ROUND_INT_0)
 
   addSqlFunctionMethod(
     ROUND,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.ROUND_DEC_0)
 
   addSqlFunctionMethod(
     ROUND,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.ROUND_DOUBLE_0)
 
   addSqlFunction(
@@ -310,57 +309,57 @@ object FunctionGenerator {
 
   addSqlFunction(
     RAND,
-    Seq(InternalTypes.INT),
+    Seq(INTEGER),
     new RandCallGen(isRandInteger = false, hasSeed = true))
 
   addSqlFunction(
     RAND_INTEGER,
-    Seq(InternalTypes.INT),
+    Seq(INTEGER),
     new RandCallGen(isRandInteger = true, hasSeed = false))
 
   addSqlFunction(
     RAND_INTEGER,
-    Seq(InternalTypes.INT, InternalTypes.INT),
+    Seq(INTEGER, INTEGER),
     new RandCallGen(isRandInteger = true, hasSeed = true))
 
   addSqlFunctionMethod(
     LOG,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.LOG)
 
   addSqlFunctionMethod(
     LOG,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.LOG_DEC)
 
   addSqlFunctionMethod(
     LOG,
-    Seq(InternalTypes.DOUBLE, InternalTypes.DOUBLE),
+    Seq(DOUBLE, DOUBLE),
     BuiltInMethods.LOG_WITH_BASE)
 
   addSqlFunctionMethod(
     LOG,
-    Seq(ANY_DEC_TYPE, ANY_DEC_TYPE),
+    Seq(DECIMAL, DECIMAL),
     BuiltInMethods.LOG_WITH_BASE_DEC)
 
   addSqlFunctionMethod(
     LOG,
-    Seq(ANY_DEC_TYPE, InternalTypes.DOUBLE),
+    Seq(DECIMAL, DOUBLE),
     BuiltInMethods.LOG_WITH_BASE_DEC_DOU)
 
   addSqlFunctionMethod(
     LOG,
-    Seq(InternalTypes.DOUBLE, ANY_DEC_TYPE),
+    Seq(DOUBLE, DECIMAL),
     BuiltInMethods.LOG_WITH_BASE_DOU_DEC)
 
   addSqlFunctionMethod(
     HEX,
-    Seq(InternalTypes.LONG),
+    Seq(BIGINT),
     BuiltInMethods.HEX_LONG)
 
   addSqlFunctionMethod(
     HEX,
-    Seq(InternalTypes.STRING),
+    Seq(VARCHAR),
     BuiltInMethods.HEX_STRING)
 
   // ----------------------------------------------------------------------------------------------
@@ -369,95 +368,95 @@ object FunctionGenerator {
 
   addSqlFunctionMethod(
     EXTRACT,
-    Seq(new GenericType(classOf[TimeUnitRange]), InternalTypes.LONG),
+    Seq(ANY, BIGINT),
     BuiltInMethod.UNIX_DATE_EXTRACT.method)
 
   addSqlFunctionMethod(
     EXTRACT,
-    Seq(new GenericType(classOf[TimeUnitRange]), InternalTypes.DATE),
+    Seq(ANY, DATE),
     BuiltInMethod.UNIX_DATE_EXTRACT.method)
 
   addSqlFunctionMethod(
     EXTRACT,
-    Seq(new GenericType(classOf[TimeUnitRange]), InternalTypes.TIME),
+    Seq(ANY, TIME_WITHOUT_TIME_ZONE),
     BuiltInMethods.UNIX_TIME_EXTRACT)
 
   addSqlFunctionMethod(
     EXTRACT,
-    Seq(new GenericType(classOf[TimeUnitRange]), InternalTypes.TIMESTAMP),
+    Seq(ANY, TIMESTAMP_WITHOUT_TIME_ZONE),
     BuiltInMethods.EXTRACT_FROM_TIMESTAMP)
 
   addSqlFunctionMethod(
     EXTRACT,
-    Seq(new GenericType(classOf[TimeUnitRange]), InternalTypes.INTERVAL_MILLIS),
+    Seq(ANY, INTERVAL_DAY_TIME),
     BuiltInMethods.EXTRACT_FROM_DATE)
 
   addSqlFunctionMethod(
     EXTRACT,
-    Seq(new GenericType(classOf[TimeUnitRange]), InternalTypes.INTERVAL_MONTHS),
+    Seq(ANY, INTERVAL_YEAR_MONTH),
     BuiltInMethods.EXTRACT_YEAR_MONTH)
 
   addSqlFunction(
     TIMESTAMP_DIFF,
     Seq(
-      new GenericType(classOf[TimeUnit]),
-      InternalTypes.TIMESTAMP,
-      InternalTypes.TIMESTAMP),
+      ANY,
+      TIMESTAMP_WITHOUT_TIME_ZONE,
+      TIMESTAMP_WITHOUT_TIME_ZONE),
     new TimestampDiffCallGen)
 
   addSqlFunction(
     TIMESTAMP_DIFF,
-    Seq(new GenericType(classOf[TimeUnit]), InternalTypes.TIMESTAMP, InternalTypes.DATE),
+    Seq(ANY, TIMESTAMP_WITHOUT_TIME_ZONE, DATE),
     new TimestampDiffCallGen)
 
   addSqlFunction(
     TIMESTAMP_DIFF,
-    Seq(new GenericType(classOf[TimeUnit]), InternalTypes.DATE, InternalTypes.TIMESTAMP),
+    Seq(ANY, DATE, TIMESTAMP_WITHOUT_TIME_ZONE),
     new TimestampDiffCallGen)
 
   addSqlFunction(
     TIMESTAMP_DIFF,
-    Seq(new GenericType(classOf[TimeUnit]), InternalTypes.DATE, InternalTypes.DATE),
+    Seq(ANY, DATE, DATE),
     new TimestampDiffCallGen)
 
   addSqlFunction(
     FLOOR,
-    Seq(InternalTypes.DATE, new GenericType(classOf[TimeUnitRange])),
+    Seq(DATE, ANY),
     new FloorCeilCallGen(
       BuiltInMethod.FLOOR.method,
       Some(BuiltInMethod.UNIX_DATE_FLOOR.method)))
 
   addSqlFunction(
     FLOOR,
-    Seq(InternalTypes.TIME, new GenericType(classOf[TimeUnitRange])),
+    Seq(TIME_WITHOUT_TIME_ZONE, ANY),
     new FloorCeilCallGen(
       BuiltInMethod.FLOOR.method,
       Some(BuiltInMethod.UNIX_DATE_FLOOR.method)))
 
   addSqlFunction(
     FLOOR,
-    Seq(InternalTypes.TIMESTAMP, new GenericType(classOf[TimeUnitRange])),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE, ANY),
     new FloorCeilCallGen(
       BuiltInMethod.FLOOR.method,
       Some(BuiltInMethods.TIMESTAMP_FLOOR)))
 
   addSqlFunction(
     CEIL,
-    Seq(InternalTypes.DATE, new GenericType(classOf[TimeUnitRange])),
+    Seq(DATE, ANY),
     new FloorCeilCallGen(
       BuiltInMethod.CEIL.method,
       Some(BuiltInMethod.UNIX_DATE_CEIL.method)))
 
   addSqlFunction(
     CEIL,
-    Seq(InternalTypes.TIME, new GenericType(classOf[TimeUnitRange])),
+    Seq(TIME_WITHOUT_TIME_ZONE, ANY),
     new FloorCeilCallGen(
       BuiltInMethod.CEIL.method,
       Some(BuiltInMethod.UNIX_DATE_CEIL.method)))
 
   addSqlFunction(
     CEIL,
-    Seq(InternalTypes.TIMESTAMP, new GenericType(classOf[TimeUnitRange])),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE, ANY),
     new FloorCeilCallGen(
       BuiltInMethod.CEIL.method,
       Some(BuiltInMethods.TIMESTAMP_CEIL)))
@@ -489,189 +488,189 @@ object FunctionGenerator {
 
   addSqlFunctionMethod(
     LOG2,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.LOG2)
 
   addSqlFunctionMethod(
     LOG2,
-    Seq(ANY_DEC_TYPE),
+    Seq(DECIMAL),
     BuiltInMethods.LOG2_DEC)
 
   addSqlFunctionMethod(
     SINH,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.SINH)
 
   addSqlFunctionMethod(
     SINH,
-    Seq(DecimalType.SYSTEM_DEFAULT),
+    Seq(DECIMAL),
     BuiltInMethods.SINH_DEC)
 
   addSqlFunctionMethod(
     COSH,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.COSH)
 
   addSqlFunctionMethod(
     COSH,
-    Seq(DecimalType.SYSTEM_DEFAULT),
+    Seq(DECIMAL),
     BuiltInMethods.COSH_DEC)
 
   addSqlFunctionMethod(
     TANH,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     BuiltInMethods.TANH)
 
   addSqlFunctionMethod(
     TANH,
-    Seq(DecimalType.SYSTEM_DEFAULT),
+    Seq(DECIMAL),
     BuiltInMethods.TANH_DEC)
 
   addSqlFunctionMethod(
     BITAND,
-    Seq(InternalTypes.BYTE, InternalTypes.BYTE),
+    Seq(INTEGER, INTEGER),
     BuiltInMethods.BITAND_BYTE)
 
   addSqlFunctionMethod(
     BITAND,
-    Seq(InternalTypes.SHORT, InternalTypes.SHORT),
+    Seq(SMALLINT, SMALLINT),
     BuiltInMethods.BITAND_SHORT)
 
   addSqlFunctionMethod(
     BITAND,
-    Seq(InternalTypes.INT, InternalTypes.INT),
+    Seq(INTEGER, INTEGER),
     BuiltInMethods.BITAND_INTEGER)
 
   addSqlFunctionMethod(
     BITAND,
-    Seq(InternalTypes.LONG, InternalTypes.LONG),
+    Seq(BIGINT, BIGINT),
     BuiltInMethods.BITAND_LONG)
 
   addSqlFunctionMethod(
     BITNOT,
-    Seq(InternalTypes.BYTE),
+    Seq(INTEGER),
     BuiltInMethods.BITNOT_BYTE)
 
   addSqlFunctionMethod(
     BITNOT,
-    Seq(InternalTypes.SHORT),
+    Seq(SMALLINT),
     BuiltInMethods.BITNOT_SHORT)
 
   addSqlFunctionMethod(
     BITNOT,
-    Seq(InternalTypes.INT),
+    Seq(INTEGER),
     BuiltInMethods.BITNOT_INTEGER)
 
   addSqlFunctionMethod(
     BITNOT,
-    Seq(InternalTypes.LONG),
+    Seq(BIGINT),
     BuiltInMethods.BITNOT_LONG)
 
   addSqlFunctionMethod(
     BITOR,
-    Seq(InternalTypes.BYTE, InternalTypes.BYTE),
+    Seq(INTEGER, INTEGER),
     BuiltInMethods.BITOR_BYTE)
 
   addSqlFunctionMethod(
     BITOR,
-    Seq(InternalTypes.SHORT, InternalTypes.SHORT),
+    Seq(SMALLINT, SMALLINT),
     BuiltInMethods.BITOR_SHORT)
 
   addSqlFunctionMethod(
     BITOR,
-    Seq(InternalTypes.INT, InternalTypes.INT),
+    Seq(INTEGER, INTEGER),
     BuiltInMethods.BITOR_INTEGER)
 
   addSqlFunctionMethod(
     BITOR,
-    Seq(InternalTypes.LONG, InternalTypes.LONG),
+    Seq(BIGINT, BIGINT),
     BuiltInMethods.BITOR_LONG)
 
   addSqlFunctionMethod(
     BITXOR,
-    Seq(InternalTypes.BYTE, InternalTypes.BYTE),
+    Seq(INTEGER, INTEGER),
     BuiltInMethods.BITXOR_BYTE)
 
   addSqlFunctionMethod(
     BITXOR,
-    Seq(InternalTypes.SHORT, InternalTypes.SHORT),
+    Seq(SMALLINT, SMALLINT),
     BuiltInMethods.BITXOR_SHORT)
 
   addSqlFunctionMethod(
     BITXOR,
-    Seq(InternalTypes.INT, InternalTypes.INT),
+    Seq(INTEGER, INTEGER),
     BuiltInMethods.BITXOR_INTEGER)
 
   addSqlFunctionMethod(
     BITXOR,
-    Seq(InternalTypes.LONG, InternalTypes.LONG),
+    Seq(BIGINT, BIGINT),
     BuiltInMethods.BITXOR_LONG)
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.STRING),
+    Seq(VARCHAR, VARCHAR),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.BOOLEAN),
+    Seq(VARCHAR, BOOLEAN),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.BYTE),
+    Seq(VARCHAR, INTEGER),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.SHORT),
+    Seq(VARCHAR, SMALLINT),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.INT),
+    Seq(VARCHAR, INTEGER),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.LONG),
+    Seq(VARCHAR, BIGINT),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.FLOAT),
+    Seq(VARCHAR, FLOAT),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.DOUBLE),
+    Seq(VARCHAR, DOUBLE),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.DATE),
+    Seq(VARCHAR, DATE),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.TIMESTAMP),
+    Seq(VARCHAR, TIMESTAMP_WITHOUT_TIME_ZONE),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, InternalTypes.TIME),
+    Seq(VARCHAR, TIME_WITHOUT_TIME_ZONE),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
-    Seq(InternalTypes.STRING, ANY_DEC_TYPE),
+    Seq(VARCHAR, DECIMAL),
     new PrintCallGen())
 
   addSqlFunction(
     PRINT,
     Seq(
-      InternalTypes.STRING,
-      InternalTypes.BINARY),
+      VARCHAR,
+      VARBINARY),
     new PrintCallGen())
 
   addSqlFunctionMethod(
@@ -681,7 +680,7 @@ object FunctionGenerator {
 
   addSqlFunctionMethod(
     NOW,
-    Seq(InternalTypes.INT),
+    Seq(INTEGER),
     BuiltInMethods.NOW_OFFSET)
 
   addSqlFunctionMethod(
@@ -691,159 +690,159 @@ object FunctionGenerator {
 
   addSqlFunctionMethod(
     UNIX_TIMESTAMP,
-    Seq(InternalTypes.TIMESTAMP),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE),
     BuiltInMethods.UNIX_TIMESTAMP_TS)
 
   addSqlFunctionMethod(
     DATEDIFF,
-    Seq(InternalTypes.TIMESTAMP,
-      InternalTypes.TIMESTAMP),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE,
+      TIMESTAMP_WITHOUT_TIME_ZONE),
     BuiltInMethods.DATEDIFF_T_T)
 
   addSqlFunction(
     IF,
-    Seq(InternalTypes.BOOLEAN, InternalTypes.STRING, InternalTypes.STRING),
+    Seq(BOOLEAN, VARCHAR, VARCHAR),
     new IfCallGen())
 
   addSqlFunction(
     IF,
-    Seq(InternalTypes.BOOLEAN, InternalTypes.BOOLEAN, InternalTypes.BOOLEAN),
+    Seq(BOOLEAN, BOOLEAN, BOOLEAN),
     new IfCallGen())
 
   // This sequence must be in sync with [[NumericOrDefaultReturnTypeInference]]
   val numericTypes = Seq(
-    InternalTypes.BYTE,
-    InternalTypes.SHORT,
-    InternalTypes.INT,
-    InternalTypes.LONG,
-    DecimalType.SYSTEM_DEFAULT,
-    InternalTypes.FLOAT,
-    InternalTypes.DOUBLE)
+    INTEGER,
+    SMALLINT,
+    INTEGER,
+    BIGINT,
+    DECIMAL,
+    FLOAT,
+    DOUBLE)
 
   for (t1 <- numericTypes) {
     for (t2 <- numericTypes) {
       addSqlFunction(
         IF,
-        Seq(InternalTypes.BOOLEAN, t1, t2),
+        Seq(BOOLEAN, t1, t2),
         new IfCallGen())
     }
   }
 
   addSqlFunction(
     IF,
-    Seq(InternalTypes.BOOLEAN, InternalTypes.DATE, InternalTypes.DATE),
+    Seq(BOOLEAN, DATE, DATE),
     new IfCallGen())
 
   addSqlFunction(
     IF,
-    Seq(InternalTypes.BOOLEAN, InternalTypes.TIMESTAMP, InternalTypes.TIMESTAMP),
+    Seq(BOOLEAN, TIMESTAMP_WITHOUT_TIME_ZONE, TIMESTAMP_WITHOUT_TIME_ZONE),
     new IfCallGen())
 
   addSqlFunction(
     IF,
-    Seq(InternalTypes.BOOLEAN, InternalTypes.TIME, InternalTypes.TIME),
+    Seq(BOOLEAN, TIME_WITHOUT_TIME_ZONE, TIME_WITHOUT_TIME_ZONE),
     new IfCallGen())
 
   addSqlFunction(
     IF,
     Seq(
-      InternalTypes.BOOLEAN,
-      InternalTypes.BINARY,
-      InternalTypes.BINARY),
+      BOOLEAN,
+      VARBINARY,
+      VARBINARY),
     new IfCallGen())
 
   addSqlFunctionMethod(
     DIV_INT,
-    Seq(InternalTypes.INT, InternalTypes.INT),
+    Seq(INTEGER, INTEGER),
     BuiltInMethods.DIV_INT)
 
   addSqlFunction(
     DIV,
-    Seq(ANY_DEC_TYPE, InternalTypes.DOUBLE),
+    Seq(DECIMAL, DOUBLE),
     new DivCallGen()
   )
 
   addSqlFunction(
     DIV,
-    Seq(ANY_DEC_TYPE, ANY_DEC_TYPE),
+    Seq(DECIMAL, DECIMAL),
     new DivCallGen()
   )
 
   addSqlFunction(
     DIV,
-    Seq(InternalTypes.DOUBLE, InternalTypes.DOUBLE),
+    Seq(DOUBLE, DOUBLE),
     new DivCallGen()
   )
 
   addSqlFunction(
     DIV,
-    Seq(InternalTypes.DOUBLE, ANY_DEC_TYPE),
+    Seq(DOUBLE, DECIMAL),
     new DivCallGen()
   )
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.BOOLEAN),
+    Seq(BOOLEAN),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.BYTE),
+    Seq(INTEGER),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.SHORT),
+    Seq(SMALLINT),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.INT),
+    Seq(INTEGER),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.LONG),
+    Seq(BIGINT),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.FLOAT),
+    Seq(FLOAT),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.DOUBLE),
+    Seq(DOUBLE),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.DATE),
+    Seq(DATE),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.TIME),
+    Seq(TIME_WITHOUT_TIME_ZONE),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.TIMESTAMP),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(InternalTypes.BINARY),
+    Seq(VARBINARY),
     new HashCodeCallGen())
 
   addSqlFunction(
     HASH_CODE,
-    Seq(DecimalType.SYSTEM_DEFAULT),
+    Seq(DECIMAL),
     new HashCodeCallGen())
 
   addSqlFunctionMethod(
     TO_DATE,
-    Seq(InternalTypes.INT),
+    Seq(INTEGER),
     BuiltInMethods.INT_TO_DATE)
 
   INTEGRAL_TYPES foreach (
@@ -857,43 +856,43 @@ object FunctionGenerator {
       BuiltInMethods.DOUBLE_TO_TIMESTAMP))
 
   addSqlFunctionMethod(TO_TIMESTAMP,
-    Seq(DecimalType.SYSTEM_DEFAULT),
+    Seq(DECIMAL),
     BuiltInMethods.DECIMAL_TO_TIMESTAMP)
 
   addSqlFunctionMethod(
     FROM_TIMESTAMP,
-    Seq(InternalTypes.TIMESTAMP),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE),
     BuiltInMethods.TIMESTAMP_TO_BIGINT)
 
   // Date/Time & BinaryString Converting -- start
   addSqlFunctionMethod(
     TO_DATE,
-    Seq(InternalTypes.STRING),
+    Seq(VARCHAR),
     BuiltInMethod.STRING_TO_DATE.method)
 
   addSqlFunctionMethod(
     TO_DATE,
-    Seq(InternalTypes.STRING, InternalTypes.STRING),
+    Seq(VARCHAR, VARCHAR),
     BuiltInMethods.STRING_TO_DATE_WITH_FORMAT)
 
   addSqlFunctionMethod(
     TO_TIMESTAMP,
-    Seq(InternalTypes.STRING),
+    Seq(VARCHAR),
     BuiltInMethods.STRING_TO_TIMESTAMP)
 
   addSqlFunctionMethod(
     TO_TIMESTAMP,
-    Seq(InternalTypes.STRING, InternalTypes.STRING),
+    Seq(VARCHAR, VARCHAR),
     BuiltInMethods.STRING_TO_TIMESTAMP_WITH_FORMAT)
 
   addSqlFunctionMethod(
     UNIX_TIMESTAMP,
-    Seq(InternalTypes.STRING),
+    Seq(VARCHAR),
     BuiltInMethods.UNIX_TIMESTAMP_STR)
 
   addSqlFunctionMethod(
     UNIX_TIMESTAMP,
-    Seq(InternalTypes.STRING, InternalTypes.STRING),
+    Seq(VARCHAR, VARCHAR),
     BuiltInMethods.UNIX_TIMESTAMP_FORMAT)
 
   INTEGRAL_TYPES foreach (
@@ -910,92 +909,110 @@ object FunctionGenerator {
 
   addSqlFunctionMethod(
     FROM_UNIXTIME,
-    Seq(DecimalType.SYSTEM_DEFAULT),
+    Seq(DECIMAL),
     BuiltInMethods.FROM_UNIXTIME_AS_DECIMAL)
 
   addSqlFunctionMethod(
     FROM_UNIXTIME,
-    Seq(InternalTypes.LONG, InternalTypes.STRING),
+    Seq(BIGINT, VARCHAR),
     BuiltInMethods.FROM_UNIXTIME_FORMAT)
 
   addSqlFunctionMethod(
     DATEDIFF,
-    Seq(InternalTypes.TIMESTAMP, InternalTypes.STRING),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE, VARCHAR),
     BuiltInMethods.DATEDIFF_T_S)
 
   addSqlFunctionMethod(
     DATEDIFF,
-    Seq(InternalTypes.STRING, InternalTypes.TIMESTAMP),
+    Seq(VARCHAR, TIMESTAMP_WITHOUT_TIME_ZONE),
     BuiltInMethods.DATEDIFF_S_T)
 
   addSqlFunctionMethod(
     DATEDIFF,
-    Seq(InternalTypes.STRING, InternalTypes.STRING),
+    Seq(VARCHAR, VARCHAR),
     BuiltInMethods.DATEDIFF_S_S)
 
   addSqlFunctionMethod(
     DATE_FORMAT,
-    Seq(InternalTypes.TIMESTAMP, InternalTypes.STRING),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE, VARCHAR),
     BuiltInMethods.DATE_FORMAT_LONG_STRING)
 
   addSqlFunctionMethod(
     DATE_FORMAT,
-    Seq(InternalTypes.STRING, InternalTypes.STRING),
+    Seq(VARCHAR, VARCHAR),
     BuiltInMethods.DATE_FORMAT_STIRNG_STRING)
 
   addSqlFunctionMethod(
     DATE_FORMAT,
-    Seq(InternalTypes.STRING, InternalTypes.STRING, InternalTypes.STRING),
+    Seq(
+      VARCHAR,
+      VARCHAR,
+      VARCHAR),
     BuiltInMethods.DATE_FORMAT_STRING_STRING_STRING)
 
   addSqlFunctionMethod(
     DATE_SUB,
-    Seq(InternalTypes.STRING, InternalTypes.INT),
+    Seq(VARCHAR, INTEGER),
     BuiltInMethods.DATE_SUB_S)
 
   addSqlFunctionMethod(
     DATE_SUB,
-    Seq(InternalTypes.TIMESTAMP, InternalTypes.INT),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE, INTEGER),
     BuiltInMethods.DATE_SUB_T)
 
   addSqlFunctionMethod(
     DATE_ADD,
-    Seq(InternalTypes.STRING, InternalTypes.INT),
+    Seq(VARCHAR, INTEGER),
     BuiltInMethods.DATE_ADD_S)
 
   addSqlFunctionMethod(
     DATE_ADD,
-    Seq(InternalTypes.TIMESTAMP, InternalTypes.INT),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE, INTEGER),
     BuiltInMethods.DATE_ADD_T)
 
   addSqlFunctionMethod(
     TO_TIMESTAMP_TZ,
-    Seq(InternalTypes.STRING, InternalTypes.STRING),
+    Seq(
+      VARCHAR,
+      VARCHAR),
     BuiltInMethods.STRING_TO_TIMESTAMP_TZ)
 
   addSqlFunctionMethod(
     TO_TIMESTAMP_TZ,
-    Seq(InternalTypes.STRING, InternalTypes.STRING, InternalTypes.STRING),
+    Seq(
+      VARCHAR,
+      VARCHAR,
+      VARCHAR),
     BuiltInMethods.STRING_TO_TIMESTAMP_FORMAT_TZ)
 
   addSqlFunctionMethod(
     DATE_FORMAT_TZ,
-    Seq(InternalTypes.TIMESTAMP, InternalTypes.STRING),
+    Seq(TIMESTAMP_WITHOUT_TIME_ZONE, VARCHAR),
     BuiltInMethods.DATE_FORMAT_LONG_ZONE)
 
   addSqlFunctionMethod(
     DATE_FORMAT_TZ,
-    Seq(InternalTypes.TIMESTAMP, InternalTypes.STRING, InternalTypes.STRING),
+    Seq(
+      TIMESTAMP_WITHOUT_TIME_ZONE,
+      VARCHAR,
+      VARCHAR),
     BuiltInMethods.DATE_FORMAT_LONG_STRING_ZONE)
 
   addSqlFunctionMethod(
     CONVERT_TZ,
-    Seq(InternalTypes.STRING, InternalTypes.STRING, InternalTypes.STRING),
+    Seq(
+      VARCHAR,
+      VARCHAR,
+      VARCHAR),
     BuiltInMethods.CONVERT_TZ)
 
   addSqlFunctionMethod(
     CONVERT_TZ,
-    Seq(InternalTypes.STRING, InternalTypes.STRING, InternalTypes.STRING, InternalTypes.STRING),
+    Seq(
+      VARCHAR,
+      VARCHAR,
+      VARCHAR,
+      VARCHAR),
     BuiltInMethods.CONVERT_FORMAT_TZ)
 
   // ----------------------------------------------------------------------------------------------
@@ -1011,34 +1028,49 @@ object FunctionGenerator {
     */
   def getCallGenerator(
     sqlOperator: SqlOperator,
-    operandTypes: Seq[InternalType],
-    resultType: InternalType)
+    operandTypes: Seq[LogicalType],
+    resultType: LogicalType)
   : Option[CallGenerator] = sqlOperator match {
-
-    // TODO: support user-defined scalar function
-
-    // TODO: support user-defined table function
-
     // built-in scalar function
     case _ =>
-      sqlFunctions.get((sqlOperator, operandTypes))
+      val typeRoots = operandTypes.map(_.getTypeRoot)
+      sqlFunctions.get((sqlOperator, typeRoots))
         .orElse(sqlFunctions.find(entry => entry._1._1 == sqlOperator
-          && entry._1._2.length == operandTypes.length
-          && entry._1._2.zip(operandTypes).forall {
-          case (x: DecimalType, y: DecimalType) => true
-          case (x: PrimitiveType, y: PrimitiveType) => 
-            InternalTypeUtils.shouldAutoCastTo(y, x) || x == y
-          case (x: InternalType, y: InternalType) => x == y
+          && entry._1._2.length == typeRoots.length
+          && entry._1._2.zip(typeRoots).forall {
+          case (DECIMAL, DECIMAL) => true
+          case (x, y) if isPrimitive(x) && isPrimitive(y) => shouldAutoCastTo(y, x) || x == y
+          case (x, y) => x == y
           case _ => false
         }).map(_._2))
+  }
 
+  /**
+    * Returns whether this type should be automatically casted to
+    * the target type in an arithmetic operation.
+    */
+  def shouldAutoCastTo(from: LogicalTypeRoot, to: LogicalTypeRoot): Boolean = {
+    from match {
+      case TINYINT =>
+        (to eq SMALLINT) || (to eq INTEGER) || (to eq BIGINT) || (to eq FLOAT) || (to eq DOUBLE)
+      case SMALLINT =>
+        (to eq INTEGER) || (to eq BIGINT) || (to eq FLOAT) || (to eq DOUBLE)
+      case INTEGER =>
+        (to eq BIGINT) || (to eq FLOAT) || (to eq DOUBLE)
+      case BIGINT =>
+        (to eq FLOAT) || (to eq DOUBLE)
+      case FLOAT =>
+        to eq DOUBLE
+      case _ =>
+        false
+    }
   }
 
   // ----------------------------------------------------------------------------------------------
 
   private def addSqlFunctionMethod(
     sqlOperator: SqlOperator,
-    operandTypes: Seq[InternalType],
+    operandTypes: Seq[LogicalTypeRoot],
     method: Method)
   : Unit = {
     sqlFunctions((sqlOperator, operandTypes)) = new MethodCallGen(method)
@@ -1046,7 +1078,7 @@ object FunctionGenerator {
 
   private def addSqlFunction(
     sqlOperator: SqlOperator,
-    operandTypes: Seq[InternalType],
+    operandTypes: Seq[LogicalTypeRoot],
     callGenerator: CallGenerator)
   : Unit = {
     sqlFunctions((sqlOperator, operandTypes)) = callGenerator
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/HashCodeCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/HashCodeCallGen.scala
index 97877af..125a618 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/HashCodeCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/HashCodeCallGen.scala
@@ -18,15 +18,15 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.GenerateUtils.generateCallIfArgsNotNull
 import org.apache.flink.table.codegen.{CodeGenUtils, CodeGeneratorContext, GeneratedExpression}
+import org.apache.flink.table.types.logical.LogicalType
 
 class HashCodeCallGen extends CallGenerator {
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = {
+      returnType: LogicalType): GeneratedExpression = {
     val inputTerm = operands.head.resultTerm
     val inputType = operands.head.resultType
     val code = CodeGenUtils.hashCodeForType(ctx, inputType, inputTerm)
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/IfCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/IfCallGen.scala
index 373512a..0471b9b 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/IfCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/IfCallGen.scala
@@ -18,9 +18,9 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.CodeGenUtils.primitiveTypeTermForType
 import org.apache.flink.table.codegen.{CodeGenUtils, CodeGeneratorContext, GeneratedExpression}
+import org.apache.flink.table.types.logical.LogicalType
 
 /**
   * Generates IF function call.
@@ -30,7 +30,7 @@ class IfCallGen() extends CallGenerator {
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType)
+      returnType: LogicalType)
     : GeneratedExpression = {
 
     // Inferred return type is ARG1. Must be the same as ARG2.
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/LikeCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/LikeCallGen.scala
index d67be04..975a25c1 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/LikeCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/LikeCallGen.scala
@@ -19,11 +19,11 @@
 package org.apache.flink.table.codegen.calls
 
 import org.apache.calcite.runtime.SqlFunctions
-import org.apache.flink.table.`type`.{InternalType, InternalTypes}
 import org.apache.flink.table.codegen.CodeGenUtils.{className, newName}
 import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
 import org.apache.flink.table.codegen.GenerateUtils.generateCallIfArgsNotNull
 import org.apache.flink.table.runtime.functions.{SqlLikeChainChecker, SqlLikeUtils}
+import org.apache.flink.table.types.logical.{BooleanType, LogicalType}
 
 import java.util.regex.Pattern
 
@@ -55,7 +55,7 @@ class LikeCallGen extends CallGenerator {
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = {
+      returnType: LogicalType): GeneratedExpression = {
     if ((operands.size == 2 && operands(1).literal) ||
         (operands.size == 3 && operands(1).literal && operands(2).literal)) {
       generateCallIfArgsNotNull(ctx, returnType, operands) {
@@ -155,7 +155,7 @@ class LikeCallGen extends CallGenerator {
   def generateDynamicLike(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression]): GeneratedExpression = {
-    generateCallIfArgsNotNull(ctx, InternalTypes.BOOLEAN, operands) {
+    generateCallIfArgsNotNull(ctx, new BooleanType(), operands) {
       terms =>
         val str1 = s"${terms.head}.toString()"
         val str2 = s"${terms(1)}.toString()"
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/MethodCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/MethodCallGen.scala
index 2a242a5..53df25e 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/MethodCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/MethodCallGen.scala
@@ -18,10 +18,10 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.InternalType
 import org.apache.flink.table.codegen.CodeGenUtils.{BINARY_STRING, qualifyMethod}
 import org.apache.flink.table.codegen.GenerateUtils.generateCallIfArgsNotNull
 import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
+import org.apache.flink.table.types.logical.LogicalType
 
 import java.lang.reflect.Method
 import java.util.TimeZone
@@ -31,7 +31,7 @@ class MethodCallGen(method: Method) extends CallGenerator {
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = {
+      returnType: LogicalType): GeneratedExpression = {
     generateCallIfArgsNotNull(ctx, returnType, operands, !method.getReturnType.isPrimitive) {
       originalTerms => {
         val terms = originalTerms.zip(method.getParameterTypes).map { case (term, clazz) =>
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/PrintCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/PrintCallGen.scala
index b3d71d4..843b976 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/PrintCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/PrintCallGen.scala
@@ -18,9 +18,9 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.{InternalType, InternalTypes}
 import org.apache.flink.table.codegen.CodeGenUtils.{newNames, primitiveTypeTermForType}
 import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
+import org.apache.flink.table.types.logical.{LogicalType, LogicalTypeRoot}
 
 /**
   * Generates PRINT function call.
@@ -30,7 +30,7 @@ class PrintCallGen extends CallGenerator {
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = {
+      returnType: LogicalType): GeneratedExpression = {
     val Seq(resultTerm, nullTerm) = newNames("result", "isNull")
     val resultTypeTerm = primitiveTypeTermForType(returnType)
 
@@ -39,7 +39,7 @@ class PrintCallGen extends CallGenerator {
     val logTerm = "logger$"
     ctx.addReusableLogger(logTerm, "_Print$_")
 
-    val outputCode = if (returnType == InternalTypes.BINARY) {
+    val outputCode = if (returnType.getTypeRoot == LogicalTypeRoot.VARBINARY) {
       s"new String($resultTerm, java.nio.charset.Charset.defaultCharset())"
     } else {
       s"String.valueOf(${operands(1).resultTerm})"
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/RandCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/RandCallGen.scala
index 9f088c2..8d10e85 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/RandCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/RandCallGen.scala
@@ -18,9 +18,9 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`.{InternalType, InternalTypes}
 import org.apache.flink.table.codegen.{CodeGeneratorContext, GeneratedExpression}
 import org.apache.flink.table.codegen.GenerateUtils.generateCallIfArgsNotNull
+import org.apache.flink.table.types.logical.{DoubleType, IntType, LogicalType}
 
 /**
   * Generates a random function call.
@@ -31,7 +31,7 @@ class RandCallGen(isRandInteger: Boolean, hasSeed: Boolean) extends CallGenerato
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = {
+      returnType: LogicalType): GeneratedExpression = {
     val randField = if (hasSeed) {
       if (operands.head.literal) {
         ctx.addReusableRandom(Some(operands.head))
@@ -43,11 +43,11 @@ class RandCallGen(isRandInteger: Boolean, hasSeed: Boolean) extends CallGenerato
     }
 
     if (isRandInteger) {
-      generateCallIfArgsNotNull(ctx, InternalTypes.INT, operands) { terms =>
+      generateCallIfArgsNotNull(ctx, new IntType(), operands) { terms =>
         s"$randField.nextInt(${terms.last})"
       }
     } else {
-      generateCallIfArgsNotNull(ctx, InternalTypes.DOUBLE, operands) { _ =>
+      generateCallIfArgsNotNull(ctx, new DoubleType(), operands) { _ =>
         s"$randField.nextDouble()"
       }
     }
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ScalarFunctionCallGen.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ScalarFunctionCallGen.scala
index ac57c6d..26c97d1 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ScalarFunctionCallGen.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ScalarFunctionCallGen.scala
@@ -19,15 +19,16 @@
 package org.apache.flink.table.codegen.calls
 
 import org.apache.flink.api.java.typeutils.GenericTypeInfo
-import org.apache.flink.table.`type`.InternalType
-import org.apache.flink.table.`type`.TypeConverters.createExternalTypeInfoFromInternalType
 import org.apache.flink.table.codegen.CodeGenUtils._
 import org.apache.flink.table.codegen.{CodeGeneratorContext, GenerateUtils, GeneratedExpression}
 import org.apache.flink.table.dataformat.DataFormatConverters
-import org.apache.flink.table.dataformat.DataFormatConverters.getConverterForTypeInfo
+import org.apache.flink.table.dataformat.DataFormatConverters.getConverterForDataType
 import org.apache.flink.table.functions.ScalarFunction
 import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils
 import org.apache.flink.table.functions.utils.UserDefinedFunctionUtils._
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromLogicalTypeToDataType
+import org.apache.flink.table.types.logical.LogicalType
+import org.apache.flink.table.types.utils.TypeConversions.fromLegacyInfoToDataType
 
 /**
   * Generates a call to user-defined [[ScalarFunction]].
@@ -39,11 +40,11 @@ class ScalarFunctionCallGen(scalarFunction: ScalarFunction) extends CallGenerato
   override def generate(
       ctx: CodeGeneratorContext,
       operands: Seq[GeneratedExpression],
-      returnType: InternalType): GeneratedExpression = {
+      returnType: LogicalType): GeneratedExpression = {
     val operandTypes = operands.map(_.resultType).toArray
     val arguments = operands.map {
       case expr if expr.literal =>
-        getConverterForTypeInfo(createExternalTypeInfoFromInternalType(expr.resultType))
+        getConverterForDataType(fromLogicalTypeToDataType(expr.resultType))
             .asInstanceOf[DataFormatConverters.DataFormatConverter[Any, Any]]
             .toExternal(expr.literalValue.get)
             .asInstanceOf[AnyRef]
@@ -116,9 +117,9 @@ class ScalarFunctionCallGen(scalarFunction: ScalarFunction) extends CallGenerato
           case (t, i) =>
             // we don't trust GenericType.
             if (t.isInstanceOf[GenericTypeInfo[_]]) {
-              createExternalTypeInfoFromInternalType(operands(i).resultType)
+              fromLogicalTypeToDataType(operands(i).resultType)
             } else {
-              t
+              fromLegacyInfoToDataType(t)
             }
         }
 
diff --git a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ScalarOperatorGens.scala b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ScalarOperatorGens.scala
index c2603c0..14fae9b 100644
--- a/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ScalarOperatorGens.scala
+++ b/flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/codegen/calls/ScalarOperatorGens.scala
@@ -18,12 +18,16 @@
 
 package org.apache.flink.table.codegen.calls
 
-import org.apache.flink.table.`type`._
 import org.apache.flink.table.codegen.CodeGenUtils.{binaryRowFieldSetAccess, binaryRowSetNull, binaryWriterWriteField, binaryWriterWriteNull, _}
 import org.apache.flink.table.codegen.GenerateUtils._
-import org.apache.flink.table.codegen.GeneratedExpression.{NEVER_NULL, NO_CODE, ALWAYS_NULL}
+import org.apache.flink.table.codegen.GeneratedExpression.{ALWAYS_NULL, NEVER_NULL, NO_CODE}
 import org.apache.flink.table.codegen.{CodeGenException, CodeGeneratorContext, GeneratedExpression}
 import org.apache.flink.table.dataformat._
+import org.apache.flink.table.types.LogicalTypeDataTypeConverter.fromLogicalTypeToDataType
+import org.apache.flink.table.types.PlannerTypeUtils
+import org.apache.flink.table.types.PlannerTypeUtils.{isInteroperable, isPrimitive}
+import org.apache.flink.table.types.logical.LogicalTypeRoot._
+import org.apache.flink.table.types.logical._
 import org.apache.flink.table.typeutils.TypeCheckUtils._
 import org.apache.flink.table.typeutils.{TypeCheckUtils, TypeCoercion}
 import org.apache.flink.util.Preconditions.checkArgument
@@ -35,6 +39,8 @@ import org.apache.calcite.util.BuiltInMethod
 import java.lang.{StringBuilder => JStringBuilder}
 import java.nio.charset.StandardCharsets
 
+import scala.collection.JavaConversions._
+
 /**
   * Utilities to generate SQL scalar operators, e.g. arithmetic operator,
   * compare operator, equal operator, etc.
@@ -51,7 +57,7 @@ object ScalarOperatorGens {
   def generateBinaryArithmeticOperator(
     ctx: CodeGeneratorContext,
     operator: String,
-    resultType: InternalType,
+    resultType: LogicalType,
     left: GeneratedExpression,
     right: GeneratedExpression)
   : GeneratedExpression = {
@@ -64,11 +70,11 @@ object ScalarOperatorGens {
 
     val leftCasting = operator match {
       case "%" =>
-        if (left.resultType == right.resultType) {
+        if (isInteroperable(left.resultType, right.resultType)) {
           numericCasting(left.resultType, resultType)
         } else {
           val castedType = if (isDecimal(left.resultType)) {
-            InternalTypes.LONG
+            new BigIntType()
           } else {
             left.resultType
           }
@@ -99,7 +105,7 @@ object ScalarOperatorGens {
 
     // do not cast a decimal operand to resultType, which may change its value.
     // use it as is during calculation.
-    def castToDec(t: InternalType): String => String = t match {
+    def castToDec(t: LogicalType): String => String = t match {
       case _: DecimalType => (operandTerm: String) => s"$operandTerm"
       case _ => numericCasting(t, resultType)
     }
@@ -115,9 +121,9 @@ object ScalarOperatorGens {
         val method = methods(operator)
         val leftCasted = castToDec(left.resultType)(leftTerm)
         val rightCasted = castToDec(right.resultType)(rightTerm)
-        val precision = resultType.precision()
-        val scale = resultType.scale()
-        s"$DECIMAL.$method($leftCasted, $rightCasted, $precision, $scale)"
+        val precision = resultType.getPrecision
+        val scale = resultType.getScale
+        s"$DECIMAL_TERM.$method($leftCasted, $rightCasted, $precision, $scale)"
       }
     }
   }
@@ -128,7 +134,7 @@ object ScalarOperatorGens {
   def generateUnaryArithmeticOperator(
       ctx: CodeGeneratorContext,
       operator: String,
-      resultType: InternalType,
+      resultType: LogicalType,
       operand: GeneratedExpression)
     : GeneratedExpression = {
     generateUnaryOperatorIfNotNull(ctx, resultType, operand) {
@@ -147,55 +153,55 @@ object ScalarOperatorGens {
   def generateTemporalPlusMinus(
     ctx: CodeGeneratorContext,
     plus: Boolean,
-    resultType: InternalType,
+    resultType: LogicalType,
     left: GeneratedExpression,
     right: GeneratedExpression)
   : GeneratedExpression = {
 
     val op = if (plus) "+" else "-"
 
-    (left.resultType, right.resultType) match {
+    (left.resultType.getTypeRoot, right.resultType.getTypeRoot) match {
       // arithmetic of time point and time interval
-      case (InternalTypes.INTERVAL_MONTHS, InternalTypes.INTERVAL_MONTHS) |
-           (InternalTypes.INTERVAL_MILLIS, InternalTypes.INTERVAL_MILLIS) =>
+      case (INTERVAL_YEAR_MONTH, INTERVAL_YEAR_MONTH) |
+           (INTERVAL_DAY_TIME, INTERVAL_DAY_TIME) =>
         generateBinaryArithmeticOperator(ctx, op, left.resultType, left, right)
 
-      case (InternalTypes.DATE, InternalTypes.INTERVAL_MILLIS) =>
-        generateOperatorIfNotNull(ctx, InternalTypes.DATE, left, right) {
+      case (DATE, INTERVAL_DAY_TIME) =>
+        generateOperatorIfNotNull(ctx, new DateType(), left, right) {
           (l, r) => s"$l $op ((int) ($r / ${MILLIS_PER_DAY}L))"
         }
 
-      case (InternalTypes.DATE, InternalTypes.INTERVAL_MONTHS) =>
-        generateOperatorIfNotNull(ctx, InternalTypes.DATE, left, right) {
+      case (DATE, INTERVAL_YEAR_MONTH) =>
+        generateOperatorIfNotNull(ctx, new DateType(), left, right) {
           (l, r) => s"${qualifyMethod(BuiltInMethod.ADD_MONTHS.method)}($l, $op($r))"
         }
 
-      case (InternalTypes.TIME, InternalTypes.INTERVAL_MILLIS) =>
-        generateOperatorIfNotNull(ctx, InternalTypes.TIME, left, right) {
+      case (TIME_WITHOUT_TIME_ZONE, INTERVAL_DAY_TIME) =>
+        generateOperatorIfNotNull(ctx, new TimeType(), left, right) {
           (l, r) => s"$l $op ((int) ($r))"
         }
 
-      case (InternalTypes.TIMESTAMP, InternalTypes.INTERVAL_MILLIS) =>
-        generateOperatorIfNotNull(ctx, InternalTypes.TIMESTAMP, left, right) {
+      case (TIMESTAMP_WITHOUT_TIME_ZONE, INTERVAL_DAY_TIME) =>
+        generateOperatorIfNotNull(ctx, left.resultType, left, right) {
           (l, r) => s"$l $op $r"
         }
 
-      case (InternalTypes.TIMESTAMP, InternalTypes.INTERVAL_MONTHS) =>
-        generateOperatorIfNotNull(ctx, InternalTypes.TIMESTAMP, left, right) {
+      case (TIMESTAMP_WITHOUT_TIME_ZONE, INTERVAL_YEAR_MONTH) =>
+        generateOperatorIfNotNull(ctx, left.resultType, left, right) {
           (l, r) => s"${qualifyMethod(BuiltInMethod.ADD_MONTHS.method)}($l, $op($r))"
         }
 
       // minus arithmetic of time points (i.e. for TIMESTAMPDIFF)
-      case (InternalTypes.TIMESTAMP | InternalTypes.TIME | InternalTypes.DATE,
-      InternalTypes.TIMESTAMP | InternalTypes.TIME | InternalTypes.DATE) if !plus =>
-        resultType match {
-          case InternalTypes.INTERVAL_MONTHS =>
+      case (TIMESTAMP_WITHOUT_TIME_ZONE | TIME_WITHOUT_TIME_ZONE | DATE,
+      TIMESTAMP_WITHOUT_TIME_ZONE | TIME_WITHOUT_TIME_ZONE | DATE) if !plus =>
+        resultType.getTypeRoot match {
+          case INTERVAL_YEAR_MONTH =>
             generateOperatorIfNotNull(ctx, resultType, left, right) {
-              (ll, rr) => (left.resultType, right.resultType) match {
-                case (InternalTypes.TIMESTAMP, InternalTypes.DATE) =>
+              (ll, rr) => (left.resultType.getTypeRoot, right.resultType.getTypeRoot) match {
+                case (TIMESTAMP_WITHOUT_TIME_ZONE, DATE) =>
                   s"${qualifyMethod(BuiltInMethod.SUBTRACT_MONTHS.method)}" +
                     s"($ll, $rr * ${MILLIS_PER_DAY}L)"
-                case (InternalTypes.DATE, InternalTypes.TIMESTAMP) =>
+                case (DATE, TIMESTAMP_WITHOUT_TIME_ZONE) =>
                   s"${qualifyMethod(BuiltInMethod.SUBTRACT_MONTHS.method)}" +
                     s"($ll * ${MILLIS_PER_DAY}L, $rr)"
                 case _ =>
@@ -203,16 +209,16 @@ object ScalarOperatorGens {
               }
             }
 
-          case InternalTypes.INTERVAL_MILLIS =>
+          case INTERVAL_DAY_TIME =>
             generateOperatorIfNotNull(ctx, resultType, left, right) {
-              (ll, rr) => (left.resultType, right.resultType) match {
-                case (InternalTypes.TIMESTAMP, InternalTypes.TIMESTAMP) =>
+              (ll, rr) => (left.resultType.getTypeRoot, right.resultType.getTypeRoot) match {
+                case (TIMESTAMP_WITHOUT_TIME_ZONE, TIMESTAMP_WITHOUT_TIME_ZONE) =>
                   s"$ll $op $rr"
-                case (InternalTypes.DATE, InternalTypes.DATE) =>
+                case (DATE, DATE) =>
                   s"($ll * ${MILLIS_PER_DAY}L) $op ($rr * ${MILLIS_PER_DAY}L)"
-                case (InternalTypes.TIMESTAMP, InternalTypes.DATE) =>
+                case (TIMESTAMP_WITHOUT_TIME_ZONE, DATE) =>
                   s"$ll $op ($rr * ${MILLIS_PER_DAY}L)"
-                case (InternalTypes.DATE, InternalTypes.TIMESTAMP) =>
+                case (DATE, TIMESTAMP_WITHOUT_TIME_ZONE) =>
                   s"($ll * ${MILLIS_PER_DAY}L) $op $rr"
               }
             }
@@ -281,8 +287,8 @@ object ScalarOperatorGens {
         resultType)
 
       val Seq(resultTerm, nullTerm) = newNames("result", "isNull")
-      val resultTypeTerm = primitiveTypeTermForType(InternalTypes.BOOLEAN)
-      val defaultValue = primitiveDefaultValue(InternalTypes.BOOLEAN)
+      val resultTypeTerm = primitiveTypeTermForType(new BooleanType())
+      val defaultValue = primitiveDefaultValue(new BooleanType())
 
       val operatorCode = if (ctx.nullCheck) {
         s"""
@@ -302,7 +308,7 @@ object ScalarOperatorGens {
            |""".stripMargin.trim
       }
 
-      GeneratedExpression(resultTerm, nullTerm, operatorCode, InternalTypes.BOOLEAN)
+      GeneratedExpression(resultTerm, nullTerm, operatorCode, new BooleanType())
     } else {
       // we use a chain of ORs for a set that contains non-constant elements
       haystack
@@ -318,8 +324,9 @@ object ScalarOperatorGens {
       left: GeneratedExpression,
       right: GeneratedExpression)
     : GeneratedExpression = {
-    if (left.resultType == InternalTypes.STRING && right.resultType == InternalTypes.STRING) {
-      generateOperatorIfNotNull(ctx, InternalTypes.BOOLEAN, left, right) {
+    val canEqual = isInteroperable(left.resultType, right.resultType)
+    if (left.resultType.getTypeRoot == VARCHAR && right.resultType.getTypeRoot == VARCHAR) {
+      generateOperatorIfNotNull(ctx, new BooleanType(), left, right) {
         (leftTerm, rightTerm) => s"$leftTerm.equals($rightTerm)"
       }
     }
@@ -327,32 +334,28 @@ object ScalarOperatorGens {
     else if (isNumeric(left.resultType) && isNumeric(right.resultType)) {
       generateComparison(ctx, "==", left, right)
     }
-    // temporal types
-    else if (isTemporal(left.resultType) && left.resultType == right.resultType) {
-      generateComparison(ctx, "==", left, right)
-    }
     // array types
-    else if (isArray(left.resultType) && left.resultType == right.resultType) {
+    else if (isArray(left.resultType) && canEqual) {
       generateArrayComparison(ctx, left, right)
     }
     // map types
-    else if (isMap(left.resultType) && left.resultType == right.resultType) {
+    else if (isMap(left.resultType) && canEqual) {
       generateMapComparison(ctx, left, right)
     }
     // comparable types of same type
-    else if (isComparable(left.resultType) && left.resultType == right.resultType) {
+    else if (isComparable(left.resultType) && canEqual) {
       generateComparison(ctx, "==", left, right)
     }
     // support date/time/timestamp equalTo string.
     // for performance, we cast literal string to literal time.
-    else if (isTimePoint(left.resultType) && right.resultType == InternalTypes.STRING) {
+    else if (isTimePoint(left.resultType) && right.resultType.getTypeRoot == VARCHAR) {
       if (right.literal) {
         generateEquals(ctx, left, generateCastStringLiteralToDateTime(ctx, right, left.resultType))
       } else {
         generateEquals(ctx, left, generateCast(ctx, right, left.resultType))
       }
     }
-    else if (isTimePoint(right.resultType) && left.resultType == InternalTypes.STRING) {
+    else if (isTimePoint(right.resultType) && left.resultType.getTypeRoot == VARCHAR) {
       if (left.literal) {
         generateEquals(
           ctx,
@@ -364,7 +367,7 @@ object ScalarOperatorGens {
     }
     // non comparable types
     else {
-      generateOperatorIfNotNull(ctx, InternalTypes.BOOLEAN, left, right) {
+      generateOperatorIfNotNull(ctx, new BooleanType(), left, right) {
         if (isReference(left)) {
           (leftTerm, rightTerm) => s"$leftTerm.equals($rightTerm)"
         }
@@ -384,8 +387,8 @@ object ScalarOperatorGens {
       left: GeneratedExpression,
       right: GeneratedExpression)
     : GeneratedExpression = {
-    if (left.resultType == InternalTypes.STRING && right.resultType == InternalTypes.STRING) {
-      generateOperatorIfNotNull(ctx, InternalTypes.BOOLEAN, left, right) {
+    if (left.resultType.isInstanceOf[VarCharType] && right.resultType.isInstanceOf[VarCharType]) {
+      generateOperatorIfNotNull(ctx, new BooleanType(), left, right) {
         (leftTerm, rightTerm) => s"!$leftTerm.equals($rightTerm)"
       }
     }
@@ -394,28 +397,30 @@ object ScalarOperatorGens {
       generateComparison(ctx, "!=", left, right)
     }
     // temporal types
-    else if (isTemporal(left.resultType) && left.resultType == right.resultType) {
+    else if (isTemporal(left.resultType) &&
+        isInteroperable(left.resultType, right.resultType)) {
       generateComparison(ctx, "!=", left, right)
     }
     // array types
-    else if (isArray(left.resultType) && left.resultType == right.resultType) {
+    else if (isArray(left.resultType) && isInteroperable(left.resultType, right.resultType)) {
       val equalsExpr = generateEquals(ctx, left, right)
       GeneratedExpression(
-        s"(!${equalsExpr.resultTerm})", equalsExpr.nullTerm, equalsExpr.code, InternalTypes.BOOLEAN)
+        s"(!${equalsExpr.resultTerm})", equalsExpr.nullTerm, equalsExpr.code, new BooleanType())
     }
     // map types
-    else if (isMap(left.resultType) && left.resultType == right.resultType) {
+    else if (isMap(left.resultType) && isInteroperable(left.resultType, right.resultType)) {
       val equalsExpr = generateEquals(ctx, left, right)
       GeneratedExpression(
-        s"(!${equalsExpr.resultTerm})", equalsExpr.nullTerm, equalsExpr.code, InternalTypes.BOOLEAN)
+        s"(!${equalsExpr.resultTerm})", equalsExpr.nullTerm, equalsExpr.code, new BooleanType())
     }
     // comparable types
-    else if (isComparable(left.resultType) && left.resultType == right.resultType) {
+    else if (isComparable(left.resultType) &&
+        isInteroperable(left.resultType, right.resultType)) {
       generateComparison(ctx, "!=", left, right)
     }
     // non-comparable types
     else {
-      generateOperatorIfNotNull(ctx, InternalTypes.BOOLEAN, left, right) {
+      generateOperatorIfNotNull(ctx, new BooleanType(), left, right) {
         if (isReference(left)) {
           (leftTerm, rightTerm) => s"!($leftTerm.equals($rightTerm))"
         }
@@ -439,7 +444,7 @@ object ScalarOperatorGens {
       left: GeneratedExpression,
       right: GeneratedExpression)
     : GeneratedExpression = {
-    generateOperatorIfNotNull(ctx, InternalTypes.BOOLEAN, left, right) {
+    generateOperatorIfNotNull(ctx, new BooleanType(), left, right) {
       // either side is decimal
       if (isDecimal(left.resultType) || isDecimal(right.resultType)) {
         (leftTerm, rightTerm) => {
@@ -451,11 +456,13 @@ object ScalarOperatorGens {
         (leftTerm, rightTerm) => s"$leftTerm $operator $rightTerm"
       }
       // both sides are temporal of same type
-      else if (isTemporal(left.resultType) && left.resultType == right.resultType) {
+      else if (isTemporal(left.resultType) &&
+          isInteroperable(left.resultType, right.resultType)) {
         (leftTerm, rightTerm) => s"$leftTerm $operator $rightTerm"
       }
       // both sides are boolean
-      else if (isBoolean(left.resultType) && left.resultType == right.resultType) {
+      else if (isBoolean(left.resultType) &&
+          isInteroperable(left.resultType, right.resultType)) {
         operator match {
           case "==" | "!=" => (leftTerm, rightTerm) => s"$leftTerm $operator $rightTerm"
           case ">" | "<" | "<=" | ">=" =>
@@ -465,12 +472,14 @@ object ScalarOperatorGens {
         }
       }
       // both sides are binary type
... 19395 lines suppressed ...