PostgreSQL: operatore CAST vs :: sulla funzione tabella LATERALE
Finché posso
SELECT elem[1], elem[2]
FROM ( VALUES ('1,2'::TEXT) ) AS q(arr),
LATERAL CAST(String_To_Array(q.arr, ',') AS INT[]) AS elem
;
utilizzando una chiamata esplicita a CAST, non posso
SELECT elem[1], elem[2]
FROM ( VALUES ('1,2'::TEXT) ) AS q(arr),
LATERAL String_To_Array(q.arr, ',')::INT[] AS elem
;
utilizzando l' ::operatore chiamante implicitamente :
ERRORE: errore di sintassi in corrispondenza o vicino a "::"
Un'altra posizione in cui CASTè richiesto un esplicito :
CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );
Dubito che ci sia una ragione sintattica, ad esempio l'uso di parentesi di chiusura extra - che qui non è corretto.
La chiamata di funzione esplicita è semplicemente necessaria a questo punto come parte dell'implementazione di basso livello? O segue delle regole linguistiche?
Risposte
Esempi eccellenti di case d'angolo. Entrambe queste varianti di sintassi sono "cast di tipo esplicito", che fanno esattamente lo stesso. Accade così che alcune posizioni speciali nel codice SQL consentano solo la notazione funzionale per evitare ambiguità.
Per quanto riguarda la tua seconda osservazione:
Un'altra posizione in cui
CASTè richiesto un esplicito :CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );
La sintassi abbreviata può essere effettivamente utilizzata qui, con un set aggiuntivo di parentesi per renderla univoca:
CREATE INDEX ON ... ((<straw>::<gold>));
db <> fiddle qui
Inoltre, entrambe le varianti di sintassi corrispondono anche all'altra espressione nelle query. Vedere:
- Possiamo creare un indice per chiave / valore del tipo di dati JSONB?
- Come creare un indice su una proprietà json intera in postgres
- Dividere Datetime in 2 colonne per lo schema di prenotazione del ristorante?
(Ci sono modi più efficienti per fare ciò che fa il tuo primo esempio, ma probabilmente non è questo il punto.)
È un po 'strano, sì, ma la grammatica accetterà solo qualcosa di sintatticamente simile a una chiamata di funzione in un'espressione function-in-FROM.
Quindi questo è davvero un trucco che puoi usare se vuoi un'espressione arbitraria in una FROMclausola: circondala con CASTun'espressione non necessaria .
PostgreSQL tratterà felicemente tutto ciò che assomiglia a una funzione come una funzione di tabella in un tale contesto.