I've got a function that got migrated from SQL Server. The intention is that the executions won't take longer than the specified timeout, yet they can take ~ 4 times longer. The calculations inside the function are lightweight and shouldn't take much time. What's the issue with the timeout mechanism?
The database is GCP Cloud SQL Postgres in case it matters.
CREATE OR REPLACE FUNCTION spleasetasks(timeout_seconds INT,
poll_interval_millis INT
...)
RETURNS TABLE (...)
AS
$$
DECLARE
timeout TIMESTAMPTZ := (CLOCK_TIMESTAMP() AT TIME ZONE 'UTC' + (timeout_seconds || ' seconds')::INTERVAL);
BEGIN
CREATE TEMP TABLE result ( ... ) ON COMMIT DROP;
LOOP
IF timeout_seconds != 0 AND (CLOCK_TIMESTAMP() AT TIME ZONE 'UTC' > timeout) THEN
EXIT;
END IF;
-- ...
IF
timeout_seconds = 0 OR
(CLOCK_TIMESTAMP() AT TIME ZONE 'UTC' + (poll_interval_millis || ' milliseconds')::INTERVAL) >=
timeout THEN
EXIT;
END IF;
-- ...
EXECUTE PG_SLEEP(CAST(poll_interval_millis AS FLOAT) / 1000);
END LOOP;
RETURN QUERY SELECT * FROM result r;
END;
$$ LANGUAGE plpgsql;
EXECUTE PG_SLEEP(CAST(poll_interval_millis AS FLOAT) / 1000);
is nonsense in PL/pgSQL, you should to use PERFORM
PERFORM PG_SLEEP(CAST(poll_interval_millis AS FLOAT) / 1000);
EXECUTE
should be used for dynamic SQL.