From 80d69d7eb98b1d7b7b3a72a15e93edc9e1ac162b Mon Sep 17 00:00:00 2001 From: Raymond Jacobson Date: Mon, 3 Aug 2026 10:25:38 -0700 Subject: [PATCH] fix(db): widen notification ids to bigint --- api/dbv1/models.go | 2 +- .../handle_challenge_disbursements.sql | 4 +- ddl/functions/handle_user_challenges.sql | 2 +- .../0233_notification_id_bigint.sql | 43 +++++++++++++++++++ sql/01_schema.sql | 11 +++-- 5 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 ddl/migrations/0233_notification_id_bigint.sql diff --git a/api/dbv1/models.go b/api/dbv1/models.go index acceb4ec..122ddbfd 100644 --- a/api/dbv1/models.go +++ b/api/dbv1/models.go @@ -1394,7 +1394,7 @@ type MutedUser struct { } type Notification struct { - ID int32 `json:"id"` + ID int64 `json:"id"` Specifier string `json:"specifier"` GroupID string `json:"group_id"` Type string `json:"type"` diff --git a/ddl/functions/handle_challenge_disbursements.sql b/ddl/functions/handle_challenge_disbursements.sql index 3dcf9569..48eb32ce 100644 --- a/ddl/functions/handle_challenge_disbursements.sql +++ b/ddl/functions/handle_challenge_disbursements.sql @@ -1,7 +1,7 @@ create or replace function handle_challenge_disbursement() returns trigger as $$ declare reward_manager_tx reward_manager_txs%ROWTYPE; - existing_notification integer; + existing_notification bigint; reward_code_exists boolean; begin @@ -67,7 +67,7 @@ end $$; create or replace function handle_sol_reward_disbursement() returns trigger as $$ declare resolved_user_id integer; - existing_notification integer; + existing_notification bigint; reward_code_exists boolean; begin select users.user_id diff --git a/ddl/functions/handle_user_challenges.sql b/ddl/functions/handle_user_challenges.sql index fbf12040..e95d4fb2 100644 --- a/ddl/functions/handle_user_challenges.sql +++ b/ddl/functions/handle_user_challenges.sql @@ -1,7 +1,7 @@ create or replace function handle_on_user_challenge() returns trigger as $$ declare cooldown_days integer; - existing_notification integer; + existing_notification bigint; listen_streak_value integer; begin if (new.is_complete = true) then diff --git a/ddl/migrations/0233_notification_id_bigint.sql b/ddl/migrations/0233_notification_id_bigint.sql new file mode 100644 index 00000000..652b3e79 --- /dev/null +++ b/ddl/migrations/0233_notification_id_bigint.sql @@ -0,0 +1,43 @@ +-- notification_id_seq exhausted its signed 32-bit range in production. Widen +-- both the owning column and the sequence so notification inserts can resume. +-- +-- ALTER COLUMN integer -> bigint rewrites notification and requires an +-- ACCESS EXCLUSIVE lock. Fail quickly if the lock is not immediately +-- available so an unattended deploy cannot leave requests queued behind this +-- migration. Production should run this while notification readers and writers +-- are quiesced, then retry the migration. + +BEGIN; + +SET LOCAL lock_timeout = '5s'; +SET LOCAL statement_timeout = '0'; + +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM pg_attribute + WHERE attrelid = 'public.notification'::regclass + AND attname = 'id' + AND atttypid = 'integer'::regtype + AND NOT attisdropped + ) THEN + LOCK TABLE public.notification IN ACCESS EXCLUSIVE MODE; + + ALTER TABLE public.notification + ALTER COLUMN id TYPE bigint; + END IF; + + IF EXISTS ( + SELECT 1 + FROM pg_sequences + WHERE schemaname = 'public' + AND sequencename = 'notification_id_seq' + AND data_type = 'integer'::regtype + ) THEN + ALTER SEQUENCE public.notification_id_seq AS bigint; + END IF; +END +$$; + +COMMIT; diff --git a/sql/01_schema.sql b/sql/01_schema.sql index cdc8008f..90cf4cce 100644 --- a/sql/01_schema.sql +++ b/sql/01_schema.sql @@ -2141,7 +2141,7 @@ CREATE FUNCTION public.handle_challenge_disbursement() RETURNS trigger AS $$ declare reward_manager_tx reward_manager_txs%ROWTYPE; - existing_notification integer; + existing_notification bigint; reward_code_exists boolean; begin @@ -3235,7 +3235,7 @@ CREATE FUNCTION public.handle_on_user_challenge() RETURNS trigger AS $$ declare cooldown_days integer; - existing_notification integer; + existing_notification bigint; listen_streak_value integer; begin if (new.is_complete = true) then @@ -4376,7 +4376,7 @@ CREATE FUNCTION public.handle_sol_reward_disbursement() RETURNS trigger AS $$ declare resolved_user_id integer; - existing_notification integer; + existing_notification bigint; reward_code_exists boolean; begin select users.user_id @@ -8653,7 +8653,7 @@ CREATE TABLE public.muted_users ( -- CREATE TABLE public.notification ( - id integer NOT NULL, + id bigint NOT NULL, specifier character varying NOT NULL, group_id character varying NOT NULL, type character varying NOT NULL, @@ -8682,7 +8682,7 @@ CREATE TABLE public.notification_campaign_push_open ( -- CREATE SEQUENCE public.notification_id_seq - AS integer + AS bigint START WITH 1 INCREMENT BY 1 NO MINVALUE @@ -14991,4 +14991,3 @@ ALTER TABLE ONLY public.users -- PostgreSQL database dump complete -- -