function for setting/getting same timestamp during whole transaction

From: Miroslav Šimulčík <simulcik(dot)miro(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: function for setting/getting same timestamp during whole transaction
Date: 2013-02-06 10:19:54
Message-ID: CAHRNM68PR35UA21O8e--aDgBVb1_bEWQmfJ3NtZNA5zv9jSzfA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers

Hi all,

I have deferred constraint update trigger in which I need to set same
timestamp to all modified rows. The time needs to be the time of first
invocation of this trigger fuction in transaciton. My intention is to set
commit time to rows modified in transaction.

So I need function that will store and return given timestamp on first call
in transaction and on subsequent calls will return stored timestamp. This
function have to be as fast as possible to minimize the inpact on
performance of trigger.

I have created a plpgsql function that uses temporal table for this task.
On first invocation in transaction row with timestamp is inserted and on
commit deleted. What I don't like is overhead with checks on table
existence on each invocation. Here is code:

CREATE OR REPLACE FUNCTION get_my_timestamp (
IN in_initial_timestamp TIMESTAMPTZ
) RETURNS TIMESTAMPTZ AS
$$
DECLARE
v_ret TIMESTAMPTZ;
BEGIN
--check temp table existence
PERFORM
1
FROM
pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n
ON n.oid = c.relnamespace
WHERE
c.relkind IN ('r','') AND
c.relname = 'timestamp_storage' AND
pg_catalog.pg_table_is_visible(c.oid) AND
n.nspname LIKE 'pg_temp%';
IF NOT FOUND THEN
CREATE TEMP TABLE timestamp_storage (
my_timestamp TIMESTAMPTZ
) ON COMMIT DELETE ROWS;
END IF;
--select timestamp
SELECT
my_timestamp
INTO
v_ret
FROM
timestamp_storage;
IF NOT FOUND THEN
INSERT INTO timestamp_storage(my_timestamp)
VALUES (in_initial_timestamp)
RETURNING my_timestamp
INTO v_ret;
END IF;

RETURN v_ret;
END;
$$ LANGUAGE plpgsql;

Example:
begin;
select get_my_timestamp(clock_timestamp());
get_my_timestamp
----------------------------
2013-02-06 11:07:33.698+01
select get_my_timestamp(clock_timestamp());
get_my_timestamp
----------------------------
2013-02-06 11:07:33.698+01
commit;
select get_my_timestamp(clock_timestamp());
get_my_timestamp
----------------------------
2013-02-06 11:09:02.406+01

Is there any more effective way of accomplishing this? Maybe in different
language.

Regards,
Miroslav Simulcik

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Misa Simic 2013-02-06 10:32:56 Re: function for setting/getting same timestamp during whole transaction
Previous Message Pavel Stehule 2013-02-06 10:12:16 Re: "explain analyze" a procedure verbosely - to find which statement in it takes longer

Browse pgsql-hackers by date

  From Date Subject
Next Message Misa Simic 2013-02-06 10:32:56 Re: function for setting/getting same timestamp during whole transaction
Previous Message Dimitri Fontaine 2013-02-06 09:33:16 Re: sql_drop Event Trigger