Konvertierungsfunktion von unbekannt in Text konnte nicht gefunden werden

75

In einer meiner select-Anweisungen habe ich den folgenden Fehler erhalten:

ERROR:  failed to find conversion function from unknown to text
********** Error **********
ERROR: failed to find conversion function from unknown to text
SQL state: XX000

Dies war leicht zu beheben cast, aber ich verstehe nicht ganz, warum es passiert ist. Ich werde meine Verwirrung mit zwei einfachen Aussagen veranschaulichen.

Dieser ist in Ordnung:

select 'text'
union all
select 'text';

Dies gibt einen Fehler zurück:

with t as (select 'text')    
select * from t
union all
select 'text'

Ich weiß, dass ich es leicht beheben kann:

with t as (select 'text'::text)    
select * from t
union all
select 'text'

Warum schlägt die Konvertierung im zweiten Beispiel fehl? Gibt es eine Logik, die ich nicht verstehe, oder wird diese in zukünftigen Versionen von PostgreSQL behoben?

PostgreSQL 9.1.9

Das gleiche Verhalten unter PostgreSQL 9.2.4 ( SQL Fiddle )

Tomas Greif
quelle
::texthat bei mir nicht funktioniert. Bei dieser Lösung wurde "Text" vor das Textliteral gestellt
Chris
Die Verwendung von PostgreSQL 9.6 löst die Ausnahme aus. Die Verwendung von PostgreSQL 10 und höher funktioniert jedoch ... (überprüft mit db-fiddle.com )
kaaas

Antworten:

68

Postgres freut sich, wenn es Typen untypisierter Konstanten aus dem Kontext erkennen kann. Wenn jedoch kein Kontext möglich ist und die Abfrage etwas komplexer als trivial ist, schlägt dieser Mechanismus fehl. Diese Regeln sind spezifisch für jede SELECT-Klausel, und einige sind strenger, andere nicht. Wenn ich sagen kann, sind ältere Routinen toleranter (aufgrund höherer Kompatibilität mit Oracle und weniger negativen Auswirkungen auf Anfänger), moderne weniger tolerant (aufgrund höherer Sicherheit gegenüber Tippfehlern).

Es gab einige Vorschläge, die versuchten, mit einer unbekannten Literalkonstante wie der Textkonstante zu arbeiten, die jedoch aus weiteren Gründen abgelehnt wurde. Ich erwarte daher keine wesentlichen Änderungen in diesem Bereich. Dieses Problem hängt normalerweise mit synthetischen Tests zusammen - und weniger mit realen Abfragen, bei denen Typen aus Spaltentypen abgeleitet werden.

Pavel Stehule
quelle
5
Aha. Ich bin im wirklichen Leben ziemlich häufig mit diesem Problem konfrontiert. Wir verwenden PostgreSQL für Analytics / Bi / Data Mining und die Vereinigung untypisierter Konstanten ist üblich. Aber wie gesagt, es ist leicht zu besetzen.
Tomas Greif
3
Warum muss ich keine numerischen Literale wie 1::int?
Iain Samuel McLean Elder
1
@IainElder - numerische Typen sind kleinere Klassen - jede Literalkonstante (als "unbekannt" bezeichnet) kann implizit in einen beliebigen Typ umgewandelt werden - Nummer nicht - also funktioniert sin ('2.34'), Länge (1) nicht
Pavel Stehule
4
Ich komme immer wieder auf diese Frage zurück, während ich versuche, unionErgebnisse zu erzielen. Und in Zukunft bin ich faul, also lese ich nicht die gesamte Frage, die tatsächlich die Antwort enthält: Konvertieren Sie die Werte der Union in Text.
Samthebrand