Home > OS >  Snowflake: Decimal or null input to function results in "Unsupported subquery type"
Snowflake: Decimal or null input to function results in "Unsupported subquery type"

Time:12-30

Given the following 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? And how can this function be rewritten to be able to handle these cases?

CodePudding user response:

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

CodePudding user response:

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. The issue is not about decimals or null. The issue is A and C variables (which are used in SUM()) contain different values. 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. 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:

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.

  • Related