如何在Bigquery UDF中传递函数作为参数?



我的问题是:

如何在Bigquery UDF中传递函数作为参数?

我想从两组私有函数创建一个bigquery udf库:

  • functionA, functionB, functionC
  • function1, function2, function3

我想公开从两个集合的每个函数组合构建的mixin udf。

我想避免源代码中的代码重复。

到目前为止,我找到的两个解决方案是:

解决方案1:

在函数内部使用一个唯一的公共UDF,带有两个字符串参数和一个开关箱。

例如:

mypublic_UDF(*args, "functionA", "function1")
mypublic_UDF(*args, "functionA", "function3")
mypublic_UDF(*args, "functionB", "function1")

然而,这个解决方案没有从bigquery SQL自省、预运行错误和警告检查中获益,并且涉及对每行的参数进行解析。


解决方案2:

使用在新函数中实例化每种情况的部署脚本

例如:

mypublic_UDF_functionA_function1(*args)
mypublic_UDF_functionA_function3(*args)
mypublic_UDF_functionB_function1(*args)

然而,这个解决方案需要更多的逻辑来部署脚本和生成大量的函数。


是否有首选/最佳解决方案?

编辑:

我的代码太复杂了,不能在这里展示,但这里有一个具体的例子。

CREATE TEMP FUNCTION functionA (myint NUMERIC)
AS (IF( mod(myint,3)=1, myint, NULL));
CREATE TEMP FUNCTION functionB (myint NUMERIC)
AS (IF( mod(myint,4)>3, myint, NULL));
CREATE TEMP FUNCTION functionC (myint NUMERIC)
AS (IF( mod(myint*myint-1,5)=0, myint, NULL));
CREATE TEMP FUNCTION function1 (myint NUMERIC)
AS (SQRT(ABS(myint)));
CREATE TEMP FUNCTION function2 (myint NUMERIC)
AS (LEAST(GREATEST(myint,-1),1));
CREATE TEMP FUNCTION function3 (myint NUMERIC)
AS (1/GREATEST(myint,1));
--------------------------------------------------------
-- SOLUTION 1
--------------------------------------------------------
CREATE TEMP FUNCTION first_functionset
(myint NUMERIC, mytype STRING)
AS (
CASE mytype
WHEN 'functionA' THEN functionA(myint)
WHEN 'functionB' THEN functionB(myint)
WHEN 'functionC' THEN functionC(myint)
ELSE ERROR('Unknown function name')
END
);

CREATE TEMP FUNCTION second_functionset
(myint NUMERIC, mytype STRING)
AS (
CASE mytype
WHEN 'function1' THEN function1(myint)
WHEN 'function2' THEN function2(myint)
WHEN 'function3' THEN function3(myint)
ELSE ERROR('Unknown function name')
END
);
CREATE TEMP FUNCTION mypublic_UDF
(myarray ARRAY<INT64>, param1 STRING, param2 STRING)
AS ((SELECT array_agg(first_functionset(second_functionset(x,param2),param1) IGNORE NULLS)
from
unnest(myarray) x
));
--------------------------------------------------------
-- SOLUTION 2
--------------------------------------------------------

CREATE TEMP FUNCTION mypublic_UDF_functionA_function1
(myarray ARRAY<INT64>)
AS ((SELECT array_agg(functionA(function1(x)) IGNORE NULLS)
from
unnest(myarray) x
));
CREATE TEMP FUNCTION mypublic_UDF_functionA_function2
(myarray ARRAY<INT64>)
AS ((SELECT array_agg(functionA(function2(x)) IGNORE NULLS)
from
unnest(myarray) x
));
CREATE TEMP FUNCTION mypublic_UDF_functionA_function3
(myarray ARRAY<INT64>)
AS ((SELECT array_agg(functionA(function3(x)) IGNORE NULLS)
from
unnest(myarray) x
));
CREATE TEMP FUNCTION mypublic_UDF_functionB_function1
(myarray ARRAY<INT64>)
AS ((SELECT array_agg(functionB(function1(x)) IGNORE NULLS)
from
unnest(myarray) x
));
-- and so on

Select
-- SOLUTION 1
mypublic_UDF(GENERATE_ARRAY(0,100), 'functionA', 'function1'),
mypublic_UDF(GENERATE_ARRAY(0,100), 'functionA', 'function3'),
mypublic_UDF(GENERATE_ARRAY(0,100), 'functionB', 'function1'),
-- SOLUTION 2
mypublic_UDF_functionA_function1(GENERATE_ARRAY(0,100)),
mypublic_UDF_functionA_function3(GENERATE_ARRAY(0,100)),
mypublic_UDF_functionB_function1(GENERATE_ARRAY(0,100)),

它将适用于解决方案1:一个函数具有不同的参数。然而,可读性也很重要。您能否将6个内部函数的查询分别放入单独的udf中?主mypublic_UDF总是可以调用其中的两个。

请随意在您的UDF中给出,我将为改进bigquery SQL自省添加这个答案

相关内容

  • 没有找到相关文章

最新更新