他のバージョンの文書 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

35.5. 関数のオーバーロード

使用する引数が異なるのであれば、同じSQL名の関数を1つ以上定義することができます。 つまり、関数名はオーバーロードが可能です。 問い合わせが実行された時、サーバは与えられた引数のデータ型と数によって呼び出すべき関数を決定します。 またオーバーロードを使用して、有限個の可変長引数を持つ関数を模擬することができます。

オーバーロード関数を作成する時、曖昧さが発生しないように注意しなければなりません。 例えば、以下のような関数を考えてみます。

CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(smallint, double precision) RETURNS ...

test(1, 1.5)のような平凡な入力でも、どちらの関数を呼び出すのかはすぐには明確ではありません。 現在実装されている解決規則は第10章にて説明していますが、この動作に巧妙に依存するようにシステムを設計することは推奨しません。

一般的に、1つの複合型の引数を取る関数は、その型の属性(フィールド)と同じ名前を持ってはいけません。 attribute(table)table.attributeと等価とみなされることを思い出してください。 複合型に対する関数と複合型の属性との間に曖昧さがあるような場合、属性の方が常に使用されます。 この振舞いは関数名をスキーマで修飾する(つまり、schema.func(table))ことにより変更することができますが、競合する名前を使用しないことで問題を防ぐ方が良いでしょう。

可変長引数を取る関数と可変長引数を取らない関数の間に、他にも競合する可能性があります。 例えば、foo(numeric)foo(VARIADIC numeric[])の両方を作成することが可能です。 この場合、単一の数値引数を取った呼び出し、例えばfoo(10.1)をどちらに一致するものとすべきか不明瞭です。 検索パスのより前にある関数が使われる、もし2つの関数が同一スキーマにあれば可変長引数を取らない関数が優先されるというのが、この場合の規則です。

C言語関数をオーバーロードする場合、さらに制限があります。 オーバーロードされた関数群内の各関数のCの名前は、内部か動的ロードされたかに関係なく他のすべての関数のCの名前と異なる必要があります。 この規則に反した場合は、この動作は移植性がありません。 実行時リンカエラーになるかもしれませんし、関数群のどれか(たいていは内部関数)が呼び出されるかもしれません。 CREATE FUNCTION SQLコマンドの別形式のAS句は、SQL関数名とCソースコード内の関数名とを分離します。 以下に例を示します。

CREATE FUNCTION test(int) RETURNS int
    AS 'filename', 'test_1arg'
    LANGUAGE C;
CREATE FUNCTION test(int, int) RETURNS int
    AS 'filename', 'test_2arg'
    LANGUAGE C;

ここでのC関数の名前は多くの取り得る規約の1つを反映しています。