This topic describes the dynamic parameters that are supported by MaxCompute user-defined aggregate functions (UDAFs) and user-defined table-valued functions (UDTFs) when the Resolve annotation is used.
Extension of Resolve annotation syntax
Both MaxCompute UDAFs and UDTFs use the Resolve annotation to generate 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.
- 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 in which the first parameter is of the DOUBLE data type, followed by parameters of any length and type. In this case, you must compile code to calculate the number and types of input parameters, and manage them based on theprintf
function in the C programming language.Note Asterisks (*) in return values indicate different meanings. - You can use
any
in a parameter list to indicate that parameters of all types are valid. For example,@Resolve('double,any->string')
indicates a parameter list in which the first parameter is of the DOUBLE data type and is followed by parameters of any type.Noteany
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 data type can be returned. The number of return values is based on the
number of aliases that are configured when a function is called. For example, the
call method of
@Resolve("ANY,ANY->DOUBLE,*")
isUDTF(x, y) as (a, b, c)
. In this example, three aliases a, b, and c are configured foras
. The editor identifies that a is of the DOUBLE data type and b and c are of the STRING data type. The type of values in the first column returned in the Resolve annotation is given. Three values are returned. Therefore, theforward
method called by a UDTF mustforward
an array of three elements. Otherwise, an error is returned.Note However, the error is not returned during compilation. Therefore, the UDTF caller must configure the number of aliases in SQL based on the rule that is defined in the UDTF. The number of return values of an aggregate function is fixed to 1. Therefore, this rule has no effect on UDAFs.
UDTF examples
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 data 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 based on 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 the parsing of the JSON file. If no error occurs, the content that is generated
during the parsing of the JSON file is provided based on the sequence of input keys.
Example: -- Configure 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 do not meet your business requirements, we recommend that you use UDTs to implement the features of aggregate functions and UDTFs. For more information, see Overview.
Note For more information about Python UDTFs and Python UDAFs, see Python 3 UDAF and Use a Python 3 UDTF to read resources from MaxCompute.