From 28054e8dff5328572e649f2d0562e746acc86451 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 11 Dec 2023 15:40:28 +0100 Subject: [PATCH] Change: Optimize permission subqueries in acl_where_owned_user The clauses checking if a permission for a given resource exists no longer contain the resource id. Instead the id is looked up outside the subquery in all permissions for the given type and user gathered by the subquery. This improves performance for resource types with many items like results by allowing PostgreSQL to execute the subquery only once and reuse it instead of having to run a subquery for every resource in the database. --- src/manage_acl.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/manage_acl.c b/src/manage_acl.c index 8b80856b4..ed8173f68 100644 --- a/src/manage_acl.c +++ b/src/manage_acl.c @@ -1117,15 +1117,14 @@ acl_where_owned_user (const char *user_id, const char *user_sql, { gchar *clause; clause - = g_strdup_printf ("OR EXISTS" - " (SELECT id FROM %spermissions_subject" - " WHERE resource = %ss%s.id" - " AND resource_type = '%s'" + = g_strdup_printf ("OR %ss%s.id IN" + " (SELECT resource FROM %spermissions_subject" + " WHERE resource_type = '%s'" " AND resource_location = %i" " AND (%s))", - with_prefix ? with_prefix : "", type, get->trash && strcmp (type, "task") ? "_trash" : "", + with_prefix ? with_prefix : "", type, get->trash ? LOCATION_TRASH : LOCATION_TABLE, permission_or->str); @@ -1133,26 +1132,24 @@ acl_where_owned_user (const char *user_id, const char *user_sql, if (strcmp (type, "report") == 0) permission_clause = g_strdup_printf ("%s" - " OR EXISTS" - " (SELECT id FROM %spermissions_subject" - " WHERE resource = reports%s.task" - " AND resource_type = 'task'" + " OR reports%s.task IN" + " (SELECT resource FROM %spermissions_subject" + " WHERE resource_type = 'task'" " AND (%s))", clause, - with_prefix ? with_prefix : "", get->trash ? "_trash" : "", + with_prefix ? with_prefix : "", permission_or->str); else if (strcmp (type, "result") == 0) permission_clause = g_strdup_printf ("%s" - " OR EXISTS" + " OR results%s.task IN" " (SELECT id FROM %spermissions_subject" - " WHERE resource = results%s.task" - " AND resource_type = 'task'" + " WHERE resource_type = 'task'" " AND (%s))", clause, - with_prefix ? with_prefix : "", get->trash ? "_trash" : "", + with_prefix ? with_prefix : "", permission_or->str); if ((strcmp (type, "report") == 0)