[英]Snowflake: Decimal or null input to function results in "Unsupported subquery type"
Given the following function:鉴于以下 function:
CREATE
OR REPLACE FUNCTION myfunction(a float, b float, c float)
RETURNS float AS
$$
select sum(1/(1+exp(-(series - c)/4)))
from (
select (a + ((row_number()) over(order by 0))*1) series
from table(generator(rowcount => 10000)) x
qualify series <= b
)
$$;
I get all the expected results when executing the following queries:执行以下查询时,我得到了所有预期结果:
select
myfunction(1, 10, 1);
select
myfunction(1, 100, 1);
select
myfunction(1, 10, 1.1);
select
myfunction(0, 1, 89.87);
select
myfunction(0, 1, null);
However when I run the following query:但是,当我运行以下查询时:
select
myfunction(a, b, c)
from
(
select
1 as a,
10 as b,
1.1 as c
union
select
0 as a,
1 as b,
null as c
);
I get an error:我得到一个错误:
"Unsupported subquery type cannot be evaluated".
“无法评估不支持的子查询类型”。
While this query does work:虽然此查询确实有效:
select
a, b, myfunction(a, b, c)
from
(
select
1 as a,
10 as b,
1 as c
union
select
1 as a,
100 as b,
1 as c
);
Why can't Snowflake handle null or decimal numbers in the 'c' column when I input multiple rows while individual rows weren't a problem?为什么当我输入多行时 Snowflake 不能处理 null 或“c”列中的十进制数字,而单行不是问题? And how can this function be rewritten to be able to handle these cases?
以及如何重写这个 function 来处理这些情况?
Weird one.奇怪的一个。 Can you try selecting from the subquery and running it through a cast?
您可以尝试从子查询中选择并通过强制转换运行它吗?
Like this:像这样:
select a, b, c
from
(select cast(a as float) as a, cast(b as float) as b, cast(c as float) as c from
(
select
1 as a,
10 as b,
1 as c
union
select
1 as a,
100 as b,
null as c
) as t) as x
SQL UDFs are converted to subqueries (for now), and if Snowflake can not determine the data type returned from these subqueries, you get the "Unsupported subquery" error. SQL UDF 被转换为子查询(目前),如果 Snowflake 无法确定从这些子查询返回的数据类型,您将收到“不支持的子查询”错误。 The issue is not about decimals or null. The issue is A and C variables (which are used in SUM()) contain different values.
问题与小数或 null 无关。问题是 A 和 C 变量(在 SUM() 中使用)包含不同的值。 For example, the following ones work:
例如,以下的工作:
select
myfunction(a, b, c )
from
(
select
1 as a,
1 as b,
1.1 as c
union
select
1 as a,
100 as b,
1.1 as c
);
select
myfunction(a, b, c )
from
(
select
1 as a,
1 as b,
null as c
union
select
1 as a,
100 as b,
null as c
);
You may hit these kinds of errors when you try to write complex functions with SQL UDFs.当您尝试使用 SQL UDF 编写复杂函数时,您可能会遇到这些类型的错误。 Sometimes rewriting them can help, but I don't see a way for this one.
有时重写它们会有所帮助,但我看不出有什么办法。 As a workaround, you may re-write it in JavaScript because JS UDFs are not converted to subqueries:
作为解决方法,您可以在 JavaScript 中重写它,因为 JS UDF 不会转换为子查询:
CREATE
OR REPLACE FUNCTION myfunction(a float, b float, c float)
RETURNS float
language javascript AS
$$
var res = 0.0;
for (let series = A + 1; series <= B; series++) {
res += (1/(1+Math.exp(-(series - C)/4)));
}
return res;
$$;
According to my tests, the above UDF returns the same result as the SQL version, and it doesn't hit "Unsupported subquery" error.根据我的测试,上述 UDF 返回与 SQL 版本相同的结果,并且没有出现“不支持的子查询”错误。
In the end implementing it as a python function allowed for also handling all the edge cases:最后将其实现为 python function 还允许处理所有边缘情况:
CREATE
OR REPLACE FUNCTION myfunction(a float, b float, c float)
returns float
language python
runtime_version=3.8
handler='compute'
as
$$
def compute(a, b, c):
import math
if b < a:
return None
if c is None:
return None
res = []
step_size = 1
it = a
while it < b:
res.append(it)
it += step_size
res = sum([1/(1+math.exp(-1*(i-c)/4)) for i in res])
return res
$$;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.