PostgreSQL-LATERALテーブル関数のCASTvs ::演算子

Nov 27 2020

私はできるが

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

への明示的な呼び出しを使用してCAST、私はできません

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

暗黙的に呼び出す::演算子の使用:

エラー:「::」またはその近くの構文エラー

明示CASTが必要なもう1つの場所:

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

構文上の理由があるとは思えません。たとえば、余分な囲み括弧を使用するなどです。これはここでは正しくありません。

低レベルの実装の一部として、この時点で明示的な関数呼び出しが必要なだけですか?それとも、言語の規則に従っていますか?

回答

5 ErwinBrandstetter Nov 27 2020 at 11:35

優れたコーナーケースの例。これらの構文バリアントは両方とも「明示的な型キャスト」であり、まったく同じことを行います。SQLコードの一部の特別な場所では、あいまいさを避けるために関数表記のみが許可されていることがあります。

あなたの2番目の観察に関して:

明示CASTが必要なもう1つの場所:

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

ここでは、省略構文を実際に使用できます。明確にするために、括弧のセットを追加します。

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

db <>フィドルはこちら

また、どちらの構文バリアントも、クエリ内の他の式と一致します。見る:

  • JSONBデータ型のキー/値のインデックスを作成できますか?
  • postgresで整数のjsonプロパティにインデックスを作成する方法
  • レストラン予約スキーマの日時を2列に分割しますか?

(最初の例が行うことを行うためのより効率的な方法がありますが、それはおそらく重要ではありません。)

5 LaurenzAlbe Nov 27 2020 at 10:27

はい、少し奇妙ですが、文法は、function-in-FROM式の関数呼び出しに構文的に類似したもののみを受け入れます。

したがって、これは、FROM句に任意の式が必要な場合に使用できるトリックですCAST。不要な式で囲みます。

PostgreSQLは、関数のように見えるものはすべて、そのようなコンテキストではテーブル関数として喜んで扱います。