Skip to content

Commit a110dc5

Browse files
committed
Refactor Mysql2Adatper#perform_query
`if prepare` is checked so much that it's more redable to duplicate a bit of code so that it's only checked once.
1 parent 26ca4b6 commit a110dc5

File tree

1 file changed

+23
-21
lines changed

1 file changed

+23
-21
lines changed

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

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notif
4848
# made since we established the connection
4949
raw_connection.query_options[:database_timezone] = default_timezone
5050

51-
result = if binds.nil? || binds.empty?
51+
result = nil
52+
if binds.nil? || binds.empty?
5253
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
5354
result = raw_connection.query(sql)
5455
# Ref: https://github.com/brianmario/mysql2/pull/1383
@@ -57,39 +58,40 @@ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notif
5758
# By avoiding to call `#affected_rows` when we have a result, we reduce the likeliness
5859
# of hitting the bug.
5960
@affected_rows_before_warnings = result&.size || raw_connection.affected_rows
60-
result
6161
end
62-
result
63-
else
64-
if prepare
65-
stmt = @statements[sql] ||= raw_connection.prepare(sql)
66-
else
67-
stmt = raw_connection.prepare(sql)
62+
elsif prepare
63+
stmt = @statements[sql] ||= raw_connection.prepare(sql)
64+
begin
65+
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
66+
result = stmt.execute(*type_casted_binds)
67+
@affected_rows_before_warnings = stmt.affected_rows
68+
end
69+
rescue ::Mysql2::Error
70+
@statements.delete(sql)
71+
raise
6872
end
73+
else
74+
stmt = raw_connection.prepare(sql)
6975

7076
begin
7177
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
7278
result = stmt.execute(*type_casted_binds)
7379
@affected_rows_before_warnings = stmt.affected_rows
74-
75-
# Ref: https://github.com/brianmario/mysql2/pull/1383
76-
# by eagerly closing uncached prepared statements, we also reduce the chances of
77-
# that bug happening. It can still happen if `#execute` is used as we have no callback
78-
# to eagerly close the statement.
79-
result.instance_variable_set(:@_ar_stmt_to_close, stmt) if result && !prepare
80-
result
8180
end
82-
rescue ::Mysql2::Error
83-
if prepare
84-
@statements.delete(sql)
81+
82+
# Ref: https://github.com/brianmario/mysql2/pull/1383
83+
# by eagerly closing uncached prepared statements, we also reduce the chances of
84+
# that bug happening. It can still happen if `#execute` is used as we have no callback
85+
# to eagerly close the statement.
86+
if result
87+
result.instance_variable_set(:@_ar_stmt_to_close, stmt)
8588
else
8689
stmt.close
8790
end
88-
91+
rescue ::Mysql2::Error
92+
stmt.close
8993
raise
9094
end
91-
92-
result
9395
end
9496

9597
notification_payload[:affected_rows] = @affected_rows_before_warnings

0 commit comments

Comments
 (0)