Подтвердить что ты не робот

Не удалось найти функцию преобразования от неизвестного до текста.

В одном из моих операторов выбора я получил следующую ошибку:

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)

4b9b3361

Ответ 1

Postgres счастлив, если он может обнаруживать типы нетипизированных констант из контекста. Но когда какой-либо контекст невозможен, а когда запрос немного сложнее, чем тривиальный, то этот механизм выходит из строя. Эти правила специфичны для любого предложения SELECT, а некоторые из них более строгие, а некоторые нет. Если я могу сказать, то более старые процедуры более терпимы (из-за более высокой совместимости с Oracle и менее негативного воздействия на новичков), современные менее терпимы (из-за более высокой степени безопасности ошибок типа).

Были некоторые предложения, которые пытались работать с любой неизвестной константой литерала, как текстовая константа, но были отклонены по другим причинам. Поэтому я не ожидаю значительных изменений в этой области. Эта проблема обычно связана с синтетическими тестами - и меньше - с реальными запросами, где типы выводятся из типов столбцов.