aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/mysql_adapter.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb25
1 files changed, 25 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 9e6cb13cca..a44ac08ce4 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -192,6 +192,10 @@ module ActiveRecord
connect
end
+ def self.visitor_for(pool) # :nodoc:
+ Arel::Visitors::MySQL.new(pool)
+ end
+
def adapter_name #:nodoc:
ADAPTER_NAME
end
@@ -487,6 +491,27 @@ module ActiveRecord
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
end
+ # In the simple case, MySQL allows us to place JOINs directly into the UPDATE
+ # query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
+ # these, we must use a subquery. However, MySQL is too stupid to create a
+ # temporary table for this automatically, so we have to give it some prompting
+ # in the form of a subsubquery. Ugh!
+ def join_to_update(update, select) #:nodoc:
+ if select.limit || select.offset || select.orders.any?
+ subsubselect = select.clone
+ subsubselect.projections = [update.key]
+
+ subselect = Arel::SelectManager.new(select.engine)
+ subselect.project Arel.sql(update.key.name)
+ subselect.from subsubselect.as('__active_record_temp')
+
+ update.where update.key.in(subselect)
+ else
+ update.table select.source
+ update.wheres = select.constraints
+ end
+ end
+
# SCHEMA STATEMENTS ========================================
def structure_dump #:nodoc: