From 65e3d8ca7cd5753dc9869280dfb4e1878484a624 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Mon, 24 Nov 2025 09:43:33 +0000 Subject: [PATCH] core: fix relation vector indexes in code and migrations to start from 0 instead of 1 (#6460) --- src/Simplex/Chat/Store/Groups.hs | 2 +- .../M20251117_member_relations_vector.hs | 18 +++++------ .../M20251117_member_relations_vector.hs | 30 +++++++------------ .../SQLite/Migrations/chat_query_plans.txt | 2 +- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/src/Simplex/Chat/Store/Groups.hs b/src/Simplex/Chat/Store/Groups.hs index 3852665766..c04a31c0a9 100644 --- a/src/Simplex/Chat/Store/Groups.hs +++ b/src/Simplex/Chat/Store/Groups.hs @@ -462,7 +462,7 @@ getUpdateNextIndexInGroup_ db groupId = UPDATE groups SET member_index = member_index + 1 WHERE group_id = ? - RETURNING member_index + RETURNING member_index - 1 |] (Only groupId) diff --git a/src/Simplex/Chat/Store/Postgres/Migrations/M20251117_member_relations_vector.hs b/src/Simplex/Chat/Store/Postgres/Migrations/M20251117_member_relations_vector.hs index 197c90a66c..3f6deeb80f 100644 --- a/src/Simplex/Chat/Store/Postgres/Migrations/M20251117_member_relations_vector.hs +++ b/src/Simplex/Chat/Store/Postgres/Migrations/M20251117_member_relations_vector.hs @@ -18,31 +18,31 @@ ALTER TABLE group_members ADD COLUMN member_relations_vector BYTEA; CREATE INDEX tmp_idx_group_members_group_id_group_member_id ON group_members(group_id, group_member_id); -CREATE TEMPORARY TABLE tmp_members_numbered AS +CREATE TEMPORARY TABLE tmp_members_indexed AS SELECT group_member_id, ROW_NUMBER() OVER ( PARTITION BY group_id ORDER BY group_member_id ASC - ) AS rn + ) - 1 AS idx_in_group FROM group_members; -CREATE INDEX tmp_idx_members_numbered ON tmp_members_numbered(group_member_id); +CREATE INDEX tmp_idx_members_indexed ON tmp_members_indexed(group_member_id); UPDATE group_members AS gm -SET index_in_group = n.rn -FROM tmp_members_numbered n -WHERE n.group_member_id = gm.group_member_id; +SET index_in_group = tmi.idx_in_group +FROM tmp_members_indexed tmi +WHERE tmi.group_member_id = gm.group_member_id; DROP INDEX tmp_idx_group_members_group_id_group_member_id; -DROP INDEX tmp_idx_members_numbered; -DROP TABLE tmp_members_numbered; +DROP INDEX tmp_idx_members_indexed; +DROP TABLE tmp_members_indexed; CREATE UNIQUE INDEX idx_group_members_group_id_index_in_group ON group_members(group_id, index_in_group); UPDATE groups g SET member_index = COALESCE(( - SELECT MAX(index_in_group) + SELECT MAX(index_in_group) + 1 FROM group_members WHERE group_members.group_id = g.group_id ), 0); diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/M20251117_member_relations_vector.hs b/src/Simplex/Chat/Store/SQLite/Migrations/M20251117_member_relations_vector.hs index 09ebe63708..5c4251cc55 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/M20251117_member_relations_vector.hs +++ b/src/Simplex/Chat/Store/SQLite/Migrations/M20251117_member_relations_vector.hs @@ -40,16 +40,8 @@ import Database.SQLite.Simple.QQ (sql) -- - for all 0s in bitvector, get members by index_in_group in corresponding positions -- - second use of group_member_intros is targeted introductions of knocking member to "remaining" members -- - has to be reworked to not rely on group_member_intros --- - one approach could be to introduce accepted member to all (so, repeatedly introduce to moderators), --- this idea was tested in PR 6327 --- - another use of group_member_intros - createIntroductions, checkInverseIntro logic --- - TBC how to avoid making redundant introductions between concurrently joining members --- - second vector - for member introductions, or track in same vector --- - when introducing to moderators only, do nothing - new moderators are introduced only to current members, --- no pending in progress members, so race can't happen there --- - when introducing to all, filter out members who already were introduced to this member --- - can also solve previous issue of introducing remaining members in same way - don't introduce --- to members this member already was introduced to +-- - set MRIntroduced status in member relations vector on first introduction, +-- exclude previously introduced members on second introduction m20251117_member_relations_vector :: Query m20251117_member_relations_vector = [sql| @@ -61,33 +53,33 @@ ALTER TABLE group_members ADD COLUMN member_relations_vector BLOB; CREATE INDEX tmp_idx_group_members_group_id_group_member_id ON group_members(group_id, group_member_id); -CREATE TEMPORARY TABLE tmp_members_numbered AS +CREATE TEMPORARY TABLE tmp_members_indexed AS SELECT group_member_id, ROW_NUMBER() OVER ( PARTITION BY group_id ORDER BY group_member_id ASC - ) AS rn + ) - 1 AS idx_in_group FROM group_members; -CREATE INDEX tmp_idx_members_numbered ON tmp_members_numbered(group_member_id); +CREATE INDEX tmp_idx_members_indexed ON tmp_members_indexed(group_member_id); UPDATE group_members AS gm SET index_in_group = ( - SELECT rn - FROM tmp_members_numbered - WHERE tmp_members_numbered.group_member_id = gm.group_member_id + SELECT idx_in_group + FROM tmp_members_indexed + WHERE tmp_members_indexed.group_member_id = gm.group_member_id ); DROP INDEX tmp_idx_group_members_group_id_group_member_id; -DROP INDEX tmp_idx_members_numbered; -DROP TABLE tmp_members_numbered; +DROP INDEX tmp_idx_members_indexed; +DROP TABLE tmp_members_indexed; CREATE UNIQUE INDEX idx_group_members_group_id_index_in_group ON group_members(group_id, index_in_group); UPDATE groups AS g SET member_index = COALESCE(( - SELECT MAX(index_in_group) + SELECT MAX(index_in_group) + 1 FROM group_members WHERE group_members.group_id = g.group_id ), 0); diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt index e343eadaeb..9156b56fcb 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt +++ b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt @@ -3794,7 +3794,7 @@ Query: UPDATE groups SET member_index = member_index + 1 WHERE group_id = ? - RETURNING member_index + RETURNING member_index - 1 Plan: SEARCH groups USING INTEGER PRIMARY KEY (rowid=?)