Woher kommt die magische Spalte "Name"?


11

Ich habe das zufällig bekommen:

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)

Die zweite Abfrage gibt ein Tupel zurück, das eine ganze Zeile enthält. Verwenden von Postgres 9.0.1.

Bearbeiten: Die Definition der Site auf Anfrage. Ich bin nicht wirklich wichtig, diese Eigenart funktioniert für jeden Tisch.

db=> \d site
                         Table "public.site"
 Column |  Type   |                     Modifiers
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('site_id_seq'::regclass)
 title  | text    | not null

Es würde helfen, die Definition von zu zeigen site.
Peter Eisentraut

~ Es ist wichtig, denn jetzt können wir sehen, dass es zunächst keinen "Namen" gibt site. Warum würden Sie nach einer Spalte fragen, die nicht existiert?
Jcolebrand

1
Versuchen Sie select site from site- dies wird Ihnen helfen, Gaius 'Antwort genauer zu verstehen
Jack sagt, versuchen Sie topanswers.xyz

Antworten:


11

NAMEist eigentlich eine Funktion . Es ist eine Eigenart von Postgres, dass eine Funktion mit einem Argument, z. B. function(arg)auch als bezeichnet werden kann arg.function. Aus den Dokumenten:

Die Äquivalenz zwischen funktionaler Notation und Attributnotation ermöglicht es, Funktionen für zusammengesetzte Typen zu verwenden, um "berechnete Felder" zu emulieren.

NAMEist ein interner Typ für Objektnamen , und diese Funktion wandelt ihr Argument in diesen Typ um und gibt ihn zurück.


Danke, das wusste ich nicht. Was stört mich, wenn diese spezielle Funktion "Name" irgendwo dokumentiert ist?
Hegemon

Aktualisiert meine Antwort
Gaius

2
Genauer gesagt wird der rowTyp umgewandelt, textda dies der Eingabetyp der Funktion ist name. Die nameFunktion konvertiert dann (ohne Casting) die Eingabezeichenfolge in Typ name(was auch den Nebeneffekt hat, auf 64 Bytes
abzuschneiden

3

Beachten Sie auch, dass die implizite Umwandlung in den Namen in PostgreSQL 8.3 entfernt wurde, was bedeutet, dass dieses Verhalten nicht mehr funktioniert. Es ist praktisch unmöglich, dieses Verhalten in PostgreSQL 8.3 und höher versehentlich zu erhalten, da Tupel nicht automatisch in Text konvertiert werden.

Also in 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;

aber um dieses Verhalten zu bekommen, müssen wir:

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

Oder wir definieren unsere eigene Namensfunktion, indem wir den Typ comp_table_test verwenden und alles zurückgeben, was wir möchten.


Ich verstehe diese Antwort nicht. Sie sagen, die oben gestellte Frage sollte ab 8.3 kein Problem mehr sein? Die Frage stellt sich jedoch nach 9.0
Colin 't Hart am

0

"Name" ist ein reserviertes Schlüsselwort . Sie sollten also das Schlüsselwort "zitieren", um es zu verwenden:

SELECT "name" FROM site;

Dies hat einige dieser Probleme in der Vergangenheit für mich gelöst, obwohl der von Ihnen veröffentlichte Code auch ohne Anführungszeichen funktionieren sollte. Auf der anderen Seite

select site.name from site;

Wort, weil Sie das Schema explizit verwenden, um den Namen der Spalte aufzulösen


1
Es können viele reservierte Wörter verwendet werden, und in diesem Fall hilft das Zitieren nicht. Dies liegt daran, dass, wenn site.name nicht als Spalte vorhanden ist, vor 8.3 nach Namensfunktionen gesucht wird, die einen Site-Datentyp oder einen Typ annehmen, der implizit von der Site übertragen wird. Da die Site implizit in Text umgewandelt werden könnte, würde der Name (Text) verwendet. Folglich select site.name from sitekönnte implizit transformiert werden, select name(site::text) from sitewoher die Magie kommt.
Chris Travers
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.