2013-08-06 6 views
40

In einem meiner select-Anweisungen in Text habe ich folgende Fehlermeldung bekommen:Fehler beim Umwandlungsfunktion von unbekannten zu finden

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

Das war einfach cast zu beheben, aber ich verstehe nicht ganz, warum es passiert . Ich werde meine Verwirrung mit zwei einfachen Aussagen illustrieren.

Dieser ist OK:

select 'text' 
union all 
select 'text'; 

Dieser Fehler zurück:

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

Ich weiß, dass ich es leicht beheben:

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

Warum wird die Umwandlung nicht in der zweites Beispiel? Gibt es eine Logik, die ich nicht verstehe oder die in zukünftigen Versionen von PostgreSQL behoben wird?

PostgreSQL 9.1.9

Das gleiche Verhalten auf PostgreSQL 9.2.4 (SQL Fiddle)

Antwort

36

Postgres glücklich ist, wenn es Arten von nicht typisierten Konstanten aus dem Zusammenhang erkennen kann. Aber wenn ein Kontext nicht möglich ist und wenn 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, dass ältere Routinen toleranter sind (aufgrund höherer Kompatibilität mit Oracle und weniger negativen Auswirkungen auf Anfänger), sind moderne weniger tolerant (aufgrund höherer Sicherheit bei Typfehlern).

Es gab einige Vorschläge versuchen, mit jeder unbekannten literalen Konstante wie Textkonstante zu arbeiten, wurde aber aus mehreren Gründen abgelehnt. Ich erwarte daher keine wesentlichen Änderungen in diesem Bereich. Dieses Problem bezieht sich normalerweise auf synthetische Tests - und weniger auf echte Abfragen, bei denen Typen aus Spaltentypen abgeleitet werden.

+2

Ich sehe. Ich begegne diesem Problem ziemlich oft im wirklichen Leben. Wir verwenden PostgreSQL für die Analyse/Bi/Data Mining und die Vereinigung von untypisierten Konstanten ist üblich. Aber wie gesagt, es ist einfach zu spielen. –

+1

Warum muss ich numerische Literale wie '1 :: int' nicht umwandeln? –

+0

@IainElder - numerische Typen sind kleinere Klassen - jede literale Konstante (mit dem Namen "unbekannt") kann implizit auf jeden Typ - Nummer nicht - umgewandelt werden, so dass sin ('2.34') funktioniert, aber Länge (1) nicht –