From 164153e81921c39fefaf27c6cd2c0d265e9b206a Mon Sep 17 00:00:00 2001 From: Go MAEDA Date: Thu, 1 Feb 2024 12:33:50 +0000 Subject: [PATCH] Optimize queries visibility check (#39852). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Pavel Rosický (@ahorek). git-svn-id: https://svn.redmine.org/redmine/trunk@22669 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/query.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/app/models/query.rb b/app/models/query.rb index 558cee23e..65aba26bd 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -379,16 +379,17 @@ class Query < ApplicationRecord scope.where("#{table_name}.visibility <> ? OR #{table_name}.user_id = ?", VISIBILITY_PRIVATE, user.id) elsif user.memberships.any? scope.where( - "#{table_name}.visibility = ?" + - " OR (#{table_name}.visibility = ? AND #{table_name}.id IN (" + - "SELECT DISTINCT q.id FROM #{table_name} q" + - " INNER JOIN #{table_name_prefix}queries_roles#{table_name_suffix} qr on qr.query_id = q.id" + - " INNER JOIN #{MemberRole.table_name} mr ON mr.role_id = qr.role_id" + - " INNER JOIN #{Member.table_name} m ON m.id = mr.member_id AND m.user_id = ?" + - " INNER JOIN #{Project.table_name} p ON p.id = m.project_id AND p.status <> ?" + - " WHERE q.project_id IS NULL OR q.project_id = m.project_id))" + - " OR #{table_name}.user_id = ?", - VISIBILITY_PUBLIC, VISIBILITY_ROLES, user.id, Project::STATUS_ARCHIVED, user.id) + "#{table_name}.visibility = ?" \ + " OR (#{table_name}.visibility = ? AND EXISTS (SELECT 1" \ + " FROM #{table_name_prefix}queries_roles#{table_name_suffix} qr" \ + " INNER JOIN #{MemberRole.table_name} mr ON mr.role_id = qr.role_id" \ + " INNER JOIN #{Member.table_name} m ON m.id = mr.member_id AND m.user_id = ?" \ + " INNER JOIN #{Project.table_name} p ON p.id = m.project_id AND p.status <> ?" \ + " WHERE qr.query_id = #{table_name}.id" \ + " AND (#{table_name}.project_id IS NULL OR #{table_name}.project_id = m.project_id)))" \ + " OR #{table_name}.user_id = ?", + VISIBILITY_PUBLIC, VISIBILITY_ROLES, user.id, Project::STATUS_ARCHIVED, user.id + ) elsif user.logged? scope.where("#{table_name}.visibility = ? OR #{table_name}.user_id = ?", VISIBILITY_PUBLIC, user.id) else