pub fn diff_grants(
target: &[Grant],
source: &[Grant],
managed_roles: &BTreeSet<Identifier>,
) -> (Vec<Grant>, Vec<Grant>, Vec<Grant>)Expand description
Compute additions and removals between target (catalog) and source (desired).
managed_roles: the set of role names mentioned anywhere in the source
catalog. Grants whose grantee is not in this set are considered unmanaged
and excluded from the revoke side (lenient policy). PUBLIC is always
considered managed.
Returns (to_add, to_revoke, unmanaged_observed).
§Ordering note — REVOKE before GRANT (issue #33)
When a grant’s with_grant_option flag changes (same grantee + privilege +
columns, different WGO value) the diff yields BOTH a to_revoke (old WGO
value) and a to_add (new WGO value). The executed plan must run
REVOKE … FROM … before GRANT … TO … [WITH GRANT OPTION]; otherwise the
GRANT is immediately undone by the following REVOKE, leaving the live
database without the privilege entirely.
This ordering is not a caller contract — ChangeSet is unordered. The
rule is enforced in the plan layer by plan::ordering’s
sort_changes_by_order revoke-before-grant tie-break, so callers may emit
to_add / to_revoke in any order.