Непосредственно не отвечая на вопрос, но может быть связано, литералы даты объявляются с ключевым словом DATE
, например, вы можете увидеть примеры в тестах в тестах Beam: one , two и в Calcite документы .
Обновление:
Похоже, что 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)'
завершается успешно и возвращает 'Date', но затем преобразуется в 'String'
при переносе в 'CASE'
. Затем, при возврате результата в моем тесте, он, кажется, пытается броситьон возвращается к 'Date'
, но формат строки теперь не 'YYYYMMDD'
, а какой-то другой формат по умолчанию. К сожалению, этот формат отсутствует в списке поддерживаемых, поэтому он не работает.
Обходной путь:
Как только вы меняете 'ELSE NULL'
на что-то, что известно как '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
должен работать автоматически, если я правильно его читаю (я предполагаю, что этот класс будет использоваться для обработки значений даты / времени).Он по-прежнему будет проходить через строки, вероятно, излишне, но он должен просто работать.