Не удалось найти функцию преобразования от неизвестного до текста.
В одном из моих операторов выбора я получил следующую ошибку:
ERROR: failed to find conversion function from unknown to text
********** Error **********
ERROR: failed to find conversion function from unknown to text
SQL state: XX000
Это было легко исправить с помощью cast
, но я не совсем понимаю, почему это произошло. Я проиллюстрирую свое замешательство двумя простыми утверждениями.
Это нормально:
select 'text'
union all
select 'text';
Это приведет к ошибке:
with t as (select 'text')
select * from t
union all
select 'text'
Я знаю, что могу легко это исправить:
with t as (select 'text'::text)
select * from t
union all
select 'text'
Почему во втором примере преобразование не выполняется? Есть ли какая-то логика, которую я не понимаю, или это будет исправлено в будущей версии PostgreSQL?
PostgreSQL 9.1.9
То же поведение в PostgreSQL 9.2.4 (SQL Fiddle)
Ответы
Ответ 1
Postgres счастлив, если он может обнаруживать типы нетипизированных констант из контекста. Но когда какой-либо контекст невозможен, а когда запрос немного сложнее, чем тривиальный, то этот механизм выходит из строя. Эти правила специфичны для любого предложения SELECT, а некоторые из них более строгие, а некоторые нет. Если я могу сказать, то более старые процедуры более терпимы (из-за более высокой совместимости с Oracle и менее негативного воздействия на новичков), современные менее терпимы (из-за более высокой степени безопасности ошибок типа).
Были некоторые предложения, которые пытались работать с любой неизвестной константой литерала, как текстовая константа, но были отклонены по другим причинам. Поэтому я не ожидаю значительных изменений в этой области. Эта проблема обычно связана с синтетическими тестами - и меньше - с реальными запросами, где типы выводятся из типов столбцов.