Drop staging function before create instead of replace
Some checks are pending
CI / lint-and-test (push) Waiting to run

Cloud SQL's postgres (cloudsqlsuperuser) cannot CREATE OR REPLACE a
function owned by another role. Drop both overloads first so a plain
CREATE works regardless of prior ownership state.

Also removes the dynamic ACL normalization block — a freshly created
function has no stale ACLs to scan and revoke.
This commit is contained in:
fwazb 2026-07-23 23:16:36 -07:00
parent 15219d7116
commit 7e1d57ef6f

View file

@ -729,11 +729,12 @@ grant insert (
payload
) on kb_stage.kb_proposals to leoclean_kb_stage_owner;
-- Remove the prior caller-supplied-identity overload before installing the
-- session-bound form. A runtime caller can only stage as canonical agent Leo.
-- Drop both overloads so CREATE (not REPLACE) works regardless of prior
-- ownership. Cloud SQL's postgres cannot replace a function owned by another role.
drop function if exists kb_stage.stage_leoclean_proposal(text, text, text, text, text, jsonb);
drop function if exists kb_stage.stage_leoclean_proposal(text, text, text, text, jsonb);
create or replace function kb_stage.stage_leoclean_proposal(
create function kb_stage.stage_leoclean_proposal(
p_proposal_type text,
p_channel text,
p_source_ref text,
@ -799,31 +800,9 @@ begin
end
$function$;
-- Normalize explicit ACL entries left by CREATE OR REPLACE or an earlier grant.
-- A newly-created function starts with owner EXECUTE, while CREATE OR REPLACE
-- preserves an existing ACL on reruns. Revoke every scoped/default entry here
-- while postgres still owns the function, so Cloud SQL's cloudsqlsuperuser
-- privilege is sufficient for the revoke.
revoke all on function kb_stage.stage_leoclean_proposal(text, text, text, text, jsonb)
from public, leoclean_kb_runtime, leoclean_kb_stage_owner;
select format(
'revoke all on function kb_stage.stage_leoclean_proposal(text, text, text, text, jsonb) from %I',
grantee.rolname
)
from pg_catalog.pg_proc function_row
cross join lateral pg_catalog.aclexplode(
coalesce(
function_row.proacl,
pg_catalog.acldefault('f', function_row.proowner)
)
) as acl
join pg_catalog.pg_roles grantee on grantee.oid = acl.grantee
where function_row.oid = 'kb_stage.stage_leoclean_proposal(text,text,text,text,jsonb)'::pg_catalog.regprocedure
\gexec
-- Fresh function has no stale ACLs. Grant runtime, transfer ownership, done.
grant execute on function kb_stage.stage_leoclean_proposal(text, text, text, text, jsonb)
to leoclean_kb_runtime;
alter function kb_stage.stage_leoclean_proposal(text, text, text, text, jsonb)
owner to leoclean_kb_stage_owner;
revoke create on schema kb_stage from leoclean_kb_stage_owner;