activerecord-sqlserver-adapter 7.2.8 → 7.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 388f899978fa08e71bc46c3b654dd2d41ac1e3dd49e4a3b781c1d20d983698b3
4
- data.tar.gz: b4df1bd77d215f3c0c1d1d6ea3ca101b04588ce08bdcbe4f79a446f3c5b88370
3
+ metadata.gz: aeac1dd3621ed52e93f365fefbca8a0e83ffcfbdac6b01907260efa98db1069f
4
+ data.tar.gz: daa368ec2b8e38e25aaab374640a29e7d6a5482a78609b32cabefdc716a01b78
5
5
  SHA512:
6
- metadata.gz: d407a6ef73809b08a2a7f59c04575e5986b1a788fa891f028d3e25757aa71802e4bb2e98459e45f42ddf6c316974516b3b08ba3c79e20ac5424ab4e5df99db67
7
- data.tar.gz: 4106b42012e5d0596ae1924055a3d8f92989fc35fa7882c70877b4ba35a5233e26d35a7ed1265ed8f15abbc8f2483967449c3923096a6457f8e9681c47dec7bf
6
+ metadata.gz: 0ca3530b11fd81b695bde3264fd2daaa221c7f21a7c6e86cbfef14bdf4a60b4aba26238aec58c2456d953fb1aa933c27c0800978061ad71889b0e92fc6a4ebf7
7
+ data.tar.gz: 5b3b6bbf751511101b26d319554ec1f394fc0d4a76250812146e7400a342b31aa60cb314406f4352f27a49b04fdfa79cf41c7cba12c916b866df6254bf0ddf03
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## v7.2.9
2
+
3
+ #### Fixed
4
+
5
+ - [#1371](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1371) Fixed query logging so that filter parameters are respected.
6
+
1
7
  ## v7.2.8
2
8
 
3
9
  #### Fixed
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.2.8
1
+ 7.2.9
@@ -34,12 +34,13 @@ module ActiveRecord
34
34
  check_if_write_query(sql)
35
35
  mark_transaction_written_if_write(sql)
36
36
 
37
- unless without_prepared_statement?(binds)
38
- types, params = sp_executesql_types_and_parameters(binds)
39
- sql = sp_executesql_sql(sql, types, params, name)
40
- end
37
+ type_casted_binds = type_casted_binds(binds)
38
+ log(sql, name, binds, type_casted_binds, async: async) do |notification_payload|
39
+ unless without_prepared_statement?(binds)
40
+ types, params = sp_executesql_types_and_parameters(binds)
41
+ sql = sp_executesql_sql(sql, types, params, name)
42
+ end
41
43
 
42
- log(sql, name, binds, async: async) do |notification_payload|
43
44
  with_raw_connection do |conn|
44
45
  result = if id_insert_table_name = query_requires_identity_insert?(sql)
45
46
  with_identity_insert_enabled(id_insert_table_name, conn) do
@@ -248,7 +248,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
248
248
  def test_belongs_to_coerced
249
249
  client = Client.find(3)
250
250
  first_firm = companies(:first_firm)
251
- assert_queries_match(/FETCH NEXT @(\d) ROWS ONLY(.)*@\1 = 1/) do
251
+ assert_queries_match(/FETCH NEXT @(\d) ROWS ONLY/) do
252
252
  assert_equal first_firm, client.firm
253
253
  assert_equal first_firm.name, client.firm.name
254
254
  end
@@ -257,21 +257,6 @@ end
257
257
 
258
258
  module ActiveRecord
259
259
  class BindParameterTest < ActiveRecord::TestCase
260
- # Same as original coerced test except log is found using `EXEC sp_executesql` wrapper.
261
- coerce_tests! :test_binds_are_logged
262
- def test_binds_are_logged_coerced
263
- sub = Arel::Nodes::BindParam.new(1)
264
- binds = [Relation::QueryAttribute.new("id", 1, Type::Value.new)]
265
- sql = "select * from topics where id = #{sub.to_sql}"
266
-
267
- @connection.exec_query(sql, "SQL", binds)
268
-
269
- logged_sql = "EXEC sp_executesql N'#{sql}', N'#{sub.to_sql} int', #{sub.to_sql} = 1"
270
- message = @subscriber.calls.find { |args| args[4][:sql] == logged_sql }
271
-
272
- assert_equal binds, message[4][:binds]
273
- end
274
-
275
260
  # SQL Server adapter does not use a statement cache as query plans are already reused using `EXEC sp_executesql`.
276
261
  coerce_tests! :test_statement_cache
277
262
  coerce_tests! :test_statement_cache_with_query_cache
@@ -279,55 +264,6 @@ module ActiveRecord
279
264
  coerce_tests! :test_statement_cache_with_find_by
280
265
  coerce_tests! :test_statement_cache_with_in_clause
281
266
  coerce_tests! :test_statement_cache_with_sql_string_literal
282
-
283
- # Same as original coerced test except prepared statements include `EXEC sp_executesql` wrapper.
284
- coerce_tests! :test_bind_params_to_sql_with_prepared_statements, :test_bind_params_to_sql_with_unprepared_statements
285
- def test_bind_params_to_sql_with_prepared_statements_coerced
286
- assert_bind_params_to_sql_coerced(prepared: true)
287
- end
288
-
289
- def test_bind_params_to_sql_with_unprepared_statements_coerced
290
- @connection.unprepared_statement do
291
- assert_bind_params_to_sql_coerced(prepared: false)
292
- end
293
- end
294
-
295
- private
296
-
297
- def assert_bind_params_to_sql_coerced(prepared:)
298
- table = Author.quoted_table_name
299
- pk = "#{table}.#{Author.quoted_primary_key}"
300
-
301
- # prepared_statements: true
302
- #
303
- # EXEC sp_executesql N'SELECT [authors].* FROM [authors] WHERE [authors].[id] IN (@0, @1, @2) OR [authors].[id] IS NULL)', N'@0 bigint, @1 bigint, @2 bigint', @0 = 1, @1 = 2, @2 = 3
304
- #
305
- # prepared_statements: false
306
- #
307
- # SELECT [authors].* FROM [authors] WHERE ([authors].[id] IN (1, 2, 3) OR [authors].[id] IS NULL)
308
- #
309
- sql_unprepared = "SELECT #{table}.* FROM #{table} WHERE (#{pk} IN (#{bind_params(1..3)}) OR #{pk} IS NULL)"
310
- sql_prepared = "EXEC sp_executesql N'SELECT #{table}.* FROM #{table} WHERE (#{pk} IN (#{bind_params(1..3)}) OR #{pk} IS NULL)', N'@0 bigint, @1 bigint, @2 bigint', @0 = 1, @1 = 2, @2 = 3"
311
-
312
- authors = Author.where(id: [1, 2, 3, nil])
313
- assert_equal sql_unprepared, @connection.to_sql(authors.arel)
314
- assert_queries_match(prepared ? sql_prepared : sql_unprepared) { assert_equal 3, authors.length }
315
-
316
- # prepared_statements: true
317
- #
318
- # EXEC sp_executesql N'SELECT [authors].* FROM [authors] WHERE [authors].[id] IN (@0, @1, @2)', N'@0 bigint, @1 bigint, @2 bigint', @0 = 1, @1 = 2, @2 = 3
319
- #
320
- # prepared_statements: false
321
- #
322
- # SELECT [authors].* FROM [authors] WHERE [authors].[id] IN (1, 2, 3)
323
- #
324
- sql_unprepared = "SELECT #{table}.* FROM #{table} WHERE #{pk} IN (#{bind_params(1..3)})"
325
- sql_prepared = "EXEC sp_executesql N'SELECT #{table}.* FROM #{table} WHERE #{pk} IN (#{bind_params(1..3)})', N'@0 bigint, @1 bigint, @2 bigint', @0 = 1, @1 = 2, @2 = 3"
326
-
327
- authors = Author.where(id: [1, 2, 3, 9223372036854775808])
328
- assert_equal sql_unprepared, @connection.to_sql(authors.arel)
329
- assert_queries_match(prepared ? sql_prepared : sql_unprepared) { assert_equal 3, authors.length }
330
- end
331
267
  end
332
268
  end
333
269
 
@@ -387,7 +323,7 @@ class CalculationsTest < ActiveRecord::TestCase
387
323
  assert_predicate accounts, :loaded?
388
324
  assert_equal expected, accounts.count(:id)
389
325
  end
390
-
326
+
391
327
  # Fix randomly failing test. The loading of the model's schema was affecting the test.
392
328
  coerce_tests! :test_offset_is_kept
393
329
  def test_offset_is_kept_coerced
@@ -508,7 +444,7 @@ class CalculationsTest < ActiveRecord::TestCase
508
444
  def test_limit_is_kept_coerced
509
445
  queries = capture_sql { Account.limit(1).count }
510
446
  assert_equal 1, queries.length
511
- assert_match(/ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1/, queries.first)
447
+ assert_match(/ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY/, queries.first)
512
448
  end
513
449
 
514
450
  # Match SQL Server limit implementation
@@ -516,7 +452,7 @@ class CalculationsTest < ActiveRecord::TestCase
516
452
  def test_limit_with_offset_is_kept_coerced
517
453
  queries = capture_sql { Account.limit(1).offset(1).count }
518
454
  assert_equal 1, queries.length
519
- assert_match(/ORDER BY \[accounts\]\.\[id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY.*@0 = 1, @1 = 1/, queries.first)
455
+ assert_match(/ORDER BY \[accounts\]\.\[id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY/, queries.first)
520
456
  end
521
457
 
522
458
  # SQL Server needs an alias for the calculated column
@@ -980,9 +916,9 @@ class FinderTest < ActiveRecord::TestCase
980
916
  # Assert SQL Server limit implementation
981
917
  coerce_tests! :test_take_and_first_and_last_with_integer_should_use_sql_limit
982
918
  def test_take_and_first_and_last_with_integer_should_use_sql_limit_coerced
983
- assert_queries_match(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.* @0 = 3/) { Topic.take(3).entries }
984
- assert_queries_match(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.* @0 = 2/) { Topic.first(2).entries }
985
- assert_queries_match(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.* @0 = 5/) { Topic.last(5).entries }
919
+ assert_queries_and_values_match(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY/, [3]) { Topic.take(3).entries }
920
+ assert_queries_and_values_match(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY/, [2]) { Topic.first(2).entries }
921
+ assert_queries_and_values_match(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY/, [5]) { Topic.last(5).entries }
986
922
  end
987
923
 
988
924
  # This fails only when run in the full test suite task. Just taking it out of the mix.
@@ -1013,7 +949,7 @@ class FinderTest < ActiveRecord::TestCase
1013
949
  # Check for `FETCH NEXT x ROWS` rather then `LIMIT`.
1014
950
  coerce_tests! :test_include_on_unloaded_relation_with_match
1015
951
  def test_include_on_unloaded_relation_with_match_coerced
1016
- assert_queries_match(/1 AS one.*FETCH NEXT @2 ROWS ONLY.*@2 = 1/) do
952
+ assert_queries_match(/1 AS one.*FETCH NEXT @2 ROWS ONLY/) do
1017
953
  assert_equal true, Customer.where(name: "David").include?(customers(:david))
1018
954
  end
1019
955
  end
@@ -1021,7 +957,7 @@ class FinderTest < ActiveRecord::TestCase
1021
957
  # Check for `FETCH NEXT x ROWS` rather then `LIMIT`.
1022
958
  coerce_tests! :test_include_on_unloaded_relation_without_match
1023
959
  def test_include_on_unloaded_relation_without_match_coerced
1024
- assert_queries_match(/1 AS one.*FETCH NEXT @2 ROWS ONLY.*@2 = 1/) do
960
+ assert_queries_match(/1 AS one.*FETCH NEXT @2 ROWS ONLY/) do
1025
961
  assert_equal false, Customer.where(name: "David").include?(customers(:mary))
1026
962
  end
1027
963
  end
@@ -1029,7 +965,7 @@ class FinderTest < ActiveRecord::TestCase
1029
965
  # Check for `FETCH NEXT x ROWS` rather then `LIMIT`.
1030
966
  coerce_tests! :test_member_on_unloaded_relation_with_match
1031
967
  def test_member_on_unloaded_relation_with_match_coerced
1032
- assert_queries_match(/1 AS one.*FETCH NEXT @2 ROWS ONLY.*@2 = 1/) do
968
+ assert_queries_match(/1 AS one.*FETCH NEXT @2 ROWS ONLY/) do
1033
969
  assert_equal true, Customer.where(name: "David").member?(customers(:david))
1034
970
  end
1035
971
  end
@@ -1037,7 +973,7 @@ class FinderTest < ActiveRecord::TestCase
1037
973
  # Check for `FETCH NEXT x ROWS` rather then `LIMIT`.
1038
974
  coerce_tests! :test_member_on_unloaded_relation_without_match
1039
975
  def test_member_on_unloaded_relation_without_match_coerced
1040
- assert_queries_match(/1 AS one.*FETCH NEXT @2 ROWS ONLY.*@2 = 1/) do
976
+ assert_queries_match(/1 AS one.*FETCH NEXT @2 ROWS ONLY/) do
1041
977
  assert_equal false, Customer.where(name: "David").member?(customers(:mary))
1042
978
  end
1043
979
  end
@@ -1052,7 +988,7 @@ class FinderTest < ActiveRecord::TestCase
1052
988
  assert_equal topics(:third), Topic.last
1053
989
 
1054
990
  c = Topic.lease_connection
1055
- assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.title"))} DESC, #{Regexp.escape(c.quote_table_name("topics.id"))} DESC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1/i) {
991
+ assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.title"))} DESC, #{Regexp.escape(c.quote_table_name("topics.id"))} DESC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY/i) {
1056
992
  Topic.last
1057
993
  }
1058
994
  ensure
@@ -1066,7 +1002,7 @@ class FinderTest < ActiveRecord::TestCase
1066
1002
  Topic.implicit_order_column = "id"
1067
1003
 
1068
1004
  c = Topic.lease_connection
1069
- assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.id"))} DESC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1/i) {
1005
+ assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.id"))} DESC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY/i) {
1070
1006
  Topic.last
1071
1007
  }
1072
1008
  ensure
@@ -1081,7 +1017,7 @@ class FinderTest < ActiveRecord::TestCase
1081
1017
 
1082
1018
  c = NonPrimaryKey.lease_connection
1083
1019
 
1084
- assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("non_primary_keys.created_at"))} DESC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1/i) {
1020
+ assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("non_primary_keys.created_at"))} DESC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY/i) {
1085
1021
  NonPrimaryKey.last
1086
1022
  }
