PostgreSQL - CAST vs :: Operator für die Funktion LATERAL table

Nov 27 2020

Solange ich kann

SELECT elem[1], elem[2]
FROM   ( VALUES ('1,2'::TEXT) ) AS q(arr),
       LATERAL CAST(String_To_Array(q.arr, ',') AS INT[]) AS elem
;

Mit einem expliziten Aufruf an CASTkann ich nicht

SELECT elem[1], elem[2]
FROM   ( VALUES ('1,2'::TEXT) ) AS q(arr),
       LATERAL String_To_Array(q.arr, ',')::INT[] AS elem
;

Verwenden des implizit aufrufenden ::Operators:

FEHLER: Syntaxfehler bei oder in der Nähe von "::"

Ein weiterer Ort, an dem eine explizite CASTAnforderung erforderlich ist:

CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );

Ich bezweifle, dass es einen syntaktischen Grund gibt, z. B. die Verwendung einer zusätzlichen Klammer - was hier falsch ist.

Wird der explizite Funktionsaufruf an dieser Stelle lediglich als Teil der Low-Level-Implementierung benötigt? Oder folgt es irgendwelchen Sprachregeln?

Antworten

5 ErwinBrandstetter Nov 27 2020 at 11:35

Hervorragende Beispiele für Eckfälle. Beide Syntaxvarianten sind "explizite Typumwandlungen", die genau dasselbe tun. Es ist nur so, dass einige spezielle Stellen im SQL-Code nur die funktionale Notation zulassen, um Mehrdeutigkeiten zu vermeiden.

Wie für Ihre zweite Beobachtung:

Ein weiterer Ort, an dem eine explizite CASTAnforderung erforderlich ist:

CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );

Hier kann tatsächlich die Kurzschrift-Syntax verwendet werden - mit einem zusätzlichen Satz von Klammern, um sie eindeutig zu machen:

CREATE INDEX ON ... ((<straw>::<gold>));

db <> hier fummeln

Und jede Syntaxvariante stimmt auch in Abfragen mit dem anderen Ausdruck überein. Sehen:

  • Können wir einen Index für den Schlüssel / Wert des JSONB-Datentyps erstellen?
  • So erstellen Sie einen Index für eine ganzzahlige json-Eigenschaft in postgres
  • Datetime in 2 Spalten für das Restaurantreservierungsschema aufteilen?

(Es gibt effizientere Möglichkeiten, um das zu tun, was Ihr erstes Beispiel tut, aber das ist wahrscheinlich nebensächlich.)

5 LaurenzAlbe Nov 27 2020 at 10:27

Es ist ein bisschen komisch, ja, aber die Grammatik akzeptiert nur etwas, das syntaktisch einem Funktionsaufruf in einem Function-in-FROM-Ausdruck ähnelt.

Das ist in der Tat ein Trick, den Sie verwenden können, wenn Sie einen beliebigen Ausdruck in einer FROMKlausel möchten : Umgeben Sie ihn mit einem unnötigen CASTAusdruck.

PostgreSQL behandelt in einem solchen Kontext gerne alles, was wie eine Funktion aussieht, als Tabellenfunktion.