public static DataType appendRowFields(DataType dataType, List<DataTypes.Field> fields) {
        Preconditions.checkArgument(dataType.getLogicalType().is(ROW), "Row data type expected.");
        if (fields.size() == 0) {
            return dataType;
        }
        DataType newRow =
                Stream.concat(DataType.getFields(dataType).stream(), fields.stream())
                        .collect(Collectors.collectingAndThen(Collectors.toList(), DataTypes::ROW));
        if (!dataType.getLogicalType().isNullable()) {
            newRow = newRow.notNull();
        }
        return newRow;
    }
@Test
    void testAppendRowFields() {
        assertThat(
                        DataTypeUtils.appendRowFields(
                                ROW(
                                        FIELD("a0", BOOLEAN()),
                                        FIELD("a1", DOUBLE()),
                                        FIELD("a2", INT())),
                                Arrays.asList(FIELD("a3", BIGINT()), FIELD("a4", TIMESTAMP(3)))))
                .isEqualTo(
                        ROW(
                                FIELD("a0", BOOLEAN()),
                                FIELD("a1", DOUBLE()),
                                FIELD("a2", INT()),
                                FIELD("a3", BIGINT()),
                                FIELD("a4", TIMESTAMP(3))));

        assertThat(
                        DataTypeUtils.appendRowFields(
                                ROW(), Arrays.asList(FIELD("a", BOOLEAN()), FIELD("b", INT()))))
                .isEqualTo(ROW(FIELD("a", BOOLEAN()), FIELD("b", INT())));
    }