web-dev-qa-db-ja.com

「SET LOCAL statement_timeout」がPostgreSQL関数で期待どおりに機能しないのはなぜですか?

私の理解では、PostgreSQL関数はトランザクションと同様に実行されます。ただし、関数内で「SET LOCAL statement_timeout」を実行しようとしても機能しませんでした。トランザクション内での動作は次のとおりです。

_BEGIN; 
  SET LOCAL statement_timeout = 100; 
  SELECT pg_sleep(10); 
COMMIT;
_

結果は(期待どおり)です。

_BEGIN
SET
ERROR:  canceling statement due to statement timeout
ROLLBACK
_

ただし、関数本体内に同じコマンドを配置した場合:

_CREATE OR REPLACE FUNCTION test() RETURNS void AS '
    SET LOCAL statement_timeout = 100;
    SELECT pg_sleep(10);
' LANGUAGE sql;

SELECT test();
_

タイムアウトは発生せず、関数test()の実行には10秒かかります。

2つのケースが異なる理由と、関数内でステートメントのタイムアウトを設定するためにそれを修正する方法についてアドバイスしてください。

9
M.S. Dousti

statement_timeoutが機能し、サーバーがクライアントから新しいコマンドを受信すると、時間がカウントされ始めます。

サーバーサイド関数内でのクエリの起動は、クライアントからのコマンドではなく、そのタイマーをリセットしたり、新しいタイマーをタイマーのスタックにプッシュしたりしません。

これが理由です SET LOCAL statement_timeout = 100;は効果がありません。

そして、関数がSET statement_timeout = 100;クライアントからの次のコマンドでのみ効果があります。

関数内の個々のクエリの実行時間を制御する方法はありません。

10
Daniel Vérité