Skip to content

Commit 3973683

Browse files
authored
Fix upserting with mixed data types (#1320)
1 parent f69c849 commit 3973683

File tree

5 files changed

+33
-1
lines changed

5 files changed

+33
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@
1313
#### Fixed
1414

1515
- [#1313](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1313) Correctly retrieve the SQL Server database version.
16+
- [#1320](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1320) Fix SQL statement to calculate `updated_at` when upserting
1617

1718
Please check [8-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/8-0-stable/CHANGELOG.md) for previous changes.

lib/active_record/connection_adapters/sqlserver/database_statements.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ def joining_on_columns_with_uniqueness_constraints(columns_with_uniqueness_const
592592
def build_sql_for_recording_timestamps_when_updating(insert:)
593593
insert.model.timestamp_attributes_for_update_in_model.filter_map do |column_name|
594594
if insert.send(:touch_timestamp_attribute?, column_name)
595-
"target.#{quote_column_name(column_name)}=CASE WHEN (#{insert.updatable_columns.map { |column| "(COALESCE(target.#{quote_column_name(column)}, 'NULL') = COALESCE(source.#{quote_column_name(column)}, 'NULL'))" }.join(" AND ")}) THEN target.#{quote_column_name(column_name)} ELSE #{high_precision_current_timestamp} END,"
595+
"target.#{quote_column_name(column_name)}=CASE WHEN (#{insert.updatable_columns.map { |column| "(source.#{quote_column_name(column)} = target.#{quote_column_name(column)} OR (source.#{quote_column_name(column)} IS NULL AND target.#{quote_column_name(column)} IS NULL))" }.join(" AND ")}) THEN target.#{quote_column_name(column_name)} ELSE #{high_precision_current_timestamp} END,"
596596
end
597597
end.join
598598
end
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
require "cases/helper_sqlserver"
4+
require "models/sqlserver/recurring_task"
5+
6+
class InsertAllTestSQLServer < ActiveRecord::TestCase
7+
test "upsert_all recording of timestamps works with mixed datatypes" do
8+
task = RecurringTask.create!(
9+
key: "abcdef",
10+
priority: 5
11+
)
12+
13+
RecurringTask.upsert_all([{
14+
id: task.id,
15+
priority: nil
16+
}])
17+
18+
assert_not_equal task.updated_at, RecurringTask.find(task.id).updated_at
19+
end
20+
end
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class RecurringTask < ActiveRecord::Base
2+
self.table_name = "recurring_tasks"
3+
end

test/schema/sqlserver_specific_schema.rb

+8
Original file line numberDiff line numberDiff line change
@@ -372,4 +372,12 @@
372372
name varchar(255)
373373
)
374374
TABLE_IN_OTHER_SCHEMA_USED_BY_MODEL
375+
376+
create_table "recurring_tasks", force: true do |t|
377+
t.string :key
378+
t.integer :priority, default: 0
379+
380+
t.datetime2 :created_at
381+
t.datetime2 :updated_at
382+
end
375383
end

0 commit comments

Comments
 (0)