From 04976a523ced7594254fa0806140405a6759e62c Mon Sep 17 00:00:00 2001 From: Andy Pfister Date: Sat, 22 Mar 2025 15:28:39 +0100 Subject: [PATCH] Order by `concurrency_key` before distinct Microsoft SQL Server requires a deterministic order when using `limit` (aka you have to provide `ORDER BY`). By default, in the MSSQL adapter, we inject a `ORDER BY [primary_key]` clause to achieve so, if not any `order` has been specified in the query. This now leads to an issue in Solid Queue, where `concurrency_key` is selected and MSSQL complains that `id` is not in its `SELECT` clause. I first looked into fixing this in the SQL adapter, but then found a test in `activerecord` itself (`test_pluck_and_distinct`) that orders first before calling `distinct`. So I would suggest to align Solid Queue here and order by `concurrency_key` prior to calling `distinct`. I am aware that the existing code works with SQlite, MySQL and PostgreSQL as these do not require to pass an `ORDER BY` clause with `LIMIT`. I don't think this small addition will cause any troubles on the other DBMS systems. --- app/models/solid_queue/blocked_execution.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/solid_queue/blocked_execution.rb b/app/models/solid_queue/blocked_execution.rb index b596b6de..4ad4d239 100644 --- a/app/models/solid_queue/blocked_execution.rb +++ b/app/models/solid_queue/blocked_execution.rb @@ -12,7 +12,7 @@ class BlockedExecution < Execution class << self def unblock(limit) SolidQueue.instrument(:release_many_blocked, limit: limit) do |payload| - expired.distinct.limit(limit).pluck(:concurrency_key).then do |concurrency_keys| + expired.order(:concurrency_key).distinct.limit(limit).pluck(:concurrency_key).then do |concurrency_keys| payload[:size] = release_many releasable(concurrency_keys) end end