CREATE RULE Pages_Upsert AS ON INSERT TO Pages
WHERE EXISTS (SELECT 1 from Pages P where NEW.Url = P.Url)
DO INSTEAD
UPDATE Pages SET LastCrawled = NOW(), Html = NEW.Html WHERE Url = NEW.Url; CREATE RULE Pages_Upsert AS ON INSERT TO Pages
WHERE EXISTS (SELECT 1 from Pages P where NEW.Url = P.Url)
DO INSTEAD
UPDATE Pages SET LastCrawled = NOW(), Html = NEW.Html WHERE Url = NEW.Url;This rule allows the possibility of raising an exception on INSERT if two Pages with the same Url are "upserted" in parallel.
You would still require a table level lock to ensure you don't get an exception within the statement as a whole.
Also: Rules are easy to get wrong. Try not to reach for them unless absolutely necessary.
2. IIRC the rule method does not work correctly for multiple-rows inserts including duplicates
Does the SQL standard actually guarantee that a MERGE is atomic? After all the MERGE statement involves a subselect which seems to be about as concurrency safe as a SQLite replace insert which a join.
Two reasons:
a.) same concurrency problems.
b.) defined globally for the table. Completely useless for the kind of things I need an upsert for.