Откуда происходит волшебная колонка «имя»?

11

Я получил это случайно:

db=> select name from site;
ERROR:  column "name" does not exist
LINE 1: select name from site;
               ^
db=> select site.name from site;
     name
---------------
 (1,mysitename)
(1 row)

Второй запрос возвращает кортеж, содержащий целую строку. Использование postgres 9.0.1.

Редактировать: определение сайта по запросу. Мне не важно, эта причудливость работает для любого стола.

db=> \d site
                         Table "public.site"
 Column |  Type   |                     Modifiers
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('site_id_seq'::regclass)
 title  | text    | not null
гегемон
источник
Это помогло бы показать определение site.
Питер Айзентраут
~ Это имеет значение, потому что теперь мы можем видеть, что siteдля начала нет «имени» . Почему вы запрашиваете столбец, который не существует?
Jcolebrand
1
Попробуй select site from site- это поможет тебе понять ответ Гая более подробно
Джек говорит, попробуй topanswers.xyz

Ответы:

11

NAMEна самом деле функция . Это особенность Postgres, что функция с одним аргументом, например, function(arg)также может быть вызвана как arg.function. Из документов:

Эквивалентность между функциональной нотацией и нотацией атрибута позволяет использовать функции на составных типах для эмуляции «вычисляемых полей».

NAMEявляется внутренним типом для имен объектов , и эта функция приводит свой аргумент к этому типу и возвращает его.

Gaius
источник
Спасибо, я этого не знал. Что меня беспокоит, если эта конкретная функция «имя» где-то задокументирована?
гегемон
Обновлено мой ответ
Гай
2
Точнее, rowтип приводится к типу, textпотому что это тип ввода функции name. Затем nameфункция преобразует (не преобразует) входную строку в тип name(что также будет иметь побочный эффект сокращения до 64 байт)
Джек говорит, что попробуйте topanswers.xyz
3

Также обратите внимание, что неявное приведение к имени было удалено в PostgreSQL 8.3, что означает, что это поведение больше не работает. Практически невозможно случайно получить такое поведение в PostgreSQL 8.3 и выше, потому что кортежи не преобразуются автоматически в текст.

Итак, в 9.1:

or_examples=# select c.name from comp_table_test c;
ERROR:  column c.name does not exist
LINE 1: select c.name from comp_table_test c;

но чтобы получить такое поведение, мы должны:

or_examples=# select name(c::text) from comp_table_test c;

Или мы могли бы определить нашу собственную функцию имени, принимающую тип comp_table_test и возвращающую все, что мы хотели.

Крис Траверс
источник
Я не понимаю этот ответ. Вы говорите, что вопрос, поставленный выше, не должен быть проблемой больше на 8.3 или выше? И все же вопрос задается около 9.0
Colin 't Hart
0

«имя» является зарезервированным ключевым словом . Таким образом, вы должны "процитировать" ключевое слово, чтобы использовать его:

SELECT "name" FROM site;

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

select site.name from site;

слово, потому что вы явно используете схему для разрешения имени столбца

DrColossos
источник
1
Можно использовать много зарезервированных слов, и в этом случае цитирование не помогает. Это связано с тем, что если site.name не существует в виде столбца, то, до 8.3, произойдет то, что вы начнете искать функции имен, принимающие тип данных сайта или тип, неявно приведенный с сайта. Поскольку сайт может быть неявно приведен к тексту, будет использоваться имя (текст). Следовательно, select site.name from siteможет быть неявно преобразовано в то, select name(site::text) from siteоткуда происходит магия.
Крис Трэверс