Files

30 lines
1.7 KiB
SQL
Raw Permalink Normal View History

2026-08-01 22:06:14 +02:00
-- Migration 028 (phase 6, group DMs): mark which DM channels are groups.
--
-- dm_participants has always held N rows per channel, so a group DM needed no
-- new table. What it did need is a way to tell a group from a two-person DM
-- that does NOT count participants, because the count changes underneath you:
--
-- * A group of three that two people leave has two participants, and the 1:1
-- lookup in GetOrCreateDMChannel -- "the dm channel both of these users are
-- in" -- would then match it. "Message Bob" would silently deliver into the
-- remnants of a group, in front of whoever else is still there.
-- * Leaving is destructive for a group (you come out of dm_participants) and
-- non-destructive for a 1:1 (you only hide it). Deriving which one to run
-- from the live count means the third-from-last leaver runs a different
-- operation than the second-from-last, for no reason the user can see.
--
-- So group-ness is a property of the channel, decided once at creation and
-- never recomputed. is_group = 0 for every pre-existing row, which is correct:
-- every DM that existed before this migration was created by the 1:1 path.
--
-- The column lives on channels rather than a dm_groups side table because it
-- is one bit about a channel, and every read that needs it is already loading
-- the channel row.
ALTER TABLE channels ADD COLUMN is_group INTEGER NOT NULL DEFAULT 0;
-- The 1:1 DM lookup filters on it (c.type = 'dm' AND c.is_group = 0) on every
-- "open a DM with this person", which is a hot path on the DM sidebar. Partial
-- on type so the index covers only the DM rows -- guild channels are never
-- groups and never looked up this way.
CREATE INDEX IF NOT EXISTS idx_channels_dm_group ON channels(is_group) WHERE type = 'dm';