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

Conflicts:
    neutron_lib/db/model_query.py

Related-Bug: #1918145
Change-Id: I800e0356714d59ba93ab6252c77be0a82f024055
(cherry picked from commit 829e97024c)
(cherry picked from commit 4a95204782)
This commit is contained in:
Rodolfo Alonso Hernandez 2023-05-28 17:43:30 +02:00
parent a2d0842e15
commit 619c0fe534

View File

@ -106,6 +106,7 @@ def query_with_hooks(context, model, field=None):
:param field: The column.
:returns: The query with hooks applied to it.
"""
group_by = None
if field:
if hasattr(model, field):
field = getattr(model, field)
@ -127,6 +128,11 @@ def query_with_hooks(context, model, field=None):
[constants.ACCESS_SHARED, constants.ACCESS_READONLY]) &
((rbac_model.target_tenant == context.tenant_id) |
(rbac_model.target_tenant == '*'))))
# 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()))
@ -146,6 +152,10 @@ def query_with_hooks(context, model, field=None):
# condition, raising an exception
if query_filter is not None:
query = query.filter(query_filter)
if group_by:
query = query.group_by(group_by)
return query