migrations/20261023010000_record_membership.up.sql
Rama main · réplica de lectura del repositorio original.
-- Derived candidates only: authorization must still inspect the file record.
CREATE TABLE IF NOT EXISTS shardline_record_membership (
record_key TEXT NOT NULL,
scope_key TEXT NOT NULL,
member_hash TEXT NOT NULL,
PRIMARY KEY (record_key, member_hash)
);
CREATE INDEX IF NOT EXISTS shardline_record_membership_lookup_idx
ON shardline_record_membership (member_hash, scope_key, record_key);
CREATE OR REPLACE FUNCTION shardline_refresh_record_membership()
RETURNS trigger LANGUAGE plpgsql SET search_path = pg_catalog AS $$
BEGIN
IF TG_OP = 'UPDATE'
AND NEW.record IS NOT DISTINCT FROM OLD.record
AND NEW.scope_key IS NOT DISTINCT FROM OLD.scope_key
AND NEW.record_key IS NOT DISTINCT FROM OLD.record_key THEN
RETURN NEW;
END IF;
IF TG_OP <> 'INSERT' THEN
EXECUTE format('DELETE FROM %I.shardline_record_membership WHERE record_key = $1',
TG_TABLE_SCHEMA)
USING OLD.record_key;
END IF;
IF TG_OP <> 'DELETE' THEN
EXECUTE format(
'INSERT INTO %I.shardline_record_membership (record_key, scope_key, member_hash)
SELECT DISTINCT $1, $2, member->>''hash''
FROM jsonb_array_elements(
CASE WHEN jsonb_typeof($3->''chunks'') = ''array''
THEN $3->''chunks'' ELSE ''[]''::jsonb END) AS member
WHERE jsonb_typeof(member->''hash'') = ''string''', TG_TABLE_SCHEMA)
USING NEW.record_key, NEW.scope_key, NEW.record;
RETURN NEW;
END IF;
RETURN OLD;
END;
$$;
CREATE OR REPLACE TRIGGER shardline_record_membership_refresh
AFTER INSERT OR UPDATE OR DELETE ON shardline_file_records
FOR EACH ROW EXECUTE FUNCTION shardline_refresh_record_membership();
INSERT INTO shardline_record_membership (record_key, scope_key, member_hash)
SELECT DISTINCT source.record_key, source.scope_key, member->>'hash'
FROM shardline_file_records AS source
CROSS JOIN LATERAL jsonb_array_elements(
CASE WHEN jsonb_typeof(source.record->'chunks') = 'array'
THEN source.record->'chunks' ELSE '[]'::jsonb END) AS member
WHERE jsonb_typeof(member->'hash') = 'string'
ON CONFLICT (record_key, member_hash) DO NOTHING;