Fixing the Behavior
Learn how to fix errors generated by writing the erroneous code for triggers.
We'll cover the following...
While it’s easy to maintain cache in an event-driven fashion thanks to PostgreSQL and its trigger support. Turning an insert into an update with contention on a single row is never a good idea. It’s even a classic anti-pattern.
Script for triggers
Here’s a modern way to fix the problem with the previous trigger implementation, this time applied to a per-message counter of Retweet and favorite actions:
Press + to interact
begin;create table twcache.counters(messageid bigint not null references tweet.message(messageid),rts bigint,favs bigint,unique(messageid));create or replace function twcache.tg_update_counters ()returns triggerlanguage plpgsqlas $$declarebegininsert into twcache.counters(messageid, rts, favs)select NEW.messageid,case when NEW.action = 'rt' then 1 else 0 end,case when NEW.action = 'fav' then 1 else 0 endon conflict (messageid)do updateset rts = case when NEW.action = 'rt'then counters.rts + 1when NEW.action = 'de-rt'then counters.rts - 1else counters.rtsend,favs = case when NEW.action = 'fav'then counters.favs + 1when NEW.action = 'de-fav'then counters.favs - 1else counters.favsendwhere counters.messageid = NEW.messageid;RETURN NULL;end;$$;CREATE TRIGGER update_countersAFTER INSERTON tweet.activityFOR EACH ROWEXECUTE PROCEDURE twcache.tg_update_counters();insert into tweet.activity(messageid, action)values (7, 'rt'),(7, 'fav'),(7, 'de-fav'),(8, 'rt'),(8, 'rt'),(8, 'rt'),(8, 'de-rt'),(8, 'rt');select messageid, rts, favsfrom twcache.counters;rollback;
And ...