Add workaround for UPDATE with subquery when using MySQL
When trying to run an UPDATE, this query is ran: ```sql UPDATE `todos` INNER JOIN `projects` ON `projects`.`id` = `todos`.`project_id` SET `todos`.`state` = 'done' WHERE `todos`.`user_id` = 4 AND (`todos`.`state` IN ('pending')) AND (EXISTS (SELECT 1 FROM `project_authorizations` WHERE `project_authorizations`.`user_id` = 4 AND (project_authorizations.project_id = projects.id)) OR projects.visibility_level IN (10, 20)) AND `projects`.`id` IN (SELECT `todos`.`project_id` FROM `todos` WHERE `todos`.`user_id` = 4 AND (`todos`.`state` IN ('pending'))) AND (`todos`.`state` != 'done') ``` But MySQL does not like the subquery used to filter on `projects.id IN (SELECT ...` Because the subquery queries from the same table: > Error: You can’t specify target table ‘todos’ for update in FROM clause So as workaround, wrap it in another subquery, where the original subquery is aliased using the `AS` statement. Mostly inspired by https://stackoverflow.com/a/43610081/89376
This commit is contained in:
parent
a723cba574
commit
a488fc0add
|
@ -95,9 +95,18 @@ class TodosFinder
|
||||||
@project
|
@project
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project_ids(items)
|
||||||
|
ids = items.except(:order).select(:project_id)
|
||||||
|
if Gitlab::Database.mysql?
|
||||||
|
# To make UPDATE work on MySQL, wrap it in a SELECT with an alias
|
||||||
|
ids = Todo.except(:order).select('*').from("(#{ids.to_sql}) AS t")
|
||||||
|
end
|
||||||
|
|
||||||
|
ids
|
||||||
|
end
|
||||||
|
|
||||||
def projects(items)
|
def projects(items)
|
||||||
item_project_ids = items.reorder(nil).select(:project_id)
|
ProjectsFinder.new(current_user: current_user, project_ids_relation: project_ids(items)).execute
|
||||||
ProjectsFinder.new(current_user: current_user, project_ids_relation: item_project_ids).execute
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def type?
|
def type?
|
||||||
|
|
Loading…
Reference in New Issue