@Override
  public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
    if (arguments.length != 2) {
      throw new UDFArgumentLengthException(
        "ICEBERG_BUCKET requires 2 arguments (value, bucketCount), but got " + arguments.length);
    }

    truncateLength = getTruncateLength(arguments[1]);

    if (arguments[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
      throw new UDFArgumentException(
        "ICEBERG_BUCKET first argument takes primitive types, got " + argumentOI.getTypeName());
    }
    argumentOI = (PrimitiveObjectInspector) arguments[0];

    PrimitiveObjectInspector.PrimitiveCategory inputType = argumentOI.getPrimitiveCategory();
    ObjectInspector outputOI;
    switch (inputType) {
      case CHAR:
      case VARCHAR:
      case STRING:
        converter = new PrimitiveObjectInspectorConverter.StringConverter(argumentOI);
        Function<Object, Object> stringTransform = Transforms.truncate(truncateLength).bind(Types.StringType.get());
        evaluator = arg -> {
          String val = (String) converter.convert(arg.get());
          result.set(String.valueOf(stringTransform.apply(val)));
        };
        break;

      case INT:
        converter = new PrimitiveObjectInspectorConverter.IntConverter(argumentOI,
          PrimitiveObjectInspectorFactory.writableIntObjectInspector);
        Function<Object, Object> intTransform = Transforms.truncate(truncateLength).bind(Types.IntegerType.get());
        evaluator = arg -> {
          IntWritable val = (IntWritable) converter.convert(arg.get());
          result.set(String.valueOf(intTransform.apply(val.get())));
        };
        break;

      case LONG:
        converter = new PrimitiveObjectInspectorConverter.LongConverter(argumentOI,
          PrimitiveObjectInspectorFactory.writableLongObjectInspector);
        Function<Object, Object> longTransform = Transforms.truncate(truncateLength).bind(Types.LongType.get());
        evaluator = arg -> {
          LongWritable val = (LongWritable) converter.convert(arg.get());
          result.set(String.valueOf(longTransform.apply(val.get())));
        };
        break;

      case DECIMAL:
        DecimalTypeInfo decimalTypeInfo = (DecimalTypeInfo) TypeInfoUtils.getTypeInfoFromObjectInspector(argumentOI);
        Type.PrimitiveType decimalIcebergType = Types.DecimalType.of(decimalTypeInfo.getPrecision(),
            decimalTypeInfo.getScale());

        converter = new PrimitiveObjectInspectorConverter.HiveDecimalConverter(argumentOI,
          PrimitiveObjectInspectorFactory.writableHiveDecimalObjectInspector);
        Function<Object, Object> bigDecimalTransform = Transforms.truncate(truncateLength).bind(decimalIcebergType);
        evaluator = arg -> {
          HiveDecimalWritable val = (HiveDecimalWritable) converter.convert(arg.get());
          result.set(((BigDecimal) bigDecimalTransform.apply(val.getHiveDecimal().bigDecimalValue())).toPlainString());
        };
        break;

      case FLOAT:
        converter = new PrimitiveObjectInspectorConverter.FloatConverter(argumentOI,
          PrimitiveObjectInspectorFactory.writableFloatObjectInspector);
        Function<Object, Object> floatTransform = Transforms.truncate(truncateLength).bind(Types.FloatType.get());
        evaluator = arg -> {
          FloatWritable val = (FloatWritable) converter.convert(arg.get());
          result.set(String.valueOf(floatTransform.apply(val.get())));
        };
        break;

      case DOUBLE:
        converter = new PrimitiveObjectInspectorConverter.DoubleConverter(argumentOI,
          PrimitiveObjectInspectorFactory.writableDoubleObjectInspector);
        Function<Object, Object> doubleTransform = Transforms.truncate(truncateLength).bind(Types.DoubleType.get());
        evaluator = arg -> {
          DoubleWritable val = (DoubleWritable) converter.convert(arg.get());
          result.set(String.valueOf(doubleTransform.apply(val.get())));
        };
        break;

      default:
        throw new UDFArgumentException(
          " ICEBERG_TRUNCATE() only takes STRING/CHAR/VARCHAR/INT/LONG/DECIMAL/FLOAT/DOUBLE" +
          " types as first argument, got " + inputType);
    }
    outputOI = PrimitiveObjectInspectorFactory.writableStringObjectInspector;
    return outputOI;
  }
GenericUDFIcebergTruncate - UDF that wraps around Iceberg's truncate transform function
iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/udf/GenericUDFIcebergTruncate.java