PostgreSQLはリファレンスが非常に充実していますが、サポートする機能が多彩であるため個別のケースの挙動が自明ではないことがあります。
ストアド関数は複雑なケースを扱うことが多く、挙動の観察が重要です。
呼び出し形式
ストアド関数の呼び出しはSELECT some_function();
で実行できます。
ただしテーブルを返す関数の場合には、この形式で呼び出すとカラム名が割り当てられないケースがあります。
SELECT id, name FROM some_function();
のようにFROM句で関数を呼び出すと、戻り値のテーブルにカラム指定できます。
早期リターン
PL/pgSQLのRETURN
は他の言語と異なる挙動をとる場合があるため、基本的に注意が必要です。
注意したうえで、以下のような早期リターンは実装可能です。
CREATE FUNCTION get_inventories(IN in_id integer)
RETURNS TABLE (name text, quantity integer) AS $$
BEGIN
PERFORM 1 FROM privileges p
WHERE p.id = in_id;
IF NOT FOUND THEN
RETURN;
END IF;
RETURN QUERY SELECT
i.name AS name,
i.qty AS quantity,
FROM inventories i;
END;
$$ LANGUAGE plpgsql;
テーブルを返すストアド関数では、CREATE FUNCTION ... RETURNS TABLE
の定義と、RETURN QUERY
の返す型と列名を一致させる必要があります。
よって、目的外のテーブルの値を返したい場合の簡潔な方法はありません。
この例では冒頭で別のテーブル(アクセス権限照会など)を検索し、引数にマッチするレコードがない場合にRETURN
しています。
この例では、大方の期待どおり早期リターンの挙動となります。
他のテーブルから定義に一致する型をとり出すことは難しいのですが、戻り値をセットしない場合には空行となり、型不一致エラーを避けられます。
また、引数をとるRETURN
の中には関数処理を中断しない(一般的な想像どおりでない)挙動の文もありますが、この例の書き方であればその場で関数を抜ける挙動をとります。
つまり書き方によっては早期リターンに見えるクエリが早期リターンしないことがあるものの、注意すれば早期リターンは実装可能です。
Chuma Takahiro