public static TypeInformation<Row> decorateRowTypeWithNeededHeadFields(
            @Nullable String timeFieldName,
            @Nullable String attributesFieldName,
            RowTypeInfo dataRowType) {
        List<String> fieldNames = new ArrayList<>();
        List<TypeInformation<?>> fieldTypes = new ArrayList<>();

        if (timeFieldName != null) {
            fieldNames.add(timeFieldName);
            fieldTypes.add(Types.SQL_TIMESTAMP);
        }

        if (attributesFieldName != null) {
            fieldNames.add(attributesFieldName);
            fieldTypes.add(Types.MAP(Types.STRING, Types.STRING));
        }

        String[] dataFieldNames = dataRowType.getFieldNames();
        TypeInformation<?>[] dataFieldTypes = dataRowType.getFieldTypes();

        for (int i = 0; i < dataFieldNames.length; ++i) {
            fieldNames.add(dataFieldNames[i]);
            fieldTypes.add(dataFieldTypes[i]);
        }

        return Types.ROW_NAMED(
                fieldNames.toArray(new String[0]),
                fieldTypes.toArray(new TypeInformation[0]));
    }
Creates the type information with given field names and data schema.

@param timeFieldName The name of the time field. Null if the time field is not required.
@param attributesFieldName The name of the attributes field. Null if the attributes field is
                           not required.
@param dataRowType The type of the data fields.
@return The type information
inlong-sort/sort-formats/format-row/format-inlongmsg-base/src/main/java/org/apache/inlong/sort/formats/inlongmsg/row/InLongMsgUtils.java