Add a "GROUP BY" clause on queries with RBAC entries
As reported in the Neutron patch [1], this change introduce a "GROUP BY" clause on the SQL queries with RBAC entries. With [1], all resouces with RBAC entries ('network', 'qospolicy', 'securitygroup', 'addressscope', 'subnetpool', 'addressgroup') will load the RBAC entries with "joined" strategy. Because of the low cardinality of the RBAC query when all the RBAC registers are in one single project, this patch groups the resource queries by the resource ID. That will reduce the results returned by the SQL engine to only the singular registers required. [1]https://review.opendev.org/c/openstack/neutron/+/884877 Related-Bug: #1918145 Change-Id: I800e0356714d59ba93ab6252c77be0a82f024055
This commit is contained in:
parent
64cfdacdc1
commit
829e97024c
@ -108,6 +108,7 @@ def query_with_hooks(context, model, field=None, lazy_fields=None):
|
||||
:param lazy_fields: list of fields for lazy loading
|
||||
:returns: The query with hooks applied to it.
|
||||
"""
|
||||
group_by = None
|
||||
if field:
|
||||
if hasattr(model, field):
|
||||
field = getattr(model, field)
|
||||
@ -129,6 +130,11 @@ def query_with_hooks(context, model, field=None, lazy_fields=None):
|
||||
[constants.ACCESS_SHARED, constants.ACCESS_READONLY]) &
|
||||
((rbac_model.target_project == context.tenant_id) |
|
||||
(rbac_model.target_project == '*'))))
|
||||
# This "group_by" clause will limit the number of registers
|
||||
# returned by the query, avoiding the problem of the low SQL
|
||||
# query cardinality when the RBAC registers are in the requested
|
||||
# project ID.
|
||||
group_by = model.id
|
||||
elif hasattr(model, 'shared'):
|
||||
query_filter = ((model.tenant_id == context.tenant_id) |
|
||||
(model.shared == sql.true()))
|
||||
@ -149,6 +155,9 @@ def query_with_hooks(context, model, field=None, lazy_fields=None):
|
||||
if query_filter is not None:
|
||||
query = query.filter(query_filter)
|
||||
|
||||
if group_by:
|
||||
query = query.group_by(group_by)
|
||||
|
||||
if lazy_fields:
|
||||
for field in lazy_fields:
|
||||
query = query.options(lazyload(field))
|
||||
|
Loading…
Reference in New Issue
Block a user