public static TypeInformation<?> toLegacyTypeInfo(DataType dataType) {
        // time indicators first as their hashCode/equals is shared with those of regular timestamps
        if (canConvertToTimeAttributeTypeInfo(dataType)) {
            return convertToTimeAttributeTypeInfo((TimestampType) dataType.getLogicalType());
        }

        // check in the map but relax the nullability constraint as every not null data type can be
        // stored in the corresponding nullable type information
        final TypeInformation<?> foundTypeInfo = dataTypeTypeInfoMap.get(dataType.nullable());
        if (foundTypeInfo != null) {
            return foundTypeInfo;
        }

        // we are relaxing the constraint for DECIMAL, CHAR, VARCHAR, TIMESTAMP_WITHOUT_TIME_ZONE to
        // support value literals in legacy planner
        LogicalType logicalType = dataType.getLogicalType();
        if (hasRoot(logicalType, LogicalTypeRoot.DECIMAL)) {
            return Types.BIG_DEC;
        }

        else if (hasRoot(logicalType, LogicalTypeRoot.CHAR)) {
            return Types.STRING;
        }

        else if (hasRoot(logicalType, LogicalTypeRoot.VARCHAR)) {
            return Types.STRING;
        }

        // relax the precision constraint as Timestamp can store the highest precision
        else if (hasRoot(logicalType, LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE) &&
                dataType.getConversionClass() == Timestamp.class) {
            return Types.SQL_TIMESTAMP;
        }
        else if(hasRoot(logicalType, LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE) &&
                dataType.getLogicalType() instanceof TimestampType){
            return Types.SQL_TIMESTAMP;

        }
        // relax the precision constraint as LocalDateTime can store the highest precision
        else if (hasRoot(logicalType, LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE) &&
                dataType.getConversionClass() == LocalDateTime.class) {
            return Types.LOCAL_DATE_TIME;
        }

        // relax the precision constraint as LocalTime can store the highest precision
        else if (hasRoot(logicalType, LogicalTypeRoot.TIME_WITHOUT_TIME_ZONE) &&
                dataType.getConversionClass() == LocalTime.class) {
            return Types.LOCAL_TIME;
        }

        else if (canConvertToLegacyTypeInfo(dataType)) {
            return convertToLegacyTypeInfo(dataType);
        }

        else if (canConvertToRowTypeInfo(dataType)) {
            return convertToRowTypeInfo((FieldsDataType) dataType);
        }

        // this could also match for basic array type info but this is covered by legacy type info
        else if (canConvertToObjectArrayTypeInfo(dataType)) {
            return convertToObjectArrayTypeInfo((CollectionDataType) dataType);
        }

        else if (canConvertToMultisetTypeInfo(dataType)) {
            return convertToMultisetTypeInfo((CollectionDataType) dataType);
        }

        else if (canConvertToMapTypeInfo(dataType)) {
            return convertToMapTypeInfo((KeyValueDataType) dataType);
        }

        // makes the raw type accessible in the legacy planner
        else if (canConvertToRawTypeInfo(dataType)) {
            return convertToRawTypeInfo(dataType);
        }

        throw new TableException(
                String.format(
                        "Unsupported conversion from data type '%s' (conversion class: %s) to type information. Only data types " +
                                "that originated from type information fully support a reverse conversion.",
                        dataType,
                        dataType.getConversionClass().getName()));
    }
Converter between {@link TypeInformation} and {@link DataType} that reflects the behavior before
Flink 1.9. The conversion is a 1:1 mapping that allows back-and-forth conversion. Note that nullability
constraints might get lost during the back-and-forth conversion.

<p>This converter only exists to still support deprecated methods that take or return {@link TypeInformation}.
Some methods will still support type information in the future, however, the future type information
support will integrate nicer with the new type stack.

<p>This converter reflects the old behavior that includes:

<ul>
  <li>Use old {@code java.sql.*} time classes for time data types.</li>

  <li>Only support millisecond precision for timestamps or day-time intervals.</li>

  <li>Let variable precision and scale for decimal types pass through the planner.</li>

  <li>Inconsistent nullability. Most types are nullable even though type information does not support it.</li>

  <li>Distinction between {@link BasicArrayTypeInfo} and {@link ObjectArrayTypeInfo}.</li>

  <li>Let POJOs, case classes, and tuples pass through the planner.</li>
</ul>

<p>Any changes here need to be applied to the legacy planner as well.
core/src/main/java/com/dtstack/flink/sql/util/TypeInfoDataTypeConverter.java