public static TypeInformation<RowData> decorateRowDataTypeWithNeededHeadFields(@Nullable String timeFieldName,
            @Nullable String attributesFieldName,
            RowType dataRowType) {
        List<String> fieldNames = new ArrayList<>();
        List<LogicalType> fieldTypes = new ArrayList<>();

        // Timestamp and attribute field
        if (timeFieldName != null) {
            fieldNames.add(timeFieldName);
            fieldTypes.add(new TimestampType());
        }

        if (attributesFieldName != null) {
            fieldNames.add(attributesFieldName);
            fieldTypes.add(new MapType(new VarCharType(), new VarCharType()));
        }

        // Physical fields
        List<RowType.RowField> fields = dataRowType.getFields();
        for (RowType.RowField field : fields) {
            fieldNames.add(field.getName());
            fieldTypes.add(field.getType());
        }

        RowType rowType = RowType.of(fieldTypes.toArray(new LogicalType[0]), fieldNames.toArray(new String[0]));

        return InternalTypeInfo.of(rowType);
    }
Creates the type information with given field names and data schema.

@param dataRowType         The type of the data fields.
@param metadataKeys        The metadata keys.
@return The type information
inlong-sort/sort-formats/format-rowdata/format-inlongmsg-rowdata-base/src/main/java/org/apache/inlong/sort/formats/inlongmsg/InLongMsgUtils.java