- # Get a set of permission by searching the graph and following
- # ownership and permission links.
- #
- # edges() - a subselect with the union of ownership and permission links
- #
- # traverse_graph() - recursive query, from the starting node,
- # self-join with edges to find outgoing permissions.
- # Re-runs the query on new rows until there are no more results.
- # This accomplishes a breadth-first search of the permission graph.
- #
- ActiveRecord::Base.connection.execute %{
-create or replace function search_permission_graph (starting_uuid varchar(27),
- starting_perm integer)
- returns table (target_uuid varchar(27), val integer, traverse_owned bool)
-STABLE
-language SQL
-as $$
-WITH RECURSIVE
- traverse_graph(target_uuid, val, traverse_owned) as (
- values (starting_uuid, starting_perm,
- should_traverse_owned(starting_uuid, starting_perm))
- union
- (select edges.head_uuid,
- least(edges.val, traverse_graph.val,
- case traverse_graph.traverse_owned
- when true then null
- else 0
- end),
- should_traverse_owned(edges.head_uuid, edges.val)
- from permission_graph_edges as edges, traverse_graph
- where traverse_graph.target_uuid = edges.tail_uuid))
- select target_uuid, max(val), bool_or(traverse_owned) from traverse_graph
- group by (target_uuid);
-$$;
+ # This is used to ensure that the permission edge passed into
+ # compute_permission_subgraph takes replaces the existing edge in
+ # the "edges" view that is about to be removed.
+ edge_perm = %{
+case (edges.edge_id = perm_edge_id)
+ when true then starting_perm
+ else edges.val
+ end