This topic describes the dynamic parameters supported by MaxCompute user-defined aggregate functions (UDAFs) and user-defined table-valued functions (UDTFs) when the Resolve annotation is used.

Resolve annotation syntax extension

Both MaxCompute UDAFs and UDTFs use the Resolve annotation to determine the signature of a function. However, this method cannot be overloaded, because the input and output parameters are fixed.
@com.aliyun.odps.udf.annotation.Resolve("BIGINT->DOUBLE")
public class UDTFClass extends UDTF {
    ...
}
Note This example defines a UDTF that accepts parameters of the BIGINT type and returns values of the DOUBLE type.
The syntax of the Resolve annotation in MaxCompute is extended as follows:
  • You can use an asterisk (*) in a parameter list to indicate that an input parameter can be of any length and type. For example, @Resolve('double,*->String') indicates a parameter list where the first parameter is of the DOUBLE type, followed by parameters of any length and type. In this case, you must compile code to determine the number and types of input parameters, and then manage them based on the printf function in the C programming language.
    Note Asterisks (*) indicate different meanings in return values.
  • You can use any in a parameter list to indicate that any type of the parameter is acceptable. For example, @Resolve('double,any->string') indicates a parameter list where the first parameter is of the DOUBLE type, followed by parameters of any type.
    Note any cannot be used in return values or subtypes of complex data types, such as ARRAY.
  • Asterisks can be used in return values of UDTFs to indicate that any number of values of the STRING type can be returned. The number of return values depends on the number of aliases configured when a function is called. For example, the call method of @Resolve("ANY,ANY->DOUBLE,*") is UDTF(x, y) as (a, b, c). In this example, three aliases a, b, and c are configured for as. The editor identifies that a is of the DOUBLE type and b and c are of the STRING type. The type of values in the first column returned in the Resolve annotation is given. There are three return values. Therefore, the forward method called by a UDTF must be an array of three elements. Otherwise, an error is returned.
    Note However, the error is not returned during compilation. Therefore, the UDTF caller must follow the rules defined by the UDTF when setting the number of aliases in SQL. The number of return values of an aggregate function is fixed to 1, so this rule has no effect on UDAFs.

UDTF example

import com.aliyun.odps.udf.UDFException;
import com.aliyun.odps.udf.UDTF;
import com.aliyun.odps.udf.annotation.Resolve;
import org.json.JSONException;
import org.json.JSONObject;
@Resolve("STRING,*->STRING,*")
public class JsonTuple extends UDTF {
  private Object[] result = null;
  @Override
  public void process(Object[] input) throws UDFException {
    if (result == null) {
      result = new Object[input.length];
    }
    try {
      JSONObject obj = new JSONObject((String)input[0]);
      for (int i = 1; i < input.length; i++) {
        // The variable-length part of a return value must be of the STRING type.
        result[i] = String.valueOf(obj.get((String)(input[i])));
      }
      result[0] = null;
    } catch (JSONException ex) {
      for (int i = 1; i < result.length; i++) {
        result[i] = null;
      }
      result[0] = ex.getMessage();
    }
    forward(result);
  }
}
In this example, the number of return values is determined by the number of input parameters. The first output parameter indicates a JSON file, and the other output parameters are the keys parsed from the JSON file. The first return value is an error message during JSON file parsing. If no error occurs, the content parsed from the JSON file is provided based on the sequence of input keys. The following is an example:
-- Set the number of output aliases based on that of input parameters.
SELECT my_json_tuple(json, 'a', 'b') as exceptions, a, b FROM jsons;

-- The variable-length part can have no columns.
SELECT my_json_tuple(json) as exceptions, a, b FROM jsons;

-- An error occurs when the following SQL statement is executed because the number of aliases does not match the actual number.
-- This error is not returned during compilation.
SELECT my_json_tuple(json, 'a', 'b') as exceptions, a, b, c FROM jsons;

If the extensions described in this topic fail to meet your business needs, we recommend that you use UDTs to implement the features of aggregate functions and UDTFs. For more information, see UDT.