PostgreSQL - оператор CAST vs :: для LATERAL табличной функции
Пока я могу
SELECT elem[1], elem[2]
FROM ( VALUES ('1,2'::TEXT) ) AS q(arr),
LATERAL CAST(String_To_Array(q.arr, ',') AS INT[]) AS elem
;
используя явный вызов CAST, я не могу
SELECT elem[1], elem[2]
FROM ( VALUES ('1,2'::TEXT) ) AS q(arr),
LATERAL String_To_Array(q.arr, ',')::INT[] AS elem
;
используя неявно вызывающий ::оператор:
ОШИБКА: синтаксическая ошибка около "::" или около него.
Еще одно место, в котором требуется явное указание CAST:
CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );
Я сомневаюсь, что есть синтаксическая причина, например, использование дополнительных скобок, что здесь неверно.
На данном этапе просто необходим явный вызов функции как часть низкоуровневой реализации? Или это соответствует каким-то языковым правилам?
Ответы
Отличные примеры угловых корпусов. Оба этих варианта синтаксиса представляют собой «явное приведение типов», выполняя одно и то же. Так уж получилось, что некоторые специальные места в коде SQL позволяют только функциональную нотацию, чтобы избежать двусмысленности.
Что касается вашего второго наблюдения:
Еще одно место, в котором требуется явное указание
CAST:CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );
Здесь действительно можно использовать сокращенный синтаксис - с дополнительным набором круглых скобок, чтобы сделать его однозначным:
CREATE INDEX ON ... ((<straw>::<gold>));
db <> скрипка здесь
И любой вариант синтаксиса также соответствует другому выражению в запросах. Видеть:
- Можем ли мы создать индекс для ключа / значения типа данных JSONB?
- Как создать индекс для целочисленного свойства json в postgres
- Разделение даты и времени на 2 столбца для схемы бронирования ресторана?
(Есть более эффективные способы сделать то, что делает ваш первый пример, но, вероятно, это не имеет значения.)
Да, это немного странно, но грамматика будет принимать только что-то синтаксически похожее на вызов функции в выражении function-in-FROM.
Так что это действительно уловка, которую вы можете использовать, если вам нужно произвольное выражение в FROMпредложении: окружите его ненужным CASTвыражением.
PostgreSQL с радостью будет рассматривать все, что выглядит как функция, как табличная функция в таком контексте.