1087
1023
  ensure
@@ -1091,7 +1027,7 @@ class FinderTest < ActiveRecord::TestCase
1091
1027
  # Check for `FETCH NEXT x ROWS` rather then `LIMIT`.
1092
1028
  coerce_tests! :test_member_on_unloaded_relation_with_composite_primary_key
1093
1029
  def test_member_on_unloaded_relation_with_composite_primary_key_coerced
1094
- assert_queries_match(/1 AS one.* FETCH NEXT @(\d) ROWS ONLY.*@\1 = 1/) do
1030
+ assert_queries_match(/1 AS one.* FETCH NEXT @(\d) ROWS ONLY/) do
1095
1031
  book = cpk_books(:cpk_great_author_first_book)
1096
1032
  assert Cpk::Book.where(title: "The first book").member?(book)
1097
1033
  end
@@ -1106,7 +1042,7 @@ class FinderTest < ActiveRecord::TestCase
1106
1042
  quoted_color = Regexp.escape(c.quote_table_name("clothing_items.color"))
1107
1043
  quoted_descrption = Regexp.escape(c.quote_table_name("clothing_items.description"))
1108
1044
 
1109
- assert_queries_match(/ORDER BY #{quoted_descrption} ASC, #{quoted_type} ASC, #{quoted_color} ASC OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY.*@\1 = 1/i) do
1045
+ assert_queries_match(/ORDER BY #{quoted_descrption} ASC, #{quoted_type} ASC, #{quoted_color} ASC OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY/i) do
1110
1046
  assert_kind_of ClothingItem, ClothingItem.first
1111
1047
  end
1112
1048
  ensure
@@ -1120,7 +1056,7 @@ class FinderTest < ActiveRecord::TestCase
1120
1056
  quoted_type = Regexp.escape(c.quote_table_name("clothing_items.clothing_type"))
1121
1057
  quoted_color = Regexp.escape(c.quote_table_name("clothing_items.color"))
1122
1058
 
1123
- assert_queries_match(/ORDER BY #{quoted_type} DESC, #{quoted_color} DESC OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY.*@\1 = 1/i) do
1059
+ assert_queries_match(/ORDER BY #{quoted_type} DESC, #{quoted_color} DESC OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY/i) do
1124
1060
  assert_kind_of ClothingItem, ClothingItem.last
1125
1061
  end
1126
1062
  end
@@ -1132,7 +1068,7 @@ class FinderTest < ActiveRecord::TestCase
1132
1068
  quoted_type = Regexp.escape(c.quote_table_name("clothing_items.clothing_type"))
1133
1069
  quoted_color = Regexp.escape(c.quote_table_name("clothing_items.color"))
1134
1070
 
1135
- assert_queries_match(/ORDER BY #{quoted_type} ASC, #{quoted_color} ASC OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY.*@\1 = 1/i) do
1071
+ assert_queries_match(/ORDER BY #{quoted_type} ASC, #{quoted_color} ASC OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY/i) do
1136
1072
  assert_kind_of ClothingItem, ClothingItem.first
1137
1073
  end
1138
1074
  end
@@ -1145,7 +1081,7 @@ class FinderTest < ActiveRecord::TestCase
1145
1081
  quoted_type = Regexp.escape(c.quote_table_name("clothing_items.clothing_type"))
1146
1082
  quoted_color = Regexp.escape(c.quote_table_name("clothing_items.color"))
1147
1083
 
1148
- assert_queries_match(/ORDER BY #{quoted_color} ASC, #{quoted_type} ASC OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY.*@\1 = 1/i) do
1084
+ assert_queries_match(/ORDER BY #{quoted_color} ASC, #{quoted_type} ASC OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY/i) do
1149
1085
  assert_kind_of ClothingItem, ClothingItem.first
1150
1086
  end
1151
1087
  ensure
@@ -1155,7 +1091,7 @@ class FinderTest < ActiveRecord::TestCase
1155
1091
  # Check for `FETCH NEXT x ROWS` rather then `LIMIT`.
1156
1092
  coerce_tests! :test_include_on_unloaded_relation_with_composite_primary_key
1157
1093
  def test_include_on_unloaded_relation_with_composite_primary_key_coerced
1158
- assert_queries_match(/1 AS one.*OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY.*@\1 = 1/) do
1094
+ assert_queries_match(/1 AS one.*OFFSET 0 ROWS FETCH NEXT @(\d) ROWS ONLY/) do
1159
1095
  book = cpk_books(:cpk_great_author_first_book)
1160
1096
  assert Cpk::Book.where(title: "The first book").include?(book)
1161
1097
  end
@@ -1165,11 +1101,11 @@ class FinderTest < ActiveRecord::TestCase
1165
1101
  coerce_tests! :test_nth_to_last_with_order_uses_limit
1166
1102
  def test_nth_to_last_with_order_uses_limit_coerced
1167
1103
  c = Topic.lease_connection
1168
- assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.id"))} DESC OFFSET @(\d) ROWS FETCH NEXT @(\d) ROWS ONLY.*@\1 = 1.*@\2 = 1/i) do
1104
+ assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.id"))} DESC OFFSET @(\d) ROWS FETCH NEXT @(\d) ROWS ONLY/i) do
1169
1105
  Topic.second_to_last
1170
1106
  end
1171
1107
 
1172
- assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.updated_at"))} DESC OFFSET @(\d) ROWS FETCH NEXT @(\d) ROWS ONLY.*@\1 = 1.*@\2 = 1/i) do
1108
+ assert_queries_match(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.updated_at"))} DESC OFFSET @(\d) ROWS FETCH NEXT @(\d) ROWS ONLY/i) do
1173
1109
  Topic.order(:updated_at).second_to_last
1174
1110
  end
1175
1111
  end
@@ -1217,7 +1153,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
1217
1153
  def test_has_one_coerced
1218
1154
  firm = companies(:first_firm)
1219
1155
  first_account = Account.find(1)
1220
- assert_queries_match(/FETCH NEXT @(\d) ROWS ONLY(.)*@\1 = 1/) do
1156
+ assert_queries_match(/FETCH NEXT @(\d) ROWS ONLY/) do
1221
1157
  assert_equal first_account, firm.account
1222
1158
  assert_equal first_account.credit_limit, firm.account.credit_limit
1223
1159
  end
@@ -1229,7 +1165,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
1229
1165
  coerce_tests! :test_has_one_through_executes_limited_query
1230
1166
  def test_has_one_through_executes_limited_query_coerced
1231
1167
  boring_club = clubs(:boring_club)
1232
- assert_queries_match(/FETCH NEXT @(\d) ROWS ONLY(.)*@\1 = 1/) do
1168
+ assert_queries_match(/FETCH NEXT @(\d) ROWS ONLY/) do
1233
1169
  assert_equal boring_club, @member.general_club
1234
1170
  end
1235
1171
  end
@@ -1436,7 +1372,7 @@ class RelationTest < ActiveRecord::TestCase
1436
1372
  # Find any limit via our expression.
1437
1373
  coerce_tests! %r{relations don't load all records in #inspect}
1438
1374
  def test_relations_dont_load_all_records_in_inspect_coerced
1439
- assert_queries_match(/NEXT @0 ROWS.*@0 = \d+/) do
1375
+ assert_queries_match(/NEXT @0 ROWS/) do
1440
1376
  Post.all.inspect
1441
1377
  end
1442
1378
  end
@@ -2124,7 +2060,7 @@ class RelationMergingTest < ActiveRecord::TestCase
2124
2060
  non_mary_and_bob = Author.where.not(id: [mary, bob])
2125
2061
 
2126
2062
  author_id = Author.lease_connection.quote_table_name("authors.id")
2127
- assert_queries_match(/WHERE #{Regexp.escape(author_id)} NOT IN \((@\d), \g<1>\)'/) do
2063
+ assert_queries_match(/WHERE #{Regexp.escape(author_id)} NOT IN \((@\d), \g<1>\)/) do
2128
2064
  assert_equal [david], non_mary_and_bob.merge(non_mary_and_bob)
2129
2065
  end
2130
2066
 
@@ -2262,14 +2198,6 @@ class LogSubscriberTest < ActiveRecord::TestCase
2262
2198
  def test_verbose_query_logs_coerced
2263
2199
  original_test_verbose_query_logs
2264
2200
  end
2265
-
2266
- # Bindings logged slightly differently.
2267
- coerce_tests! :test_where_in_binds_logging_include_attribute_names
2268
- def test_where_in_binds_logging_include_attribute_names_coerced
2269
- Developer.where(id: [1, 2, 3, 4, 5]).load
2270
- wait
2271
- assert_match(%{@0 = 1, @1 = 2, @2 = 3, @3 = 4, @4 = 5 [["id", nil], ["id", nil], ["id", nil], ["id", nil], ["id", nil]]}, @logger.logged(:debug).last)
2272
- end
2273
2201
  end
2274
2202
 
2275
2203
  class ReloadModelsTest < ActiveRecord::TestCase
@@ -2337,7 +2265,7 @@ class PreloaderTest < ActiveRecord::TestCase
2337
2265
 
2338
2266
  c = Cpk::OrderAgreement.lease_connection
2339
2267
  order_id_column = Regexp.escape(c.quote_table_name("cpk_order_agreements.order_id"))
2340
- order_id_constraint = /#{order_id_column} = @0.*@0 = \d+$/
2268
+ order_id_constraint = /#{order_id_column} = @0$/
2341
2269
  expectation = /SELECT.*WHERE.* #{order_id_constraint}/
2342
2270
 
2343
2271
  assert_match(expectation, preload_sql)
@@ -2361,7 +2289,7 @@ class PreloaderTest < ActiveRecord::TestCase
2361
2289
 
2362
2290
  c = Cpk::Order.lease_connection
2363
2291
  order_id = Regexp.escape(c.quote_table_name("cpk_orders.id"))
2364
- order_constraint = /#{order_id} = @0.*@0 = \d+$/
2292
+ order_constraint = /#{order_id} = @0$/
2365
2293
  expectation = /SELECT.*WHERE.* #{order_constraint}/
2366
2294
 
2367
2295
  assert_match(expectation, preload_sql)
@@ -2432,7 +2360,7 @@ class QueryLogsTest < ActiveRecord::TestCase
2432
2360
  coerce_tests! :test_sql_commenter_format
2433
2361
  def test_sql_commenter_format_coerced
2434
2362
  ActiveRecord::QueryLogs.update_formatter(:sqlcommenter)
2435
- assert_queries_match(%r{/\*application=''active_record''\*/}) do
2363
+ assert_queries_match(%r{/\*application='active_record'\*/}) do
2436
2364
  Dashboard.first
2437
2365
  end
2438
2366
  end
@@ -2447,7 +2375,7 @@ class QueryLogsTest < ActiveRecord::TestCase
2447
2375
  { tracestate: "congo=t61rcWkgMzE,rojo=00f067aa0ba902b7", custom_proc: -> { "Joe's Shack" } },
2448
2376
  ]
2449
2377
 
2450
- assert_queries_match(%r{custom_proc=''Joe%27s%20Shack'',tracestate=''congo%3Dt61rcWkgMzE%2Crojo%3D00f067aa0ba902b7''\*/}) do
2378
+ assert_queries_match(%r{custom_proc='Joe%27s%20Shack',tracestate='congo%3Dt61rcWkgMzE%2Crojo%3D00f067aa0ba902b7'\*/}) do
2451
2379
  Dashboard.first
2452
2380
  end
2453
2381
  end
@@ -2462,7 +2390,7 @@ class QueryLogsTest < ActiveRecord::TestCase
2462
2390
  { custom_proc: -> { 1234 } },
2463
2391
  ]
2464
2392
 
2465
- assert_queries_match(%r{custom_proc=''1234''\*/}) do
2393
+ assert_queries_match(%r{custom_proc='1234'\*/}) do
2466
2394
  Dashboard.first
2467
2395
  end
2468
2396
  end
@@ -2481,7 +2409,7 @@ class QueryLogsTest < ActiveRecord::TestCase
2481
2409
  },
2482
2410
  ]
2483
2411
 
2484
- assert_queries_match(%r{custom_proc=''Joe%27s%20Shack'',string=''value'',tracestate=''congo%3Dt61rcWkgMzE%2Crojo%3D00f067aa0ba902b7''\*/}) do
2412
+ assert_queries_match(%r{custom_proc='Joe%27s%20Shack',string='value',tracestate='congo%3Dt61rcWkgMzE%2Crojo%3D00f067aa0ba902b7'\*/}) do
2485
2413
  Dashboard.first
2486
2414
  end
2487
2415
  end
@@ -2705,7 +2633,7 @@ class ExplainTest < ActiveRecord::TestCase
2705
2633
  def test_relation_explain_with_first_coerced
2706
2634
  expected_query = capture_sql {
2707
2635
  Car.all.first
2708
- }.first[/EXEC sp_executesql N'(.*?) NEXT/, 1]
2636
+ }.first[/(.*?) NEXT/, 1]
2709
2637
  message = Car.all.explain.first
2710
2638
  assert_match(/^EXPLAIN/, message)
2711
2639
  assert_match(expected_query, message)
@@ -2716,7 +2644,7 @@ class ExplainTest < ActiveRecord::TestCase
2716
2644
  def test_relation_explain_with_last_coerced
2717
2645
  expected_query = capture_sql {
2718
2646
  Car.all.last
2719
- }.first[/EXEC sp_executesql N'(.*?) NEXT/, 1]
2647
+ }.first[/(.*?) NEXT/, 1]
2720
2648
  expected_query = expected_query
2721
2649
  message = Car.all.explain.last
2722
2650
 
@@ -29,7 +29,7 @@ class OptimizerHitsTestSQLServer < ActiveRecord::TestCase
29
29
  end
30
30
 
31
31
  it "support subqueries" do
32
- assert_queries_match(%r{.*'SELECT COUNT\(count_column\) FROM \(SELECT .*\) subquery_for_count OPTION \(MAXDOP 2\)'.*}) do
32
+ assert_queries_match(%r{SELECT COUNT\(count_column\) FROM \(SELECT .*\) subquery_for_count OPTION \(MAXDOP 2\)}) do
33
33
  companies = Company.optimizer_hints("MAXDOP 2")
34
34
  companies = companies.select(:id).where(firm_id: [0, 1]).limit(3)
35
35
  assert_equal 3, companies.count
@@ -28,13 +28,13 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase
28
28
 
29
29
  it "from array condition using index" do
30
30
  plan = Car.where(id: [1, 2]).explain.inspect
31
- _(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] IN (1, 2)"
31
+ _(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id]"
32
32
  _(plan).must_include "Clustered Index Seek", "make sure we do not showplan the sp_executesql"
33
33
  end
34
34
 
35
35
  it "from array condition" do
36
36
  plan = Car.where(name: ["honda", "zyke"]).explain.inspect
37
- _(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name] IN (N'honda', N'zyke')"
37
+ _(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name]"
38
38
  _(plan).must_include "Clustered Index Scan", "make sure we do not showplan the sp_executesql"
39
39
  end
40
40
  end
@@ -116,16 +116,16 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase
116
116
  end
117
117
  end
118
118
  # Using ActiveRecord's quoted_id feature for objects.
119
- assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: value.new).first }
120
- assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: value.new).first }
119
+ assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(char_col: value.new).first }
120
+ assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(varchar_col: value.new).first }
121
121
  # Using our custom char type data.
122
122
  type = ActiveRecord::Type::SQLServer::Char
123
123
  data = ActiveRecord::Type::SQLServer::Data
124
- assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: data.new("T", type.new)).first }
125
- assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: data.new("T", type.new)).first }
124
+ assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(char_col: data.new("T", type.new)).first }
125
+ assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(varchar_col: data.new("T", type.new)).first }
126
126
  # Taking care of everything.
