不直接回答问题,但可能相关,日期文字是用DATE
关键字声明的,例如,您可以在 Beam tests: one , two和 Calcite docs中的测试中看到示例。
更新:
似乎发生的是 Calcite 在做CASE
. 将字符串转换为日期通常可以按预期工作。例如,如果输入行有模式(INT f_int, VARCHAR f_string)
并且日期在'YYYYMMDD'
(例如(1, '2018')
,那么这有效:
SELECT f_int,
CAST(
SUBSTRING(TRIM(f_string) FROM 1 FOR 4)
||'-'
||SUBSTRING(TRIM(f_string) FROM 5 FOR 2)
||'-'
||SUBSTRING(TRIM(f_string) FROM 7 FOR 2) as DATE)
FROM PCOLLECTION
甚至直接铸造'YYYYMMDD'
作品:
SELECT f_int,
CAST(f_string AS DATE)
FROM PCOLLECTION
您可以在此处查看所有支持的日期格式。
但是,一旦您将其包装在 中'CASE ... ELSE NULL'
,Beam/Calcite 似乎会推断出表达式类型现在是'String'
. 这意味着 'THEN CAST(... AS DATE)'
成功并返回一个“日期”,但随后将其转换为'String'
包裹在'CASE'
. 然后,在我的测试中返回结果时,它似乎试图将其转换回'Date'
,但现在的字符串格式不是'YYYYMMDD'
,而是其他一些默认格式。不幸的是,该格式不在支持的列表中,所以它失败了。
解决方法:
一旦您更改'ELSE NULL'
为已知为 a 的东西'Date'
,例如'ELSE DATE "2001-01-01"'
,它就会再次工作,因为 Beam/Calcite 似乎没有通过'String'->'Date'->'String'->'Date'
路径,这有效:
SELECT f_int,
CASE WHEN CHAR_LENGTH(TRIM(f_string)) = 8
THEN CAST (
SUBSTRING(TRIM(f_string) FROM 1 FOR 4)
||'-'
||SUBSTRING(TRIM(f_string) FROM 5 FOR 2)
||'-'
||SUBSTRING(TRIM(f_string) FROM 7 FOR 2) AS DATE)
ELSE DATE '2001-01-01'
END
FROM PCOLLECTION
我提交了BEAM-5789以跟踪更好的解决方案。
更新 2:
因此,虽然 Calcite 生成计划告诉 Beam 要做什么,但在这种情况下,实际上是 Beam 投射/解析日期。努力使用 Calcite 的基本操作的内置实现,而不是重新实现 Beam 中的所有内容:
https ://github.com/apache/beam/pull/6417 。合并此拉取请求后CASE ... ELSE NULL
,如果我没看错,此路径应该会自动运行(我假设此类将用于处理日期/时间值)。它仍然会通过字符串,可能是不必要的,但它应该可以工作。