···11+-- Add missing indexes on document foreign keys used by get_profile_posts
22+CREATE INDEX IF NOT EXISTS comments_on_documents_document_idx
33+ ON public.comments_on_documents (document);
44+55+CREATE INDEX IF NOT EXISTS document_mentions_in_bsky_document_idx
66+ ON public.document_mentions_in_bsky (document);
77+88+CREATE INDEX IF NOT EXISTS documents_in_publications_document_idx
99+ ON public.documents_in_publications (document);
1010+1111+-- Add a stored generated column to extract the DID from at:// URIs
1212+-- at://did:plc:xxx/collection/rkey -> did:plc:xxx
1313+ALTER TABLE public.documents
1414+ ADD COLUMN identity_did text GENERATED ALWAYS AS (split_part(uri, '/', 3)) STORED;
1515+1616+-- Composite index for efficient profile post lookups: filter by DID, order by sort_date
1717+CREATE INDEX documents_identity_did_sort_idx
1818+ ON public.documents (identity_did, sort_date DESC, uri DESC);
1919+2020+-- Rewrite get_profile_posts to use the new identity_did column
2121+CREATE OR REPLACE FUNCTION get_profile_posts(
2222+ p_did text,
2323+ p_cursor_sort_date timestamptz DEFAULT NULL,
2424+ p_cursor_uri text DEFAULT NULL,
2525+ p_limit int DEFAULT 20
2626+)
2727+RETURNS TABLE (
2828+ uri text,
2929+ data jsonb,
3030+ sort_date timestamptz,
3131+ comments_count bigint,
3232+ mentions_count bigint,
3333+ recommends_count bigint,
3434+ publication_uri text,
3535+ publication_record jsonb,
3636+ publication_name text
3737+)
3838+LANGUAGE sql STABLE
3939+AS $$
4040+ SELECT
4141+ d.uri,
4242+ d.data,
4343+ d.sort_date,
4444+ (SELECT count(*) FROM comments_on_documents c WHERE c.document = d.uri),
4545+ (SELECT count(*) FROM document_mentions_in_bsky m WHERE m.document = d.uri),
4646+ (SELECT count(*) FROM recommends_on_documents r WHERE r.document = d.uri),
4747+ pub.uri,
4848+ pub.record,
4949+ pub.name
5050+ FROM documents d
5151+ LEFT JOIN LATERAL (
5252+ SELECT p.uri, p.record, p.name
5353+ FROM documents_in_publications dip
5454+ JOIN publications p ON p.uri = dip.publication
5555+ WHERE dip.document = d.uri
5656+ LIMIT 1
5757+ ) pub ON true
5858+ WHERE d.identity_did = p_did
5959+ AND (
6060+ p_cursor_sort_date IS NULL
6161+ OR d.sort_date < p_cursor_sort_date
6262+ OR (d.sort_date = p_cursor_sort_date AND d.uri < p_cursor_uri)
6363+ )
6464+ ORDER BY d.sort_date DESC, d.uri DESC
6565+ LIMIT p_limit;
6666+$$;