尝试获取不同值时雪花 JSON 未知关键字错误
Posted
技术标签:
【中文标题】尝试获取不同值时雪花 JSON 未知关键字错误【英文标题】:Snowflake JSON unknown keyword error when trying to get distinct values 【发布时间】:2019-11-20 04:32:35 【问题描述】:我在 Snowflake 中有一个表,其中一个名为“值”的字段有时是纯文本有时是 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
到目前为止一切正常,我可以从这两个视图中预览数据,没有错误,我得到了我期望的结果。
当我尝试从选择中获取不同的值时出现错误
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;
有什么收获?为什么它只适用于限制?
【问题讨论】:
【参考方案1】:对此非常简单的答案是内置函数TRY_PARSE_JSON()
呃,不是。您似乎对查询优化器有问题,可能会执行不正确的谓词下推。防止优化器这样做的一种方法是使用安全视图选项:
CREATE SECURE VIEW tmp_events_step2 ...
并提交支持票...
【讨论】:
非常感谢!它适用于安全视图,我将向支持人员提交票证【参考方案2】:我们在两年前报告了这个错误,他们说他们不会修复,因为在运行 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 VIEW
,但这是一场性能噩梦。
或者理解这个问题并使用TRY_TO_NUMBER或者它的朋友。
当时情况变得更糟,因为 JSON 布尔值无法传递给 TRY_TO_BOOLEAN..
有一次我们为此感到焦头烂额,是在雪花发布之后,当代码运行了一年时,开始出现此错误,因为它足够复杂,提升没有影响,然后在发布后它确实发生了。这是 Snowflake 相当敏感的地方,然后将版本回滚,我们将 TRY_TO 放在一块已经工作的 SQL 上,只是为了安全起见。
【讨论】:
损坏的代码现已修复,工作代码现已损坏。【参考方案3】:请为此问题提交支持案例。
【讨论】:
以上是关于尝试获取不同值时雪花 JSON 未知关键字错误的主要内容,如果未能解决你的问题,请参考以下文章
Snowflake METADATA$FILENAME 关键字在 snowsql(Unix 命令提示符)中不起作用,但在雪花 UI 中起作用