@Override
        public FieldGetter<RowData> createFieldGetter(Type type, int pos) {
          final FieldGetter<RowData> fieldGetter;
          switch (type.typeId()) {
            case BOOLEAN:
              fieldGetter = RowData::getBoolean;
              break;
            case INTEGER:
            case DATE:
              fieldGetter = RowData::getInt;
              break;
            case LONG:
            case TIME:
              fieldGetter = RowData::getLong;
              break;
            case FLOAT:
              fieldGetter = RowData::getFloat;
              break;
            case DOUBLE:
              fieldGetter = RowData::getDouble;
              break;
            case TIMESTAMP:
              Types.TimestampType timestamp = (Types.TimestampType) type;
              if (timestamp.shouldAdjustToUTC()) {
                return (row, fieldPos) -> {
                  if (row.isNullAt(fieldPos)) {
                    return null;
                  }
                  return row.getTimestamp(fieldPos, 9).toInstant();
                };
              } else {
                return (row, fieldPos) -> {
                  if (row.isNullAt(fieldPos)) {
                    return null;
                  }
                  return row.getTimestamp(fieldPos, 9).toLocalDateTime();
                };
              }
            case STRING:
              fieldGetter = RowData::getString;
              break;
            case UUID:
            case FIXED:
            case BINARY:
              fieldGetter = RowData::getBinary;
              break;
            case DECIMAL:
              fieldGetter =
                  ((row, fieldPos) -> {
                    Types.DecimalType decimalType = (Types.DecimalType) type;
                    int precision = decimalType.precision();
                    int scale = decimalType.scale();
                    DecimalData decimalData = row.getDecimal(fieldPos, precision, scale);
                    return decimalData == null ? null : decimalData.toBigDecimal();
                  });
              break;
            case LIST:
              fieldGetter =
                  ((row, fieldPos) -> {
                    ArrayData arrayData = row.getArray(fieldPos);
                    // check arrayData is null or not. arrayData could be nullable.
                    if (arrayData == null) {
                      return null;
                    }
                    return new LogFlinkArrayData(arrayData);
                  });
              break;
            case MAP:
              fieldGetter =
                  ((row, fieldPos) -> {
                    MapData mapData = row.getMap(pos);
                    if (mapData == null) {
                      return null;
                    }
                    return new LogFlinkMapData(mapData);
                  });
              break;
            case STRUCT:
              fieldGetter = ((row, fieldPos) -> row.getRow(fieldPos, 0));
              break;
            default:
              throw new UnsupportedOperationException("not supported type:" + type);
          }
          return (row, fieldPos) -> {
            if (row.isNullAt(fieldPos)) {
              return null;
            }
            return fieldGetter.getFieldOrNull(row, fieldPos);
          };
        }
An implement of {@link LogData<RowData>} in flink application.
amoro-format-mixed/amoro-mixed-flink/amoro-mixed-flink-common-format/src/main/java/org/apache/amoro/flink/shuffle/LogRecordV1.java