Code

PostRR_update(): Use rrtimeslice_cmp() to decide how to do the update.
authorSebastian Harl <sh@tokkee.org>
Wed, 7 Nov 2012 20:28:45 +0000 (21:28 +0100)
committerSebastian Harl <sh@tokkee.org>
Wed, 7 Nov 2012 20:28:45 +0000 (21:28 +0100)
That is, added support for overwriting old values and reporting errors if the
given timestamp is older than the appropriate timestamp in the database (which
is the entry having the same sequence number).

src/postrr.sql.in

index 87ef9d36a3cabbe40450ef19c686b9e3bec5d126..9f34f22100cfd04151da1afb56ca23ec2c3538d8 100644 (file)
@@ -320,6 +320,7 @@ DECLARE
        ts_str text;
        v_str text;
        update_qry text;
+       status integer;
        newts rrtimeslice;
        new cdata;
 BEGIN
@@ -330,13 +331,13 @@ 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
@@ -346,9 +347,29 @@ BEGIN
                                        || ') 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;
 $$;