From f82e6b37a3ec7e20ca91ba0f29ccbe34dce23c28 Mon Sep 17 00:00:00 2001 From: Leon Stringer Date: Mon, 18 Aug 2025 11:35:21 +0100 Subject: [PATCH] MDL-84898 core: Improve prohibit performance Change the query used to check if a user has a capability but is assigned a role that prohibits that capability. This is based on the query added by Petr Skoda for MDL-57027. --- public/lib/accesslib.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/public/lib/accesslib.php b/public/lib/accesslib.php index 3c6df9dfbc5..646fe1dfa04 100644 --- a/public/lib/accesslib.php +++ b/public/lib/accesslib.php @@ -3796,14 +3796,13 @@ function get_with_capability_join(context $context, $capability, $useridcolumn) AND roleid IN (" . implode(',', array_keys($prohibited[$cap])) . "))"; } else { - $unions[] = "SELECT userid - FROM {role_assignments} - WHERE contextid IN ($ctxids) AND roleid IN (" . implode(',', array_keys($needed[$cap])) . ") - AND userid NOT IN ( - SELECT userid - FROM {role_assignments} - WHERE contextid IN ($ctxids) - AND roleid IN (" . implode(',', array_keys($prohibited[$cap])) . "))"; + $unions[] = "SELECT ra.userid + FROM {role_assignments} ra + LEFT JOIN {role_assignments} rap ON (rap.userid = ra.userid + AND rap.contextid IN ($ctxids) + AND rap.roleid IN (" . implode(',', array_keys($prohibited[$cap])) . ")) + WHERE ra.contextid IN ($ctxids) AND ra.roleid IN (" . implode(',', array_keys($needed[$cap])) . ") + AND rap.id IS NULL"; } } }