Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions db/migrations/20260529120000_connections_entity_ids.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- migrate:up

-- Schema drift repair: `connections.entity_ids` exists in the squashed baseline
-- (00000000000000_baseline.sql) with a GIN index, but installs provisioned from
-- an *older* pre-squash baseline applied the column to events/watchers/feeds and
-- never to connections. Those databases (e.g. the prod `owletto` DB) are missing
-- both the column and its index, so any query that projects connections.entity_ids
-- — including the admin `query_sql` tool whose SAFE_COLUMN_DEFS allowlist lists it
-- — fails with `column "entity_ids" does not exist`.
--
-- This delta is idempotent: a no-op on fresh installs (baseline already created
-- the column + index) and a repair on drifted databases. Matches the baseline
-- definition exactly so the allowlist stays consistent with the real schema.
ALTER TABLE public.connections ADD COLUMN IF NOT EXISTS entity_ids bigint[];

CREATE INDEX IF NOT EXISTS idx_connections_entity_ids ON public.connections USING gin (entity_ids);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚖️ Poor tradeoff

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check PostgreSQL version to confirm CONCURRENTLY IF NOT EXISTS support (requires 9.5+)

rg -n "FROM postgres:" --type dockerfile

Repository: lobu-ai/lobu

Length of output: 91


🌐 Web query:

PostgreSQL CREATE INDEX CONCURRENTLY IF NOT EXISTS minimum version

💡 Result:

Minimum PostgreSQL version: PostgreSQL 9.5. Reasoning (from sources): - PostgreSQL 9.5 release notes state: “Add IF NOT EXISTS clause to … CREATE INDEX …” [1]. - The CREATE INDEX grammar documents both optional CONCURRENTLY and IF NOT EXISTS clauses: “CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] …” [2][3]. - A CREATE INDEX IF NOT EXISTS community reference also notes “Postgres 9.5 or newer” and that it “Also works for CREATE INDEX CONCURRENTLY IF NOT EXISTS.” [4]. So the combined form “CREATE INDEX CONCURRENTLY IF NOT EXISTS …” is available starting in PostgreSQL 9.5. [1][2][4]

Citations:


Add CONCURRENTLY to avoid production locks during the GIN index build.

The migration’s CREATE INDEX IF NOT EXISTS ... USING gin (entity_ids); will take a table lock while the index is built on a non-empty public.connections table. CREATE INDEX CONCURRENTLY IF NOT EXISTS is supported by PostgreSQL 9.5+.

🔧 Proposed fix
-CREATE INDEX IF NOT EXISTS idx_connections_entity_ids ON public.connections USING gin (entity_ids);
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_connections_entity_ids ON public.connections USING gin (entity_ids);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CREATE INDEX IF NOT EXISTS idx_connections_entity_ids ON public.connections USING gin (entity_ids);
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_connections_entity_ids ON public.connections USING gin (entity_ids);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@db/migrations/20260529120000_connections_entity_ids.sql` at line 16, Replace
the blocking index creation with a concurrent one: change the statement that
creates idx_connections_entity_ids on public.connections to use CREATE INDEX
CONCURRENTLY IF NOT EXISTS ... USING gin (entity_ids) so the GIN build won’t
lock the table; also ensure this migration is executed outside a transactional
migration runner (CONCURRENTLY cannot run inside a transaction block) or mark
the migration as non-transactional in your migration tool.


-- migrate:down

DROP INDEX IF EXISTS public.idx_connections_entity_ids;

ALTER TABLE public.connections DROP COLUMN IF EXISTS entity_ids;
Loading