雪花 UDF 在使用“LIMIT”时表现不同

时间:2021-05-04 14:06:11

标签: javascript snowflake-cloud-data-platform

我创建了一个评估行的 UDF。在大多数情况下它工作正常,但有时它会表现得很奇怪。请参阅下面的示例。这些是完全相同的查询。一个有“限制”,另一个没有。此处的总记录数为 32,但我仅为示例添加了限制 1000。您知道为什么这两个查询的行为不同吗?

无限制 - 错误输出 enter image description here

有限制 - 正确输出 - 总记录数再次为 32。 enter image description here

1 个答案:

答案 0 :(得分:0)

功能代码:

create or replace function new_row_evaluator
       (b varchar, m datetime, f DATETIME, t datetime ) 
returns string
language javascript
as '
if (typeof tmp_barcode === "undefined") {
    tmp_barcode = B;
    tmp_fromdate = F;
    tmp_todate = T;
    return "1";
}
if (tmp_barcode == B) {
    if (M >= tmp_fromdate && M <= tmp_todate) {
        return "0";
    } else {
        tmp_fromdate = F;
        tmp_todate = T;
        return "1";
    }
} else {
    tmp_barcode = B;
    tmp_fromdate = F;
    tmp_todate = T;
    return "1";
} ';

我假设 UDF 正在使用某种全局状态 tmp_barcode

<块引用>

Global state

Snowflake 通常会在 UDF 的迭代之间保留 JavaScript 全局状态。 但是,您不应依赖先前对函数调用之间可用的全局状态的修改。此外,您不应假设所有行都将在同一 JavaScript 环境中执行。

推荐的模式是使用 JavaScript 的全局变量语义来保证相关代码只被评估一次。例如:

var setup = function() {
/* SETUP LOGIC */
};

if (typeof(setup_done) === "undefined") {
  setup();
  setup_done = true;  // setting global variable to true
}

请注意,此机制仅对缓存代码评估的效果是安全的。不能保证初始化后所有行的全局上下文都会保留,并且没有业务逻辑应该依赖它。