public static GenericUDF cloneGenericUDF(GenericUDF genericUDF) {
    if (null == genericUDF) {
      return null;
    }

    GenericUDF clonedUDF;
    if (genericUDF instanceof GenericUDFBridge) {
      GenericUDFBridge bridge = (GenericUDFBridge) genericUDF;
      clonedUDF = new GenericUDFBridge(bridge.getUdfName(), bridge.isOperator(),
          bridge.getUdfClassName());
    } else if (genericUDF instanceof GenericUDFMacro) {
      GenericUDFMacro bridge = (GenericUDFMacro) genericUDF;
      clonedUDF = new GenericUDFMacro(bridge.getMacroName(), bridge.getBody().clone(),
          bridge.getColNames(), bridge.getColTypes());
    } else {
      clonedUDF = ReflectionUtils.newInstance(genericUDF.getClass(), null);
    }

    if (clonedUDF != null) {
      // Copy info that may be required in the new copy.
      // The SettableUDF calls below could be replaced using this mechanism as well.
      try {
        genericUDF.copyToNewInstance(clonedUDF);
      } catch (UDFArgumentException err) {
        throw new IllegalArgumentException(err);
      }

      // The original may have settable info that needs to be added to the new copy.
      if (genericUDF instanceof SettableUDF) {
        try {
          TypeInfo typeInfo = ((SettableUDF)genericUDF).getTypeInfo();
          if (typeInfo != null) {
            ((SettableUDF)clonedUDF).setTypeInfo(typeInfo);
          }
        } catch (UDFArgumentException err) {
          // In theory this should not happen - if the original copy of the UDF had this
          // data, we should be able to set the UDF copy with this same settableData.
          LOG.error("Unable to add settable data to UDF " + genericUDF.getClass());
          throw new IllegalArgumentException(err);
        }
      }
    }

    return clonedUDF;
  }
Create a copy of an existing GenericUDF.
ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java