Fix upsert
warning for MySQL
This commit is contained in:
parent
2fa3294618
commit
0e7826e10e
@ -639,18 +639,37 @@ def default_index_type?(index) # :nodoc:
|
||||
end
|
||||
|
||||
def build_insert_sql(insert) # :nodoc:
|
||||
sql = +"INSERT #{insert.into} #{insert.values_list}"
|
||||
no_op_column = quote_column_name(insert.keys.first)
|
||||
|
||||
if insert.skip_duplicates?
|
||||
no_op_column = quote_column_name(insert.keys.first)
|
||||
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
|
||||
elsif insert.update_duplicates?
|
||||
sql << " ON DUPLICATE KEY UPDATE "
|
||||
if insert.raw_update_sql?
|
||||
sql << insert.raw_update_sql
|
||||
else
|
||||
sql << insert.touch_model_timestamps_unless { |column| "#{column}<=>VALUES(#{column})" }
|
||||
sql << insert.updatable_columns.map { |column| "#{column}=VALUES(#{column})" }.join(",")
|
||||
# Avoid MySQL 8.0 deprecation warning, see https://dev.mysql.com/worklog/task/?id=13325.
|
||||
if !mariadb? && database_version >= "8.0.0"
|
||||
values_alias = quote_table_name("#{insert.model.table_name}_values")
|
||||
sql = +"INSERT #{insert.into} #{insert.values_list} AS #{values_alias}"
|
||||
|
||||
if insert.skip_duplicates?
|
||||
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{values_alias}.#{no_op_column}"
|
||||
elsif insert.update_duplicates?
|
||||
sql << " ON DUPLICATE KEY UPDATE "
|
||||
if insert.raw_update_sql?
|
||||
sql << insert.raw_update_sql
|
||||
else
|
||||
sql << insert.touch_model_timestamps_unless { |column| "#{insert.model.quoted_table_name}.#{column}<=>#{values_alias}.#{column}" }
|
||||
sql << insert.updatable_columns.map { |column| "#{column}=#{values_alias}.#{column}" }.join(",")
|
||||
end
|
||||
end
|
||||
else
|
||||
sql = +"INSERT #{insert.into} #{insert.values_list}"
|
||||
|
||||
if insert.skip_duplicates?
|
||||
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
|
||||
elsif insert.update_duplicates?
|
||||
sql << " ON DUPLICATE KEY UPDATE "
|
||||
if insert.raw_update_sql?
|
||||
sql << insert.raw_update_sql
|
||||
else
|
||||
sql << insert.touch_model_timestamps_unless { |column| "#{column}<=>VALUES(#{column})" }
|
||||
sql << insert.updatable_columns.map { |column| "#{column}=VALUES(#{column})" }.join(",")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -20,6 +20,7 @@ class InsertAllTest < ActiveRecord::TestCase
|
||||
|
||||
def setup
|
||||
Arel::Table.engine = nil # should not rely on the global Arel::Table.engine
|
||||
@original_db_warnings_action = :ignore
|
||||
end
|
||||
|
||||
def teardown
|
||||
@ -336,6 +337,22 @@ def test_upsert_logs_message_including_model_name
|
||||
end
|
||||
end
|
||||
|
||||
def test_upsert_and_db_warnings
|
||||
skip unless supports_insert_on_duplicate_update?
|
||||
|
||||
begin
|
||||
with_db_warnings_action(:raise) do
|
||||
assert_nothing_raised do
|
||||
Book.upsert({ id: 1001, name: "Remote", author_id: 1 })
|
||||
end
|
||||
end
|
||||
ensure
|
||||
# We need to explicitly remove the record, because `with_db_warnings_action`
|
||||
# prevents the wrapping transaction to be rolled back.
|
||||
Book.delete(1001)
|
||||
end
|
||||
end
|
||||
|
||||
def test_upsert_all_logs_message_including_model_name
|
||||
skip unless supports_insert_on_duplicate_update?
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user