PostgreSQL - operator CAST vs :: na tabeli LATERAL

Nov 27 2020

Dopóki mogę

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

używając wyraźnego wezwania do CAST, nie mogę

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

używając niejawnie wywołującego ::operatora:

BŁĄD: błąd składni na poziomie „::” lub w jego pobliżu

Jeszcze jedna lokalizacja, w której CASTwymagane jest jawne :

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

Wątpię, czy jest jakiś powód składniowy, np. Użycie dodatkowego nawiasu zamykającego - co jest tutaj nieprawidłowe.

Czy jawne wywołanie funkcji jest po prostu potrzebne w tym momencie jako część implementacji niskiego poziomu? Czy też przestrzega jakichś zasad językowych?

Odpowiedzi

5 ErwinBrandstetter Nov 27 2020 at 11:35

Doskonałe przykłady skrzynek narożnych. Oba te warianty składni są „rzutami typu jawnego”, robiąc dokładnie to samo. Tak się składa, że ​​niektóre specjalne lokalizacje w kodzie SQL pozwalają tylko na notację funkcjonalną, aby uniknąć niejasności.

Jeśli chodzi o twoją drugą obserwację:

Jeszcze jedna lokalizacja, w której CASTwymagane jest jawne :

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

W rzeczywistości można tutaj użyć skróconej składni - z dodatkowym zestawem nawiasów, aby uczynić ją jednoznaczną:

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

db <> skrzypce tutaj

Każdy wariant składni pasuje również do drugiego wyrażenia w zapytaniach. Widzieć:

  • Czy możemy utworzyć indeks dla klucza / wartości typu danych JSONB?
  • Jak utworzyć indeks dla właściwości JSON typu integer w Postgres
  • Podzielenie daty i godziny na 2 kolumny w schemacie rezerwacji restauracji?

(Istnieją bardziej efektywne sposoby zrobienia tego, co robi twój pierwszy przykład, ale prawdopodobnie nie ma to znaczenia).

5 LaurenzAlbe Nov 27 2020 at 10:27

To trochę dziwne, tak, ale gramatyka akceptuje tylko coś podobnego składniowo do wywołania funkcji w wyrażeniu funkcja w FROM.

Jest to więc rzeczywiście sztuczka, której możesz użyć, jeśli chcesz mieć dowolne wyrażenie w FROMzdaniu: otocz je niepotrzebnym CASTwyrażeniem.

PostgreSQL z przyjemnością potraktuje wszystko, co wygląda jak funkcja, jako funkcję tabelową w takim kontekście.