diff --git a/src/postrr.sql.in b/src/postrr.sql.in
index 10aeb777815720620e55c6a71f75ece9504ddadc..9f34f22100cfd04151da1afb56ca23ec2c3538d8 100644 (file)
--- a/src/postrr.sql.in
+++ b/src/postrr.sql.in
WITH FUNCTION Tstamptz(rrtimeslice);
-- EXPLICIT
+CREATE OR REPLACE FUNCTION rrtimeslice_cmp(rrtimeslice, rrtimeslice)
+ RETURNS integer
+ AS 'postrr-@POSTRR_MAJOR_VERSION@.@POSTRR_MINOR_VERSION@', 'rrtimeslice_cmp'
+ LANGUAGE 'C' IMMUTABLE STRICT;
+
CREATE OR REPLACE FUNCTION rrtimeslice_seq_eq(rrtimeslice, rrtimeslice)
RETURNS boolean
AS 'postrr-@POSTRR_MAJOR_VERSION@.@POSTRR_MINOR_VERSION@', 'rrtimeslice_seq_eq'
ts_str text;
v_str text;
update_qry text;
+ status integer;
newts rrtimeslice;
new cdata;
BEGIN
update_qry = 'CData_update(' || vcol || ', ' || v_str || ')';
+ -- XXX: handle race conditions
+
BEGIN
- EXECUTE 'UPDATE ' || tbl
- || ' SET ' || tscol || ' = ' || ts_str
- || ', ' || vcol || ' = ' || update_qry
+ EXECUTE 'SELECT rrtimeslice_cmp(' || tscol || ', ' || ts_str
+ || ') AS status FROM ' || tbl
|| ' WHERE ' || tscol || ' = ' || ts_str
- || ' RETURNING ' || tscol || ', ' || vcol
- INTO STRICT newts, new;
+ INTO STRICT status;
EXCEPTION
WHEN NO_DATA_FOUND THEN
|| ') RETURNING ' || tscol || ', ' || vcol
INTO newts, new;
-- use strict again; on exception retry?
+ RETURN new;
WHEN TOO_MANY_ROWS THEN
RAISE EXCEPTION '% is not unique in %.%', ts_str, tbl, tscol;
END;
+
+ IF status = 0 THEN
+ -- timestamps match
+ EXECUTE 'UPDATE ' || tbl
+ || ' SET ' || vcol || ' = ' || update_qry
+ || ' WHERE ' || tscol || ' = ' || ts_str
+ || ' RETURNING ' || tscol || ', ' || vcol
+ INTO STRICT newts, new;
+ ELSIF status < 0 THEN
+ -- given timestamp is newer than in the database
+ EXECUTE 'UPDATE ' || tbl
+ || ' SET ' || tscol || ' = ' || ts_str
+ || ', ' || vcol || ' = ' || v_str
+ || ' WHERE ' || tscol || ' = ' || ts_str
+ || ' RETURNING ' || tscol || ', ' || vcol
+ INTO STRICT newts, new;
+ ELSE
+ RAISE EXCEPTION '% is too old in %.%', ts_str, tbl, tscol;
+ END IF;
RETURN new;
END;
$$;
LANGUAGE plpgsql
AS $$
DECLARE
- rraname ALIAS FOR $1;
- ts ALIAS FOR $2;
- value ALIAS FOR $3;
+ -- $1: rraname
+ -- $2: timestamp
+ -- $3: value
adef RECORD;
new cdata;
BEGIN
FOR adef IN SELECT tbl, tscol, vcol FROM postrr.rrarchives
WHERE postrr.rrarchives.rraname = $1 LOOP
- EXECUTE 'SELECT PostRR_update('
- || quote_literal(adef.tbl) || ', '
- || quote_literal(adef.tscol) || ', '
- || quote_literal(adef.vcol) || ', '
- || quote_literal(ts) || ', '
- || quote_literal(value) || ')'
+ SELECT PostRR_update(adef.tbl, adef.tscol, adef.vcol, $2, $3)
INTO new;
RETURN NEXT new;
END LOOP;