Jump to…
snowinitial commitqoxwzsukwmkx1mo
Matt W1-- M5: global search over repositories, changes and issues.
Matt W2--
Matt W3-- Spec §5 in-scope list ends at "Global search over repos, changes, and issues
Matt W4-- (not code)", so this indexes titles, descriptions and bodies — never blobs.
Matt W5--
Matt W6-- Generated columns rather than triggers: the tsvector cannot drift from the
Matt W7-- row, and there is no ordering hazard between an update and its index.
Matt W8
Matt W9-- ─── repositories ────────────────────────────────────────────────────────────
Matt W10
Matt W11ALTER TABLE repos ADD COLUMN search tsvector
Matt W12 GENERATED ALWAYS AS (
Matt W13 setweight(to_tsvector('english', coalesce(name::text, '')), 'A') ||
Matt W14 setweight(to_tsvector('english', coalesce(description, '')), 'B')
Matt W15 ) STORED;
Matt W16
Matt W17CREATE INDEX repos_search_idx ON repos USING gin (search);
Matt W18
Matt W19-- ─── changes ─────────────────────────────────────────────────────────────────
Matt W20
Matt W21ALTER TABLE changes ADD COLUMN search tsvector
Matt W22 GENERATED ALWAYS AS (
Matt W23 setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
Matt W24 setweight(to_tsvector('english', coalesce(description, '')), 'B')
Matt W25 ) STORED;
Matt W26
Matt W27CREATE INDEX changes_search_idx ON changes USING gin (search);
Matt W28
Matt W29-- ─── issues ──────────────────────────────────────────────────────────────────
Matt W30
Matt W31ALTER TABLE issues ADD COLUMN search tsvector
Matt W32 GENERATED ALWAYS AS (
Matt W33 setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
Matt W34 setweight(to_tsvector('english', coalesce(body, '')), 'B')
Matt W35 ) STORED;
Matt W36
Matt W37CREATE INDEX issues_search_idx ON issues USING gin (search);
Matt W38
Matt W39-- Cross-references between issues and changes, extracted from bodies and
Matt W40-- comments when they are written. Stored rather than re-scanned so a change's
Matt W41-- page can list the issues that mention it without a full-text query per view.
Matt W42CREATE TABLE cross_references (
Matt W43 id uuid PRIMARY KEY,
Matt W44 repo_id uuid NOT NULL REFERENCES repos ON DELETE CASCADE,
Matt W45 -- What contains the reference.
Matt W46 source_type text NOT NULL CHECK (source_type IN ('change', 'issue', 'comment')),
Matt W47 source_id uuid NOT NULL,
Matt W48 -- What it points at.
Matt W49 target_type text NOT NULL CHECK (target_type IN ('change', 'issue')),
Matt W50 target_id uuid NOT NULL,
Matt W51 created_at timestamptz NOT NULL DEFAULT now(),
Matt W52 UNIQUE (source_type, source_id, target_type, target_id)
Matt W53);
Matt W54CREATE INDEX cross_references_target_idx ON cross_references (target_type, target_id);
Matt W55
Matt W56-- Labels need a default set per repository or the issue form has nothing to
Matt W57-- offer. Seeded for repositories that already exist; new ones are seeded in
Matt W58-- application code at creation.
Matt W59INSERT INTO labels (id, repo_id, name, color)
Matt W60SELECT gen_random_uuid(), r.id, l.name, l.color
Matt W61 FROM repos r
Matt W62 CROSS JOIN (VALUES
Matt W63 ('bug', '#d06b6b'),
Matt W64 ('enhancement', '#6ba9b8'),
Matt W65 ('question', '#d9a441'),
Matt W66 ('documentation', '#8b7fd4')
Matt W67 ) AS l(name, color)
Matt W68ON CONFLICT (repo_id, name) DO NOTHING;

68 lines · SQL