127
- assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(char_col: "T").first }
128
- assert_queries_match(/@0 = 'T'/) { SSTestDatatypeMigration.where(varchar_col: "T").first }
127
+ assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(char_col: "T").first }
128
+ assert_queries_and_values_match(/.*/, ["'T'", 1]) { SSTestDatatypeMigration.where(varchar_col: "T").first }
129
129
  end
130
130
 
131
131
  it "can update and hence properly quoted non-national char/varchar columns" do
@@ -22,6 +22,28 @@ module ARTest
22
22
  end
23
23
  end
24
24
 
25
+ def assert_queries_and_values_match(match, bound_values=[], count: nil, &block)
26
+ ActiveRecord::Base.lease_connection.materialize_transactions
27
+
28
+ counter = ActiveRecord::Assertions::QueryAssertions::SQLCounter.new
29
+ ActiveSupport::Notifications.subscribed(counter, "sql.active_record") do
30
+ result = _assert_nothing_raised_or_warn("assert_queries_match", &block)
31
+ queries = counter.log_full
32
+ matched_queries = queries.select do |query, values|
33
+ values = values.map { |v| v.respond_to?(:quoted) ? v.quoted : v }
34
+ match === query && bound_values === values
35
+ end
36
+
37
+ if count
38
+ assert_equal count, matched_queries.size, "#{matched_queries.size} instead of #{count} queries were executed.#{count.log.empty? ? '' : "\nQueries:\n#{counter.log.join("\n")}"}"
39
+ else
40
+ assert_operator matched_queries.size, :>=, 1, "1 or more queries expected, but none were executed.#{counter.log.empty? ? '' : "\nQueries:\n#{counter.log.join("\n")}"}"
41
+ end
42
+
43
+ result
44
+ end
45
+ end
46
+
25
47
  private
26
48
 
27
49
  # Rails tests expect a save-point to be created and released. SQL Server does not release
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-sqlserver-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.8
4
+ version: 7.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Collins
@@ -241,8 +241,8 @@ licenses:
241
241
  - MIT
242
242
  metadata:
243
243
  bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
244
- changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.2.8/CHANGELOG.md
245
- source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.2.8
244
+ changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.2.9/CHANGELOG.md
245
+ source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.2.9
246
246
  rdoc_options: []
247
247
  require_paths:
248
248
  - lib