Prior to Rails 5.2, MySQL and PostgreSQL adapters had select_value, select_values & select_rows select_{value,values,rows} methods. They improve the performance by not instantiating ActiveRecord::Result.
However these methods broke query caching of ActiveRecord::FinderMethods#exists? method. Let's check the issue.
1>> User.cache do 2>> 2.times { User.exists?(1) } 3>> end 4 5User Exists (2.1ms) SELECT 1 AS one FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 6 7User Exists (2ms) SELECT 1 AS one FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 8
As we can see, query was not cached and sql was executed second time.
From Rails 5.2, MySQL and PostgreSQL adapters are no longer override select_{value,values,rows} methods which fix this query caching issue.
Also, the performance improvement provided by these methods was marginal and not a hotspot in Active Record, so this change was accepted.
Let's check query caching of ActiveRecord::FinderMethods#exists? after the change.
1>> User.cache do 2>> 2.times { User.exists?(1) } 3>> end 4 5User Exists (2.1ms) SELECT 1 AS one FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 6 7CACHE User Exists (0.0ms) SELECT 1 AS one FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Now, query has been cached as expected.
This change has been backported in rails 5.1 from version 5.1.2 as well.