mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
refactor(schema): fan desired-state schema out to one file per table (#8131)
This commit is contained in:
78
schema/functions/assert_community_write_allowed.sql
Normal file
78
schema/functions/assert_community_write_allowed.sql
Normal file
@@ -0,0 +1,78 @@
|
||||
CREATE FUNCTION assert_community_write_allowed(target UUID) RETURNS VOID
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
lifecycle TEXT;
|
||||
generation BIGINT;
|
||||
executor_community TEXT;
|
||||
executor_generation TEXT;
|
||||
serving_community TEXT;
|
||||
serving_lease_id TEXT;
|
||||
serving_owner TEXT;
|
||||
serving_generation TEXT;
|
||||
serving_fence_generation TEXT;
|
||||
serving_lease_valid BOOLEAN := false;
|
||||
BEGIN
|
||||
-- The fence proof requires a fresh statement snapshot after lock grant;
|
||||
-- pinned RR/Serializable snapshots can retain pre-fence authorization.
|
||||
IF current_setting('transaction_isolation') <> 'read committed' THEN
|
||||
RAISE EXCEPTION 'community writes require READ COMMITTED isolation'
|
||||
USING ERRCODE = 'invalid_transaction_state';
|
||||
END IF;
|
||||
|
||||
-- Nullable operator-attribution rows without a tenant are unrelated.
|
||||
IF target IS NULL THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
PERFORM pg_advisory_xact_lock_shared(community_deletion_lock_key(target));
|
||||
SELECT deletion_state, deletion_fence_generation
|
||||
INTO lifecycle, generation
|
||||
FROM communities
|
||||
WHERE id = target;
|
||||
IF NOT FOUND THEN
|
||||
RAISE EXCEPTION 'community write rejected: community % is missing', target
|
||||
USING ERRCODE = 'object_not_in_prerequisite_state';
|
||||
END IF;
|
||||
|
||||
-- Authorization is evaluated independently for every community checked.
|
||||
executor_community := current_setting('buzz.deletion_executor_community', true);
|
||||
executor_generation := current_setting('buzz.deletion_fence_generation', true);
|
||||
IF executor_community = target::TEXT
|
||||
AND executor_generation ~ '^[0-9]+$'
|
||||
AND executor_generation::BIGINT = generation THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- A serving mutation admitted before quiescing may finish only while its
|
||||
-- exact durable lease remains current and bound to this fence generation.
|
||||
serving_community := current_setting('buzz.serving_write_community', true);
|
||||
serving_lease_id := current_setting('buzz.serving_write_lease_id', true);
|
||||
serving_owner := current_setting('buzz.serving_write_owner', true);
|
||||
serving_generation := current_setting('buzz.serving_write_generation', true);
|
||||
serving_fence_generation := current_setting('buzz.serving_write_fence_generation', true);
|
||||
IF lifecycle IN ('active', 'quiescing')
|
||||
AND serving_community = target::TEXT
|
||||
AND serving_lease_id ~ '^[0-9a-fA-F-]{36}$'
|
||||
AND serving_generation ~ '^[0-9]+$'
|
||||
AND serving_fence_generation ~ '^[0-9]+$'
|
||||
AND serving_fence_generation::BIGINT = generation THEN
|
||||
SELECT EXISTS(
|
||||
SELECT 1 FROM community_serving_write_leases lease
|
||||
WHERE lease.id = serving_lease_id::UUID
|
||||
AND lease.community_id = target
|
||||
AND lease.owner = serving_owner
|
||||
AND lease.generation = serving_generation::BIGINT
|
||||
AND lease.fence_generation = serving_fence_generation::BIGINT
|
||||
AND lease.lease_until >= now()
|
||||
) INTO serving_lease_valid;
|
||||
IF serving_lease_valid THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
IF lifecycle <> 'active' THEN
|
||||
RAISE EXCEPTION 'community write fenced: community % generation %', target, generation
|
||||
USING ERRCODE = 'object_not_in_prerequisite_state';
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
Reference in New Issue
Block a user