Este tópico descreve como usar parâmetros dinâmicos com a anotação Resolve em UDAFs e UDTFs do MaxCompute.
Sintaxe estendida para a anotação Resolve
No MaxCompute, as UDAFs e UDTFs usam a anotação Resolve para determinar a assinatura da função.
@com.aliyun.odps.udf.annotation.Resolve("BIGINT->DOUBLE")
public class UDTFClass extends UDTF {
...
}
Este exemplo define uma UDTF que aceita um parâmetro de entrada BIGINT e retorna um valor DOUBLE.
O MaxCompute suporta as seguintes extensões para a sintaxe da anotação Resolve:
-
Selecione
*na lista de parâmetros de entrada para aceitar uma quantidade variável de parâmetros de entrada de qualquer tipo. Por exemplo,@Resolve('double,*->String')indica que a função aceita um DOUBLE como primeiro parâmetro de entrada, seguido por qualquer quantidade de parâmetros subsequentes de qualquer tipo. Em seguida, escreva o código para verificar a quantidade e os tipos dos parâmetros de entrada e processá-los adequadamente. Esse mecanismo é semelhante à funçãoprintfem C.NotaO asterisco tem um significado diferente na lista de valores de retorno.
-
Selecione a palavra-chave
anyna lista de parâmetros de entrada para representar um parâmetro de qualquer tipo. Por exemplo,@Resolve('double,any->string')indica que a função aceita o primeiro parâmetro de entrada do tipo DOUBLE e um segundo parâmetro de entrada de qualquer tipo.NotaA palavra-chave
anynão pode ser usada na lista de valores de retorno nem para subtipos de tipos complexos, como ARRAY. -
O valor de retorno de uma UDTF pode ser um asterisco (*), que representa uma quantidade arbitrária de valores do tipo STRING. A quantidade de valores de retorno depende da quantidade de aliases especificados ao chamar a função. Por exemplo, com a anotação
@Resolve("ANY,ANY->DOUBLE,*"), a função é chamada comoUDTF(x, y) as (a, b, c). Nesse caso, três aliases são especificados apósas: a, b e c. O editor determina queaé do tipo DOUBLE, especificado como o primeiro valor de retorno na anotação, e quebecsão do tipo STRING. Como a anotação especifica três valores de retorno, a UDTF deve passar um array de tamanho 3 paraforwardquando o métodoforwardfor chamado. Caso contrário, ocorrerá um erro em tempo de execução.NotaEsse tipo de erro não pode ser detectado em tempo de compilação. Portanto, ao chamar uma UDTF, a quantidade de aliases na sua consulta SQL deve corresponder à quantidade de colunas retornadas pela UDTF. Esse recurso não se aplica a UDAFs, que sempre têm um único valor de retorno.
Exemplo de UDTF
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 the return value must consist of STRING types.
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);
}
}
Neste exemplo de UDTF, a quantidade de parâmetros de entrada determina a quantidade de valores de retorno. O primeiro parâmetro de entrada é uma string JSON, e os parâmetros subsequentes são as chaves a serem extraídas do objeto JSON. O primeiro valor de retorno relata quaisquer erros de parsing. Se o parsing for bem-sucedido, esse valor será nulo, e os valores subsequentes serão o conteúdo extraído para cada chave. Os exemplos a seguir demonstram esta UDTF.
-- Customize the number of output aliases based on the number of input parameters.
SELECT my_json_tuple(json, 'a', 'b') as exceptions, a, b FROM jsons;
-- When no JSON fields are to be parsed, expect only the error message column.
SELECT my_json_tuple(json) as exceptions FROM jsons;
-- The following SQL statement causes a runtime error because the number of aliases
-- does not match the actual number of outputs.
-- Note that this error cannot be detected at compile time.
SELECT my_json_tuple(json, 'a', 'b') as exceptions, a, b, c FROM jsons;
Se as extensões descritas neste tópico não atenderem aos seus requisitos de negócio, implemente funcionalidades semelhantes com UDTs. Para mais informações, consulte UDT Overview.
Para exemplos de UDAFs e UDTFs em Python, consulte Python 3 UDAF e Python 3 UDTF to read MaxCompute resource example.