Snowflake cloud data platform 尝试获取不同值时出现Snowflake JSON未知关键字错误

Snowflake cloud data platform 尝试获取不同值时出现Snowflake JSON未知关键字错误,snowflake-cloud-data-platform,Snowflake Cloud Data Platform,我在Snowflake中有一个表,其中一个名为“value”的字段有时是纯文本,有时是JSON,这个字段在Snowflake中存储为字符串 我创建这个视图是为了只获取Json格式的行 CREATE OR REPLACE VIEW tmp_events AS SELECT PARSE_JSON(value) as json_data, id FROM SessionEvent WHERE session_event_type_id=7; 然后我将行

我在Snowflake中有一个表,其中一个名为“value”的字段有时是纯文本,有时是JSON,这个字段在Snowflake中存储为字符串

我创建这个视图是为了只获取Json格式的行

CREATE OR REPLACE VIEW tmp_events AS
    SELECT PARSE_JSON(value) as json_data,
           id
    FROM SessionEvent 
    WHERE session_event_type_id=7;
然后我将行展平以创建一个新字段

CREATE OR REPLACE VIEW tmp_events_step2 AS
     SELECT id,
            json_data:meta:selected::string AS choice
         from tmp_events ,
     LATERAL FLATTEN(input => tmp_events.json_data)
     WHERE choice IS NOT NULL
到目前为止,一切都运行良好,我可以预览这两个视图中的数据,没有错误,我得到了预期的结果

当我试图从choice中获取不同的值时,会出现错误

 SELECT DISTINCT choice from tmp_events_step2;
解析JSON时出错:未知关键字brain,位置6

这个名字Brain似乎来自我的初始表格,没有WHERE语句

如果我在不使用DISTINCT的情况下运行查询,则不会出现错误

我在调试时注意到一件奇怪的事情:当我在tmp_events_step2中设置一个限制时,代码再次正常工作,尽管我设置的限制大于表中的行数

CREATE OR REPLACE VIEW tmp_events_step2 AS
     SELECT id,
            json_data:meta:selected::string AS choice
         from tmp_events ,
     LATERAL FLATTEN(input => tmp_events.json_data)
     WHERE choice IS NOT NULL
     LIMIT 10000000;
SELECT DISTINCT choice from tmp_events_step2;

有什么问题吗?为什么它只在限制条件下工作?

请提交此问题的支持案例。

请提交此问题的支持案例。

非常简单的答案是内置函数

呃不是。查询优化器似乎有问题,可能会执行不正确的谓词下推。防止优化器执行此操作的一种方法是使用安全视图选项:

CREATE SECURE VIEW tmp_events_step2 ...

并提交一份支持票…

对此非常简单的答案是内置函数

呃不是。查询优化器似乎有问题,可能会执行不正确的谓词下推。防止优化器执行此操作的一种方法是使用安全视图选项:

CREATE SECURE VIEW tmp_events_step2 ...

并提交一份支持票证…

我们在两年前报告了这个错误,他们说他们不会在何处修复,因为在运行where子句中的过滤器之前提升JSON访问权限会使强制转换有效/安全,影响性能

create table variant_cast_bug(num number, var variant);

insert into variant_cast_bug
    select column1 as num, parse_json(column2) as var
    from values (1, '{"id": 1}'), 
            (1, '{"id": 2}'),
            (2, '{"id": "text"}')
            v;

select * from variant_cast_bug;
select var:id from variant_cast_bug;
select var:id from variant_cast_bug where num = 1;
select var:id::number from variant_cast_bug where num = 1; -- <- broken
select TRY_TO_NUMBER(var:id) from variant_cast_bug where num = 1; -- <- works
有时,您可以嵌套select,它会工作,然后您可以在它周围添加另一个select层,并进行一些聚合,成本再次爆炸

正如Hans提到的,仅有的两种安全解决方案是SERCURE视图,但这是一场性能噩梦。 或者了解这个问题并使用它或者它的朋友

当时情况变得更糟,因为JSON布尔值不是要传递给TRY_to_boolean的有效值


有一次我们被这件事烧坏了,那是在一个雪花版本发布后,运行了一年的代码开始出现这个错误,因为它太复杂了,吊装并没有造成影响,然后在发布后就出现了。这就是Snowflake的响应速度非常快的地方,然后将版本回滚,为了安全起见,我们在已经运行的SQL上添加了TRY\u TO,因为在运行WHERE子句中的过滤器之前提升JSON访问权限会使强制转换有效/安全,从而影响性能

create table variant_cast_bug(num number, var variant);

insert into variant_cast_bug
    select column1 as num, parse_json(column2) as var
    from values (1, '{"id": 1}'), 
            (1, '{"id": 2}'),
            (2, '{"id": "text"}')
            v;

select * from variant_cast_bug;
select var:id from variant_cast_bug;
select var:id from variant_cast_bug where num = 1;
select var:id::number from variant_cast_bug where num = 1; -- <- broken
select TRY_TO_NUMBER(var:id) from variant_cast_bug where num = 1; -- <- works
有时,您可以嵌套select,它会工作,然后您可以在它周围添加另一个select层,并进行一些聚合,成本再次爆炸

正如Hans提到的,仅有的两种安全解决方案是SERCURE视图,但这是一场性能噩梦。 或者了解这个问题并使用它或者它的朋友

当时情况变得更糟,因为JSON布尔值不是要传递给TRY_to_boolean的有效值


有一次我们被这件事烧坏了,那是在一个雪花版本发布后,运行了一年的代码开始出现这个错误,因为它太复杂了,吊装并没有造成影响,然后在发布后就出现了。这就是Snowflake的响应速度非常快的地方,然后将版本回滚,为了安全起见,我们在已经运行的SQL上添加了TRY\u TO。

非常感谢!它的工作与安全的看法,我会提交一张票的支持非常感谢!它在安全视图下工作,我将向支持提交一张票证。坏代码现在已修复,工作代码现在已损坏。坏代码现在已修复,工作代码现在已损坏。