PostgreSQLのエラー「function does not exist」の原因と対処法まとめ

PostgreSQLのエラー「function does not exist」の原因と対処法まとめ

PostgreSQLで関数を呼び出す際に表示される「function does not exist」というエラーの原因と、その解決方法を網羅的にまとめました。エラーの具体的な発生条件や、注意すべき点、環境や構文によって異なる対処方法も細かく記載しています。

エラーの基本構文と発生例

ERROR:  function my_function(integer) does not exist
LINE 1: SELECT my_function(123);
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

このエラーは、指定された関数が存在しないか、引数の型が一致しない場合に発生します。単純なタイプミスだけでなく、引数のデータ型が正確に一致していない場合でも発生するため注意が必要です。

関数が存在しない場合

関数名のスペルミスや、大文字小文字の違いで発生するケース。

-- 間違った例(my_function ではなく myFunction)
SELECT my_function(123);

PostgreSQLでは関数名はデフォルトで小文字に変換されるため、引用符を使わないと正確に一致しません。

引数の型が一致していない場合

同名の関数が定義されていても、渡された引数の型が異なると、エラーが出ます。

-- 定義されている関数
CREATE FUNCTION my_function(integer) RETURNS text AS $$
BEGIN
  RETURN 'OK';
END;
$$ LANGUAGE plpgsql;

-- 呼び出し(NG: 引数がtext型)
SELECT my_function('123');

この場合、明示的にキャストすることで解決します。

-- キャストする方法
SELECT my_function('123'::integer);

スキーマの指定漏れ

関数が別スキーマに存在している場合、エラーになります。

-- 関数は custom_schema に存在
SELECT my_function(123); -- エラー

-- スキーマを明示すれば成功
SELECT custom_schema.my_function(123);

または、スキーマをsearch_pathに追加しておく方法もあります。

SET search_path TO custom_schema, public;
SELECT my_function(123);

関数がまだ定義されていない場合

単純に関数が作成されていない場合、当然ながら「does not exist」が返されます。

-- まだ関数を作っていない
SELECT new_func(10); -- エラー

必要な関数を定義すれば解決します。

CREATE FUNCTION new_func(integer) RETURNS integer AS $$
BEGIN
  RETURN $1 * 2;
END;
$$ LANGUAGE plpgsql;

関数のオーバーロードに注意

PostgreSQLは同名関数でも引数の型が異なるバージョン(オーバーロード)を定義できます。そのため、意図しない型で呼び出すとマッチしません。

-- 2つの関数定義
CREATE FUNCTION test_func(integer) RETURNS text ...
CREATE FUNCTION test_func(text) RETURNS text ...

-- 呼び出し時に曖昧な引数
SELECT test_func(NULL); -- どちらかわからずエラー

この場合、明示的にキャストを加える必要があります。

SELECT test_func(NULL::integer);

引数が多すぎる/少なすぎる

定義された関数と異なる数の引数を渡すと、同じエラーが出ます。

-- 1つの引数の関数
CREATE FUNCTION only_one(integer) RETURNS text ...

-- 呼び出し(引数が2つなのでエラー)
SELECT only_one(1, 2);

データ型の自動キャストに依存しすぎない

PostgreSQLはある程度の型変換は行ってくれますが、すべての型で自動変換されるわけではありません。

-- 自動キャストに頼ると予期せぬエラー
SELECT my_function(123.0); -- float から integer へ自動変換されない

型を明示的に指定する習慣を持つと、安全に処理できます。

関数の存在確認方法

以下のSQLで、定義済みの関数一覧を確認できます。

SELECT proname, proargtypes, prorettype
FROM pg_proc
WHERE proname = 'my_function';

より詳細な情報を取得する場合は、pg_catalogビューをJOINして使う方法もあります。

カスタム関数とextensionの関係

拡張機能(extension)で提供される関数を使おうとしてこのエラーになる場合、拡張が有効になっていない可能性があります。

-- 例: pg_trgm が使えない場合
SELECT similarity('abc', 'abd'); -- function does not exist

-- 解決策
CREATE EXTENSION pg_trgm;

PostgreSQLのバージョン差異による非対応

バージョンによってはサポートされていない関数を呼び出している場合もあります。特に新しい関数を使いたい時は、対象のPostgreSQLバージョンで対応しているか確認が必要です。

-- jsonb_path_exists は PostgreSQL 12 以降
SELECT jsonb_path_exists('{"a":1}', '$.a'); -- PostgreSQL 11ではエラー

まとめ

  • 関数名のタイプミス、大文字小文字
  • 引数の数や型の不一致
  • NULLの扱い(型指定が必要)
  • 関数のスキーマが異なる
  • 関数自体が存在しない
  • 拡張機能が有効になっていない
  • PostgreSQLのバージョンにより非対応
-- よくある正しい呼び出しのパターン
SELECT my_function(123::integer);

-- スキーマ指定
SELECT custom_schema.my_function(123);

-- 拡張の有効化
CREATE EXTENSION IF NOT EXISTS pg_trgm;