Search code examples
postgresqlgoogle-cloud-platformstored-proceduresplpgsqlgoogle-cloud-sql

Function takes significantly longer than specified timeout


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;

Solution

  • 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.