Skip to content

Commit c165c07

Browse files
authored
Merge pull request rails#53277 from skipkayhil/hm-instrument-affected-rows
Add affected_rows to sql.active_record
2 parents b0f74bf + a029da5 commit c165c07

File tree

8 files changed

+37
-2
lines changed

8 files changed

+37
-2
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Add `affected_rows` to `sql.active_record` Notification.
2+
3+
*Hartley McGuire*
4+
15
* Fix `sum` when performing a grouped calculation.
26

37
`User.group(:friendly).sum` no longer worked. This is fixed.

activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ def log(sql, name = "SQL", binds = [], type_casted_binds = [], async: false, &bl
11351135
async: async,
11361136
connection: self,
11371137
transaction: current_transaction.user_transaction.presence,
1138+
affected_rows: 0,
11381139
row_count: 0,
11391140
&block
11401141
)

activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,11 @@ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notif
6565
raw_connection.query(sql)
6666
end
6767

68+
@affected_rows_before_warnings = raw_connection.affected_rows
69+
70+
notification_payload[:affected_rows] = @affected_rows_before_warnings
6871
notification_payload[:row_count] = result&.size || 0
6972

70-
@affected_rows_before_warnings = raw_connection.affected_rows
7173
raw_connection.abandon_results!
7274

7375
verified!

activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notif
164164

165165
verified!
166166
handle_warnings(result)
167+
168+
notification_payload[:affected_rows] = result.cmd_tuples
167169
notification_payload[:row_count] = result.count
168170
result
169171
end

activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notif
109109
@last_affected_rows = raw_connection.changes
110110
verified!
111111

112+
notification_payload[:affected_rows] = @last_affected_rows
112113
notification_payload[:row_count] = result&.length || 0
113114
result
114115
end

activerecord/lib/active_record/connection_adapters/trilogy/database_statements.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notif
3030
end
3131
verified!
3232
handle_warnings(sql)
33+
34+
notification_payload[:affected_rows] = result.affected_rows
3335
notification_payload[:row_count] = result.count
3436
result
3537
ensure

activerecord/test/cases/instrumentation_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,27 @@ def test_payload_row_count_on_cache
172172
assert_equal 1, events[1][:row_count]
173173
end
174174

175+
def test_payload_affected_rows
176+
affected_row_values = []
177+
178+
ActiveSupport::Notifications.subscribed(
179+
-> (event) { affected_row_values << event.payload[:affected_rows] },
180+
"sql.active_record",
181+
) do
182+
# The combination of MariaDB + Trilogy returns 0 for affected_rows with
183+
# INSERT ... RETURNING
184+
Book.insert_all!([{ name: "One" }, { name: "Two" }, { name: "Three" }, { name: "Four" }], returning: false)
185+
186+
Book.where(name: ["One", "Two", "Three"]).update_all(status: :published)
187+
188+
Book.where(name: ["Three", "Four"]).delete_all
189+
190+
Book.where(name: ["Three", "Four"]).delete_all
191+
end
192+
193+
assert_equal [4, 3, 2, 0], affected_row_values
194+
end
195+
175196
def test_payload_connection_with_query_cache_disabled
176197
connection = ClothingItem.lease_connection
177198
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |_, _, _, _, payload|

guides/source/active_support_instrumentation.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ The `:cache_hits` key is only included if the collection is rendered with `cache
367367
| `:async` | `true` if query is loaded asynchronously |
368368
| `:cached` | `true` is added when cached queries used |
369369
| `:row_count` | Number of rows returned by the query |
370+
| `:affected_rows` | Number of rows affected by the query |
370371

371372
Adapters may add their own data as well.
372373

@@ -379,7 +380,8 @@ Adapters may add their own data as well.
379380
binds: [<ActiveModel::Attribute::WithCastValue:0x00007fe19d15dc00>],
380381
type_casted_binds: [11],
381382
statement_name: nil,
382-
row_count: 5
383+
row_count: 5,
384+
affected_rows: 0
383385
}
384386
```
385387

0 commit comments

Comments
 (0)