activerecord-jdbcsqlserver-adapter 50.0.0 → 52.0.0

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.travis.yml +4 -5
  4. data/CHANGELOG.md +22 -101
  5. data/{Dockerfile → Dockerfile.ci} +0 -0
  6. data/Gemfile +1 -3
  7. data/README.md +5 -9
  8. data/VERSION +1 -1
  9. data/activerecord-jdbcsqlserver-adapter.gemspec +2 -2
  10. data/appveyor.yml +1 -1
  11. data/docker-compose.ci.yml +7 -5
  12. data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +3 -1
  13. data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +3 -1
  14. data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +51 -0
  15. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +18 -20
  16. data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +5 -3
  17. data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +43 -0
  18. data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +26 -0
  19. data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +13 -2
  20. data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +94 -28
  21. data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +1 -0
  22. data/lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb +5 -25
  23. data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +24 -1
  24. data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +23 -2
  25. data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +110 -74
  26. data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +15 -7
  27. data/lib/active_record/connection_adapters/sqlserver/transaction.rb +3 -4
  28. data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +0 -4
  29. data/lib/active_record/connection_adapters/sqlserver/type/data.rb +5 -0
  30. data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +3 -6
  31. data/lib/active_record/connection_adapters/sqlserver/type/json.rb +1 -1
  32. data/lib/active_record/connection_adapters/sqlserver/type/string.rb +7 -0
  33. data/lib/active_record/connection_adapters/sqlserver/type/time.rb +1 -0
  34. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +47 -24
  35. data/lib/active_record/tasks/sqlserver_database_tasks.rb +5 -3
  36. data/lib/activerecord-jdbcsqlserver-adapter.rb +4 -1
  37. data/lib/arel/visitors/sqlserver.rb +17 -4
  38. data/lib/arel_sqlserver.rb +0 -1
  39. data/lib/jdbc_mssql_driver_loader.rb +22 -0
  40. data/test/bin/install-freetds.sh +18 -0
  41. data/test/bin/setup.sh +19 -0
  42. data/test/cases/adapter_test_sqlserver.rb +43 -39
  43. data/test/cases/change_column_null_test_sqlserver.rb +42 -0
  44. data/test/cases/coerced_tests.rb +419 -39
  45. data/test/cases/column_test_sqlserver.rb +496 -462
  46. data/test/cases/connection_test_sqlserver.rb +2 -2
  47. data/test/cases/fetch_test_sqlserver.rb +5 -5
  48. data/test/cases/helper_sqlserver.rb +12 -1
  49. data/test/cases/json_test_sqlserver.rb +6 -6
  50. data/test/cases/migration_test_sqlserver.rb +13 -3
  51. data/test/cases/order_test_sqlserver.rb +19 -19
  52. data/test/cases/pessimistic_locking_test_sqlserver.rb +37 -20
  53. data/test/cases/rake_test_sqlserver.rb +20 -20
  54. data/test/cases/schema_dumper_test_sqlserver.rb +44 -43
  55. data/test/cases/schema_test_sqlserver.rb +2 -2
  56. data/test/cases/showplan_test_sqlserver.rb +25 -10
  57. data/test/cases/specific_schema_test_sqlserver.rb +11 -17
  58. data/test/cases/transaction_test_sqlserver.rb +9 -9
  59. data/test/cases/trigger_test_sqlserver.rb +31 -0
  60. data/test/cases/utils_test_sqlserver.rb +36 -36
  61. data/test/cases/uuid_test_sqlserver.rb +8 -8
  62. data/test/config.yml +2 -2
  63. data/test/migrations/create_clients_and_change_column_null.rb +23 -0
  64. data/test/models/sqlserver/trigger.rb +7 -0
  65. data/test/models/sqlserver/trigger_history.rb +3 -0
  66. data/test/schema/datatypes/2012.sql +1 -0
  67. data/test/schema/sqlserver_specific_schema.rb +47 -5
  68. data/test/support/core_ext/query_cache.rb +29 -0
  69. data/test/support/sql_counter_sqlserver.rb +1 -1
  70. metadata +32 -15
  71. data/RAILS5-TODO.md +0 -5
  72. data/test/models/sqlserver/dot_table_name.rb +0 -3
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -x
4
+ set -e
5
+
6
+ tag=2017-GA
7
+
8
+ docker pull metaskills/mssql-server-linux-rails:$tag
9
+
10
+ container=$(docker ps -a -q --filter ancestor=metaskills/mssql-server-linux-rails:$tag)
11
+ if [[ -z $container ]]; then
12
+ docker run -p 1433:1433 -d metaskills/mssql-server-linux-rails:$tag && sleep 10
13
+ exit
14
+ fi
15
+
16
+ container=$(docker ps -q --filter ancestor=metaskills/mssql-server-linux-rails:$tag)
17
+ if [[ -z $container ]]; then
18
+ docker start $container && sleep 10
19
+ fi
@@ -13,16 +13,17 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
13
13
  let(:basic_update_sql) { "UPDATE [customers] SET [address_street] = NULL WHERE [id] = 2" }
14
14
  let(:basic_select_sql) { "SELECT * FROM [customers] WHERE ([customers].[id] = 1)" }
15
15
 
16
- it 'has basic and non-senstive information in the adpaters inspect method' do
16
+ it 'has basic and non-sensitive information in the adapters inspect method' do
17
17
  string = connection.inspect
18
- string.must_match %r{ActiveRecord::ConnectionAdapters::SQLServerAdapter}
19
- string.must_match %r{version\: \d.\d}
20
- string.must_match %r{mode: (dblib|jdbc)}
21
- string.must_match %r{azure: (true|false)}
22
- string.wont_match %r{host}
23
- string.wont_match %r{password}
24
- string.wont_match %r{username}
25
- string.wont_match %r{port}
18
+
19
+ _(string).must_match %r{ActiveRecord::ConnectionAdapters::SQLServerAdapter}
20
+ _(string).must_match %r{version\: \d+\.\d}
21
+ _(string).must_match %r{mode: (dblib|jdbc)}
22
+ _(string).must_match %r{azure: (true|false)}
23
+ _(string).wont_match %r{host}
24
+ _(string).wont_match %r{password}
25
+ _(string).wont_match %r{username}
26
+ _(string).wont_match %r{port}
26
27
  end
27
28
 
28
29
  it 'has a 128 max #table_alias_length' do
@@ -37,10 +38,6 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
37
38
  assert_equal 'SQLServer', connection.adapter_name
38
39
  end
39
40
 
40
- it 'supports migrations' do
41
- assert connection.supports_migrations?
42
- end
43
-
44
41
  it 'support DDL in transactions' do
45
42
  assert connection.supports_ddl_transactions?
46
43
  end
@@ -145,12 +142,12 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
145
142
  end
146
143
 
147
144
  it 'return quoted table_name to #query_requires_identity_insert? when INSERT sql contains id column' do
148
- assert_equal '[funny_jokes]', connection.send(:query_requires_identity_insert?,@identity_insert_sql)
149
- assert_equal '[funny_jokes]', connection.send(:query_requires_identity_insert?,@identity_insert_sql_unquoted)
150
- assert_equal '[funny_jokes]', connection.send(:query_requires_identity_insert?,@identity_insert_sql_unordered)
151
- assert_equal '[funny_jokes]', connection.send(:query_requires_identity_insert?,@identity_insert_sql_sp)
152
- assert_equal '[funny_jokes]', connection.send(:query_requires_identity_insert?,@identity_insert_sql_unquoted_sp)
153
- assert_equal '[funny_jokes]', connection.send(:query_requires_identity_insert?,@identity_insert_sql_unordered_sp)
145
+ assert_equal 'funny_jokes', connection.send(:query_requires_identity_insert?,@identity_insert_sql)
146
+ assert_equal 'funny_jokes', connection.send(:query_requires_identity_insert?,@identity_insert_sql_unquoted)
147
+ assert_equal 'funny_jokes', connection.send(:query_requires_identity_insert?,@identity_insert_sql_unordered)
148
+ assert_equal 'funny_jokes', connection.send(:query_requires_identity_insert?,@identity_insert_sql_sp)
149
+ assert_equal 'funny_jokes', connection.send(:query_requires_identity_insert?,@identity_insert_sql_unquoted_sp)
150
+ assert_equal 'funny_jokes', connection.send(:query_requires_identity_insert?,@identity_insert_sql_unordered_sp)
154
151
  end
155
152
 
156
153
  it 'return false to #query_requires_identity_insert? for normal SQL' do
@@ -166,7 +163,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
166
163
  end
167
164
 
168
165
  it 'return an empty array when calling #identity_columns for a table_name with no identity' do
169
- connection.send(:identity_columns, Subscriber.table_name).must_equal []
166
+ _(connection.send(:identity_columns, Subscriber.table_name)).must_equal []
170
167
  end
171
168
 
172
169
  end
@@ -236,6 +233,11 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
236
233
  end
237
234
  end
238
235
 
236
+ it 'not disable referential integrity for the same table twice' do
237
+ tables = SSTestHasPk.connection.tables_with_referential_integrity
238
+ assert_equal tables.size, tables.uniq.size
239
+ end
240
+
239
241
  end
240
242
 
241
243
  describe 'database statements' do
@@ -266,23 +268,26 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
266
268
  end
267
269
 
268
270
  it 'create integers when limit is 4' do
269
- assert_equal 'integer', connection.type_to_sql(:integer, 4)
271
+ assert_equal 'integer', connection.type_to_sql(:integer, limit: 4)
270
272
  end
271
273
 
272
274
  it 'create integers when limit is 3' do
273
- assert_equal 'integer', connection.type_to_sql(:integer, 3)
275
+ assert_equal 'integer', connection.type_to_sql(:integer, limit: 3)
276
+ end
277
+
278
+ it 'create smallints when limit is 2' do
279
+ assert_equal 'smallint', connection.type_to_sql(:integer, limit: 2)
274
280
  end
275
281
 
276
- it 'create smallints when limit is less than 3' do
277
- assert_equal 'smallint', connection.type_to_sql(:integer, 2)
278
- assert_equal 'smallint', connection.type_to_sql(:integer, 1)
282
+ it 'create tinyints when limit is 1' do
283
+ assert_equal 'tinyint', connection.type_to_sql(:integer, limit: 1)
279
284
  end
280
285
 
281
286
  it 'create bigints when limit is greateer than 4' do
282
- assert_equal 'bigint', connection.type_to_sql(:integer, 5)
283
- assert_equal 'bigint', connection.type_to_sql(:integer, 6)
284
- assert_equal 'bigint', connection.type_to_sql(:integer, 7)
285
- assert_equal 'bigint', connection.type_to_sql(:integer, 8)
287
+ assert_equal 'bigint', connection.type_to_sql(:integer, limit: 5)
288
+ assert_equal 'bigint', connection.type_to_sql(:integer, limit: 6)
289
+ assert_equal 'bigint', connection.type_to_sql(:integer, limit: 7)
290
+ assert_equal 'bigint', connection.type_to_sql(:integer, limit: 8)
286
291
  end
287
292
 
288
293
  it 'create floats when no limit supplied' do
@@ -300,7 +305,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
300
305
  end
301
306
 
302
307
  it 'find SSTestCustomersView table name' do
303
- connection.views.must_include 'sst_customers_view'
308
+ _(connection.views).must_include 'sst_customers_view'
304
309
  end
305
310
 
306
311
  it 'work with dynamic finders' do
@@ -341,9 +346,9 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
341
346
  end
342
347
 
343
348
  it 'find identity column' do
344
- SSTestCustomersView.primary_key.must_equal 'id'
345
- connection.primary_key(SSTestCustomersView.table_name).must_equal 'id'
346
- SSTestCustomersView.columns_hash['id'].must_be :is_identity?
349
+ _(SSTestCustomersView.primary_key).must_equal 'id'
350
+ _(connection.primary_key(SSTestCustomersView.table_name)).must_equal 'id'
351
+ _(SSTestCustomersView.columns_hash['id']).must_be :is_identity?
347
352
  end
348
353
 
349
354
  it 'find default values' do
@@ -368,9 +373,9 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
368
373
  end
369
374
 
370
375
  it 'find identity column' do
371
- SSTestStringDefaultsView.primary_key.must_equal 'id'
372
- connection.primary_key(SSTestStringDefaultsView.table_name).must_equal 'id'
373
- SSTestStringDefaultsView.columns_hash['id'].must_be :is_identity?
376
+ _(SSTestStringDefaultsView.primary_key).must_equal 'id'
377
+ _(connection.primary_key(SSTestStringDefaultsView.table_name)).must_equal 'id'
378
+ _(SSTestStringDefaultsView.columns_hash['id']).must_be :is_identity?
374
379
  end
375
380
 
376
381
  it 'find default values' do
@@ -419,12 +424,11 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
419
424
 
420
425
  it 'in_memory_oltp' do
421
426
  if ENV['IN_MEMORY_OLTP'] && connection.supports_in_memory_oltp?
422
- SSTMemory.primary_key.must_equal 'id'
423
- SSTMemory.columns_hash['id'].must_be :is_identity?
427
+ _(SSTMemory.primary_key).must_equal 'id'
428
+ _(SSTMemory.columns_hash['id']).must_be :is_identity?
424
429
  else
425
430
  skip 'supports_in_memory_oltp? => false'
426
431
  end
427
432
  end
428
433
 
429
434
  end
430
-
@@ -0,0 +1,42 @@
1
+ require 'cases/helper_sqlserver'
2
+ require 'migrations/create_clients_and_change_column_null'
3
+
4
+ class ChangeColumnNullTestSqlServer < ActiveRecord::TestCase
5
+ before do
6
+ @old_verbose = ActiveRecord::Migration.verbose
7
+ ActiveRecord::Migration.verbose = false
8
+ CreateClientsAndChangeColumnNull.new.up
9
+ end
10
+
11
+ after do
12
+ CreateClientsAndChangeColumnNull.new.down
13
+ ActiveRecord::Migration.verbose = @old_verbose
14
+ end
15
+
16
+ def find_column(table, name)
17
+ table.find { |column| column.name == name }
18
+ end
19
+
20
+ let(:clients_table) { connection.columns('clients') }
21
+ let(:name_column) { find_column(clients_table, 'name') }
22
+ let(:code_column) { find_column(clients_table, 'code') }
23
+ let(:value_column) { find_column(clients_table, 'value') }
24
+
25
+ describe '#change_column_null' do
26
+ it 'does not change the column limit' do
27
+ _(name_column.limit).must_equal 15
28
+ end
29
+
30
+ it 'does not change the column default' do
31
+ _(code_column.default).must_equal 'n/a'
32
+ end
33
+
34
+ it 'does not change the column precision' do
35
+ _(value_column.precision).must_equal 32
36
+ end
37
+
38
+ it 'does not change the column scale' do
39
+ _(value_column.scale).must_equal 8
40
+ end
41
+ end
42
+ end
@@ -31,6 +31,10 @@ end
31
31
  require 'models/event'
32
32
  module ActiveRecord
33
33
  class AdapterTest < ActiveRecord::TestCase
34
+ # I really dont think we can support legacy binds.
35
+ coerce_tests! :test_select_all_with_legacy_binds
36
+ coerce_tests! :test_insert_update_delete_with_legacy_binds
37
+
34
38
  # As far as I can tell, SQL Server does not support null bytes in strings.
35
39
  coerce_tests! :test_update_prepared_statement
36
40
  coerce_tests! :test_log_invalid_encoding if defined? JRUBY_VERSION # JRuby just happily converts the encoding
@@ -53,14 +57,14 @@ end
53
57
 
54
58
  require 'models/topic'
55
59
  class AttributeMethodsTest < ActiveRecord::TestCase
56
- coerce_tests! :test_typecast_attribute_from_select_to_false
60
+ coerce_tests! %r{typecast attribute from select to false}
57
61
  def test_typecast_attribute_from_select_to_false_coerced
58
62
  Topic.create(:title => 'Budget')
59
63
  topic = Topic.all.merge!(:select => "topics.*, IIF (1 = 2, 1, 0) as is_test").first
60
64
  assert !topic.is_test?
61
65
  end
62
66
 
63
- coerce_tests! :test_typecast_attribute_from_select_to_true
67
+ coerce_tests! %r{typecast attribute from select to true}
64
68
  def test_typecast_attribute_from_select_to_true_coerced
65
69
  Topic.create(:title => 'Budget')
66
70
  topic = Topic.all.merge!(:select => "topics.*, IIF (1 = 1, 1, 0) as is_test").first
@@ -69,7 +73,11 @@ class AttributeMethodsTest < ActiveRecord::TestCase
69
73
  end
70
74
 
71
75
 
72
-
76
+ class NumericDataTest < ActiveRecord::TestCase
77
+ # We do not have do the DecimalWithoutScale type.
78
+ coerce_tests! :test_numeric_fields
79
+ coerce_tests! :test_numeric_fields_with_scale
80
+ end
73
81
 
74
82
  class BasicsTest < ActiveRecord::TestCase
75
83
  coerce_tests! :test_column_names_are_escaped
@@ -78,16 +86,44 @@ class BasicsTest < ActiveRecord::TestCase
78
86
  assert_equal '[t]]]', conn.quote_column_name('t]')
79
87
  end
80
88
 
81
- # We do not have do the DecimalWithoutScale type.
82
- coerce_tests! :test_numeric_fields
83
- coerce_tests! :test_numeric_fields_with_scale
84
-
85
89
  # Just like PostgreSQLAdapter does.
86
90
  coerce_tests! :test_respect_internal_encoding
87
91
 
88
92
  # Caused in Rails v4.2.5 by adding `firm_id` column in this http://git.io/vBfMs
89
93
  # commit. Trust Rails has this covered.
90
94
  coerce_tests! :test_find_keeps_multiple_group_values
95
+
96
+ def test_update_date_time_attributes
97
+ Time.use_zone("Eastern Time (US & Canada)") do
98
+ topic = Topic.find(1)
99
+ time = Time.zone.parse("2017-07-17 10:56")
100
+ topic.update_attributes!(written_on: time)
101
+ assert_equal(time, topic.written_on)
102
+ end
103
+ end
104
+
105
+ def test_update_date_time_attributes_with_default_timezone_local
106
+ with_env_tz 'America/New_York' do
107
+ with_timezone_config default: :local do
108
+ Time.use_zone("Eastern Time (US & Canada)") do
109
+ topic = Topic.find(1)
110
+ time = Time.zone.parse("2017-07-17 10:56")
111
+ topic.update_attributes!(written_on: time)
112
+ assert_equal(time, topic.written_on)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ # Need to escape `quoted_id` once it contains brackets
119
+ coerce_tests! %r{column names are quoted when using #from clause and model has ignored columns}
120
+ test "column names are quoted when using #from clause and model has ignored columns coerced" do
121
+ refute_empty Developer.ignored_columns
122
+ query = Developer.from("developers").to_sql
123
+ quoted_id = "#{Developer.quoted_table_name}.#{Developer.quoted_primary_key}"
124
+
125
+ assert_match(/SELECT #{Regexp.escape(quoted_id)}.* FROM developers/, query)
126
+ end
91
127
  end
92
128
 
93
129
 
@@ -108,17 +144,63 @@ end
108
144
 
109
145
 
110
146
 
147
+ # module ActiveRecord
148
+ # class BindParameterTest < ActiveRecord::TestCase
149
+ # # Same as original coerced test except log is found using `EXEC sp_executesql` wrapper.
150
+ # # coerce_tests! :test_binds_are_logged
151
+ # # def test_binds_are_logged_coerced
152
+ # # sub = Arel::Nodes::BindParam.new(1)
153
+ # # binds = [Relation::QueryAttribute.new("id", 1, Type::Value.new)]
154
+ # # sql = "select * from topics where id = #{sub.to_sql}"
155
+ # #
156
+ # # @connection.exec_query(sql, "SQL", binds)
157
+ # #
158
+ # # logged_sql = "EXEC sp_executesql N'#{sql}', N'#{sub.to_sql} int', #{sub.to_sql} = 1"
159
+ # # message = @subscriber.calls.find { |args| args[4][:sql] == logged_sql }
160
+ # #
161
+ # # assert_equal binds, message[4][:binds]
162
+ # # end
163
+ # #
164
+ # # # SQL Server adapter does not use a statement cache as query plans are already reused using `EXEC sp_executesql`.
165
+ # # coerce_tests! :test_statement_cache
166
+ # # coerce_tests! :test_statement_cache_with_query_cache
167
+ # # coerce_tests! :test_statement_cache_with_find_by
168
+ # # coerce_tests! :test_statement_cache_with_in_clause
169
+ # # coerce_tests! :test_statement_cache_with_sql_string_literal
170
+ # end
171
+ # end
172
+
173
+
111
174
  module ActiveRecord
112
- class BindParameterTest < ActiveRecord::TestCase
113
- # Never finds `sql` since we use `EXEC sp_executesql` wrappers.
114
- coerce_tests! :test_binds_are_logged
175
+ class InstrumentationTest < ActiveRecord::TestCase
176
+ # This fails randomly due to schema cache being lost?
177
+ coerce_tests! :test_payload_name_on_load
178
+ def test_payload_name_on_load_coerced
179
+ Book.create(name: "test book")
180
+ Book.first
181
+ subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |*args|
182
+ event = ActiveSupport::Notifications::Event.new(*args)
183
+ if event.payload[:sql].match "SELECT"
184
+ assert_equal "Book Load", event.payload[:name]
185
+ end
186
+ end
187
+ Book.first
188
+ ensure
189
+ ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
190
+ end
115
191
  end
116
192
  end
117
193
 
118
-
119
-
120
-
121
194
  class CalculationsTest < ActiveRecord::TestCase
195
+ # This fails randomly due to schema cache being lost?
196
+ coerce_tests! :test_offset_is_kept
197
+ def test_offset_is_kept_coerced
198
+ Account.first
199
+ queries = assert_sql { Account.offset(1).count }
200
+ assert_equal 1, queries.length
201
+ assert_match(/OFFSET/, queries.first)
202
+ end
203
+
122
204
  # Are decimal, not integer.
123
205
  coerce_tests! :test_should_return_decimal_average_of_integer_field
124
206
  def test_should_return_decimal_average_of_integer_field_coerced
@@ -130,28 +212,36 @@ class CalculationsTest < ActiveRecord::TestCase
130
212
  def test_limit_is_kept_coerced
131
213
  queries = capture_sql_ss { Account.limit(1).count }
132
214
  assert_equal 1, queries.length
133
- queries.first.must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1}
215
+ _(queries.first).must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1}
134
216
  end unless defined? JRUBY_VERSION
135
217
 
136
218
  def test_limit_is_kept_coerced
137
219
  queries = capture_sql_ss { Account.limit(1).count }
138
220
  assert_equal 1, queries.length
139
- queries.first.must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT \? ROWS ONLY}
221
+ _(queries.first).must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT \? ROWS ONLY}
140
222
  end if defined? JRUBY_VERSION
141
223
 
142
224
  coerce_tests! :test_limit_with_offset_is_kept
143
225
  def test_limit_with_offset_is_kept_coerced
144
226
  queries = capture_sql_ss { Account.limit(1).offset(1).count }
145
227
  assert_equal 1, queries.length
146
- queries.first.must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY.*@0 = 1, @1 = 1}
228
+ _(queries.first).must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY.*@0 = 1, @1 = 1}
147
229
  end unless defined? JRUBY_VERSION
148
230
 
149
231
  def test_limit_with_offset_is_kept_coerced
150
232
  queries = capture_sql_ss { Account.limit(1).offset(1).count }
151
233
  assert_equal 1, queries.length
152
- queries.first.must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET \? ROWS FETCH NEXT \? ROWS ONLY}
234
+ _(queries.first).must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET \? ROWS FETCH NEXT \? ROWS ONLY}
153
235
  end if defined? JRUBY_VERSION
154
236
 
237
+ # SQL Server needs an alias for the calculated column
238
+ coerce_tests! :test_distinct_count_all_with_custom_select_and_order
239
+ def test_distinct_count_all_with_custom_select_and_order_coerced
240
+ accounts = Account.distinct.select("credit_limit % 10 AS the_limit").order(Arel.sql("credit_limit % 10"))
241
+ assert_queries(1) { assert_equal 3, accounts.count(:all) }
242
+ assert_queries(1) { assert_equal 3, accounts.load.size }
243
+ end
244
+
155
245
  # Leave it up to users to format selects/functions so HAVING works correctly.
156
246
  coerce_tests! :test_having_with_strong_parameters
157
247
  end
@@ -165,6 +255,7 @@ module ActiveRecord
165
255
  coerce_tests! :test_create_table_with_bigint,
166
256
  :test_create_table_with_defaults
167
257
  end
258
+
168
259
  class ChangeSchemaWithDependentObjectsTest < ActiveRecord::TestCase
169
260
  # In SQL Server you have to delete the tables yourself in the right order.
170
261
  coerce_tests! :test_create_table_with_force_cascade_drops_dependent_objects
@@ -174,6 +265,29 @@ end
174
265
 
175
266
 
176
267
 
268
+ module ActiveRecord
269
+ module ConnectionAdapters
270
+ class QuoteARBaseTest < ActiveRecord::TestCase
271
+
272
+ # Use our date format.
273
+ coerce_tests! :test_quote_ar_object
274
+ def test_quote_ar_object_coerced
275
+ value = DatetimePrimaryKey.new(id: @time)
276
+ assert_equal "'02-14-2017 12:34:56.789'", @connection.quote(value)
277
+ end
278
+
279
+ # Use our date format.
280
+ coerce_tests! :test_type_cast_ar_object
281
+ def test_type_cast_ar_object_coerced
282
+ value = DatetimePrimaryKey.new(id: @time)
283
+ assert_equal "02-14-2017 12:34:56.789", @connection.type_cast(value)
284
+ end
285
+
286
+ end
287
+ end
288
+ end
289
+
290
+
177
291
 
178
292
  module ActiveRecord
179
293
  class Migration
@@ -183,7 +297,7 @@ module ActiveRecord
183
297
  def test_add_column_without_limit_coerced
184
298
  add_column :test_models, :description, :string, limit: nil
185
299
  TestModel.reset_column_information
186
- TestModel.columns_hash["description"].limit.must_equal 4000
300
+ _(TestModel.columns_hash["description"].limit).must_equal 4000
187
301
  end
188
302
  end
189
303
  end
@@ -269,7 +383,7 @@ class MigrationTest < ActiveRecord::TestCase
269
383
  end
270
384
 
271
385
  # For some reason our tests set Rails.@_env which breaks test env switching.
272
- coerce_tests! :test_migration_sets_internal_metadata_even_when_fully_migrated
386
+ coerce_tests! :test_internal_metadata_stores_environment_when_other_data_exists
273
387
  coerce_tests! :test_internal_metadata_stores_environment
274
388
  end
275
389
 
@@ -295,6 +409,7 @@ module ActiveRecord
295
409
  # a value of 'default_env' will still show tests failing. Just ignoring all
296
410
  # of them since we have no monkey in this circus.
297
411
  MergeAndResolveDefaultUrlConfigTest.coerce_all_tests! if defined?(MergeAndResolveDefaultUrlConfigTest)
412
+ ConnectionHandlerTest.coerce_all_tests! if defined?(ConnectionHandlerTest)
298
413
  end
299
414
  end
300
415
 
@@ -302,6 +417,10 @@ end
302
417
 
303
418
 
304
419
  module ActiveRecord
420
+ class DatabaseTasksDumpSchemaCacheTest < ActiveRecord::TestCase
421
+ # Skip this test with /tmp/my_schema_cache.yml path on Windows.
422
+ coerce_tests! :test_dump_schema_cache if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
423
+ end
305
424
  class DatabaseTasksCreateAllTest < ActiveRecord::TestCase
306
425
  # We extend `local_database?` so that common VM IPs can be used.
307
426
  coerce_tests! :test_ignores_remote_databases, :test_warning_for_remote_databases
@@ -395,12 +514,6 @@ class FinderTest < ActiveRecord::TestCase
395
514
  end
396
515
  end if defined? JRUBY_VERSION
397
516
 
398
- coerce_tests! :test_string_sanitation
399
- def test_string_sanitation_coerced
400
- assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
401
- assert_equal "N'something; select table'", ActiveRecord::Base.sanitize("something; select table")
402
- end
403
-
404
517
  coerce_tests! :test_take_and_first_and_last_with_integer_should_use_sql_limit
405
518
  def test_take_and_first_and_last_with_integer_should_use_sql_limit_coerced
406
519
  assert_sql(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.* @0 = 3/) { Topic.take(3).entries }
@@ -485,7 +598,7 @@ class InheritanceTest < ActiveRecord::TestCase
485
598
  coerce_tests! :test_eager_load_belongs_to_primary_key_quoting
486
599
  def test_eager_load_belongs_to_primary_key_quoting_coerced
487
600
  con = Account.connection
488
- assert_sql(/\[companies\]\.\[id\] = 1/) do
601
+ assert_sql(/\[companies\]\.\[id\] = \?/) do
489
602
  Account.all.merge!(:includes => :firm).find(1)
490
603
  end
491
604
  end
@@ -538,6 +651,7 @@ end
538
651
 
539
652
 
540
653
 
654
+ require 'models/parrot'
541
655
  require 'models/topic'
542
656
  class PersistenceTest < ActiveRecord::TestCase
543
657
  # We can not UPDATE identity columns.
@@ -547,14 +661,14 @@ class PersistenceTest < ActiveRecord::TestCase
547
661
  coerce_tests! :test_update_all_doesnt_ignore_order
548
662
  def test_update_all_doesnt_ignore_order_coerced
549
663
  david, mary = authors(:david), authors(:mary)
550
- david.id.must_equal 1
551
- mary.id.must_equal 2
552
- david.name.wont_equal mary.name
664
+ _(david.id).must_equal 1
665
+ _(mary.id).must_equal 2
666
+ _(david.name).wont_equal mary.name
553
667
  assert_sql(/UPDATE.*\(SELECT \[authors\].\[id\] FROM \[authors\].*ORDER BY \[authors\].\[id\]/i) do
554
668
  Author.where('[id] > 1').order(:id).update_all(name: 'Test')
555
669
  end
556
- david.reload.name.must_equal 'David'
557
- mary.reload.name.must_equal 'Test'
670
+ _(david.reload.name).must_equal 'David'
671
+ _(mary.reload.name).must_equal 'Test'
558
672
  end
559
673
 
560
674
  # We can not UPDATE identity columns.
@@ -580,6 +694,19 @@ class PersistenceTest < ActiveRecord::TestCase
580
694
  # assert_nothing_raised { topic.reload }
581
695
  # assert_equal topic.title, Topic.find(1234).title
582
696
  end
697
+
698
+ coerce_tests! :test_delete_new_record
699
+ def test_delete_new_record_coerced
700
+ client = Client.new(name: "37signals")
701
+ client.delete
702
+ assert_predicate client, :frozen?
703
+
704
+ assert_not client.save
705
+ assert_raise(ActiveRecord::RecordNotSaved) { client.save! }
706
+
707
+ assert_predicate client, :frozen?
708
+ assert_raise(FrozenError) { client.name = "something else" } # For some reason we get a FrozenError instead of a RuntimeError here
709
+ end
583
710
  end
584
711
 
585
712
 
@@ -603,10 +730,19 @@ end
603
730
 
604
731
 
605
732
 
733
+ class PrimaryKeysTest < ActiveRecord::TestCase
734
+ # Gonna trust Rails core for this. We end up with 2 querys vs 3 asserted
735
+ # but as far as I can tell, this is only one for us anyway.
736
+ coerce_tests! :test_create_without_primary_key_no_extra_query
737
+ end
738
+
739
+
740
+
741
+
606
742
  require 'models/task'
607
743
  class QueryCacheTest < ActiveRecord::TestCase
608
- coerce_tests! :test_cache_does_not_wrap_string_results_in_arrays
609
- def test_cache_does_not_wrap_string_results_in_arrays_coerced
744
+ coerce_tests! :test_cache_does_not_wrap_results_in_arrays
745
+ def test_cache_does_not_wrap_results_in_arrays_coerced
610
746
  Task.cache do
611
747
  assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
612
748
  end
@@ -621,16 +757,16 @@ class RelationTest < ActiveRecord::TestCase
621
757
  # Use LEN vs LENGTH function.
622
758
  coerce_tests! :test_reverse_order_with_function
623
759
  def test_reverse_order_with_function_coerced
624
- topics = Topic.order("LEN(title)").reverse_order
760
+ topics = Topic.order(Arel.sql("LEN(title)")).reverse_order
625
761
  assert_equal topics(:second).title, topics.first.title
626
762
  end
627
763
 
628
764
  # Use LEN vs LENGTH function.
629
765
  coerce_tests! :test_reverse_order_with_function_other_predicates
630
766
  def test_reverse_order_with_function_other_predicates_coerced
631
- topics = Topic.order("author_name, LEN(title), id").reverse_order
767
+ topics = Topic.order(Arel.sql("author_name, LEN(title), id")).reverse_order
632
768
  assert_equal topics(:second).title, topics.first.title
633
- topics = Topic.order("LEN(author_name), id, LEN(title)").reverse_order
769
+ topics = Topic.order(Arel.sql("LEN(author_name), id, LEN(title)")).reverse_order
634
770
  assert_equal topics(:fifth).title, topics.first.title
635
771
  end
636
772
 
@@ -646,6 +782,60 @@ class RelationTest < ActiveRecord::TestCase
646
782
  # Leave it up to users to format selects/functions so HAVING works correctly.
647
783
  coerce_tests! :test_multiple_where_and_having_clauses
648
784
  coerce_tests! :test_having_with_binds_for_both_where_and_having
785
+
786
+ # Find any limit via our expression.
787
+ coerce_tests! %r{relations don't load all records in #inspect}
788
+ def test_relations_dont_load_all_records_in_inspect_coerced
789
+ assert_sql(/NEXT \? ROWS ONLY/) do
790
+ Post.all.inspect
791
+ end
792
+ end
793
+
794
+ # I wanted to add `.order("author_id")` scope to avoid error: Column "posts.id" is invalid in the ORDER BY
795
+ # However, this pull request on Rails core drops order on exists relation. https://github.com/rails/rails/pull/28699
796
+ # so we are skipping all together.
797
+ coerce_tests! :test_empty_complex_chained_relations
798
+
799
+ # Can't apply offset withour ORDER
800
+ coerce_tests! %r{using a custom table affects the wheres}
801
+ test 'using a custom table affects the wheres coerced' do
802
+ post = posts(:welcome)
803
+
804
+ assert_equal post, custom_post_relation.where!(title: post.title).order(:id).take
805
+ end
806
+
807
+ # Can't apply offset withour ORDER
808
+ coerce_tests! %r{using a custom table with joins affects the joins}
809
+ test 'using a custom table with joins affects the joins coerced' do
810
+ post = posts(:welcome)
811
+
812
+ assert_equal post, custom_post_relation.joins(:author).where!(title: post.title).order(:id).take
813
+ end
814
+
815
+ # Use LEN() vs length() function.
816
+ coerce_tests! :test_reverse_arel_assoc_order_with_function
817
+ def test_reverse_arel_assoc_order_with_function_coerced
818
+ topics = Topic.order(Arel.sql("LEN(title)") => :asc).reverse_order
819
+ assert_equal topics(:second).title, topics.first.title
820
+ end
821
+ end
822
+
823
+ class ActiveRecord::RelationTest < ActiveRecord::TestCase
824
+ coerce_tests! :test_relation_merging_with_merged_symbol_joins_is_aliased
825
+ def test_relation_merging_with_merged_symbol_joins_is_aliased__coerced
826
+ categorizations_with_authors = Categorization.joins(:author)
827
+ queries = capture_sql { Post.joins(:author, :categorizations).merge(Author.select(:id)).merge(categorizations_with_authors).to_a }
828
+
829
+ nb_inner_join = queries.sum { |sql| sql.scan(/INNER\s+JOIN/i).size }
830
+ assert_equal 3, nb_inner_join, "Wrong amount of INNER JOIN in query"
831
+
832
+ # using `\W` as the column separator
833
+ query_matches = queries.any? do |sql|
834
+ %r[INNER\s+JOIN\s+#{Regexp.escape(Author.quoted_table_name)}\s+\Wauthors_categorizations\W]i.match?(sql)
835
+ end
836
+
837
+ assert query_matches, "Should be aliasing the child INNER JOINs in query"
838
+ end
649
839
  end
650
840
 
651
841
 
@@ -677,9 +867,6 @@ class SchemaDumperTest < ActiveRecord::TestCase
677
867
  assert_match %r{t.decimal\s+"atoms_in_universe",\s+precision: 38}, output
678
868
  end
679
869
 
680
- # This accidently returns the wrong number because of our tables too.
681
- coerce_tests! :test_types_line_up
682
-
683
870
  # This is a poorly written test and really does not catch the bottom'ness it is meant too. Ours throw it off.
684
871
  coerce_tests! :test_foreign_keys_are_dumped_at_the_bottom_to_circumvent_dependency_issues
685
872
 
@@ -803,10 +990,55 @@ class DateTimePrecisionTest < ActiveRecord::TestCase
803
990
  end
804
991
  end
805
992
  end
993
+
994
+ unless defined? JRUBY_VERSION
995
+ # datetime is rounded to increments of .000, .003, or .007 seconds
996
+ coerce_tests! :test_datetime_precision_is_truncated_on_assignment
997
+ def test_datetime_precision_is_truncated_on_assignment_coerced
998
+ @connection.create_table(:foos, force: true)
999
+ @connection.add_column :foos, :created_at, :datetime, precision: 0
1000
+ @connection.add_column :foos, :updated_at, :datetime, precision: 6
1001
+
1002
+ time = ::Time.now.change(nsec: 123456789)
1003
+ foo = Foo.new(created_at: time, updated_at: time)
1004
+
1005
+ assert_equal 0, foo.created_at.nsec
1006
+ assert_equal 123457000, foo.updated_at.nsec
1007
+
1008
+ foo.save!
1009
+ foo.reload
1010
+
1011
+ assert_equal 0, foo.created_at.nsec
1012
+ assert_equal 123457000, foo.updated_at.nsec
1013
+ end
1014
+ end
806
1015
  end
807
1016
 
808
1017
 
809
1018
 
1019
+ class TimePrecisionTest < ActiveRecord::TestCase
1020
+ # datetime is rounded to increments of .000, .003, or .007 seconds
1021
+ coerce_tests! :test_time_precision_is_truncated_on_assignment
1022
+ def test_time_precision_is_truncated_on_assignment_coerced
1023
+ @connection.create_table(:foos, force: true)
1024
+ @connection.add_column :foos, :start, :time, precision: 0
1025
+ @connection.add_column :foos, :finish, :time, precision: 6
1026
+
1027
+ time = ::Time.now.change(nsec: 123456789)
1028
+ foo = Foo.new(start: time, finish: time)
1029
+
1030
+ assert_equal 0, foo.start.nsec
1031
+ assert_equal 123457000, foo.finish.nsec
1032
+
1033
+ foo.save!
1034
+ foo.reload
1035
+
1036
+ assert_equal 0, foo.start.nsec
1037
+ assert_equal 123457000, foo.finish.nsec
1038
+ end
1039
+ end unless defined? JRUBY_VERSION
1040
+
1041
+
810
1042
 
811
1043
  class DefaultNumbersTest < ActiveRecord::TestCase
812
1044
  # We do better with native types and do not return strings for everything.
@@ -843,3 +1075,151 @@ module ActiveRecord
843
1075
  #coerce_tests! :test_find_does_not_use_statement_cache_if_table_name_is_changed
844
1076
  end
845
1077
  end
1078
+
1079
+
1080
+
1081
+
1082
+ module ActiveRecord
1083
+ module ConnectionAdapters
1084
+ class SchemaCacheTest < ActiveRecord::TestCase
1085
+ private
1086
+ # We need to give the full path for this to work.
1087
+ def schema_dump_path
1088
+ File.join ARTest::SQLServer.root_activerecord, 'test/assets/schema_dump_5_1.yml'
1089
+ end
1090
+ end
1091
+ end
1092
+ end
1093
+
1094
+ class UnsafeRawSqlTest < ActiveRecord::TestCase
1095
+ coerce_tests! %r{always allows Arel}
1096
+ test 'order: always allows Arel' do
1097
+ ids_depr = with_unsafe_raw_sql_deprecated { Post.order(Arel.sql("len(title)")).pluck(:title) }
1098
+ ids_disabled = with_unsafe_raw_sql_disabled { Post.order(Arel.sql("len(title)")).pluck(:title) }
1099
+
1100
+ assert_equal ids_depr, ids_disabled
1101
+ end
1102
+
1103
+ test "pluck: always allows Arel" do
1104
+ values_depr = with_unsafe_raw_sql_deprecated { Post.includes(:comments).pluck(:title, Arel.sql("len(title)")) }
1105
+ values_disabled = with_unsafe_raw_sql_disabled { Post.includes(:comments).pluck(:title, Arel.sql("len(title)")) }
1106
+
1107
+ assert_equal values_depr, values_disabled
1108
+ end
1109
+
1110
+
1111
+ coerce_tests! %r{order: disallows invalid Array arguments}
1112
+ test "order: disallows invalid Array arguments" do
1113
+ with_unsafe_raw_sql_disabled do
1114
+ assert_raises(ActiveRecord::UnknownAttributeReference) do
1115
+ Post.order(["author_id", "len(title)"]).pluck(:id)
1116
+ end
1117
+ end
1118
+ end
1119
+
1120
+ coerce_tests! %r{order: allows valid Array arguments}
1121
+ test "order: allows valid Array arguments" do
1122
+ ids_expected = Post.order(Arel.sql("author_id, len(title)")).pluck(:id)
1123
+
1124
+ ids_depr = with_unsafe_raw_sql_deprecated { Post.order(["author_id", Arel.sql("len(title)")]).pluck(:id) }
1125
+ ids_disabled = with_unsafe_raw_sql_disabled { Post.order(["author_id", Arel.sql("len(title)")]).pluck(:id) }
1126
+
1127
+ assert_equal ids_expected, ids_depr
1128
+ assert_equal ids_expected, ids_disabled
1129
+ end
1130
+
1131
+ coerce_tests! %r{order: logs deprecation warning for unrecognized column}
1132
+ test "order: logs deprecation warning for unrecognized column" do
1133
+ with_unsafe_raw_sql_deprecated do
1134
+ assert_deprecated(/Dangerous query method/) do
1135
+ Post.order("len(title)")
1136
+ end
1137
+ end
1138
+ end
1139
+
1140
+ coerce_tests! %r{pluck: disallows invalid column name}
1141
+ test "pluck: disallows invalid column name" do
1142
+ with_unsafe_raw_sql_disabled do
1143
+ assert_raises(ActiveRecord::UnknownAttributeReference) do
1144
+ Post.pluck("len(title)")
1145
+ end
1146
+ end
1147
+ end
1148
+
1149
+ coerce_tests! %r{pluck: disallows invalid column name amongst valid names}
1150
+ test "pluck: disallows invalid column name amongst valid names" do
1151
+ with_unsafe_raw_sql_disabled do
1152
+ assert_raises(ActiveRecord::UnknownAttributeReference) do
1153
+ Post.pluck(:title, "len(title)")
1154
+ end
1155
+ end
1156
+ end
1157
+
1158
+ coerce_tests! %r{pluck: disallows invalid column names with includes}
1159
+ test "pluck: disallows invalid column names with includes" do
1160
+ with_unsafe_raw_sql_disabled do
1161
+ assert_raises(ActiveRecord::UnknownAttributeReference) do
1162
+ Post.includes(:comments).pluck(:title, "len(title)")
1163
+ end
1164
+ end
1165
+ end
1166
+
1167
+ coerce_tests! %r{pluck: logs deprecation warning}
1168
+ test "pluck: logs deprecation warning" do
1169
+ with_unsafe_raw_sql_deprecated do
1170
+ assert_deprecated(/Dangerous query method/) do
1171
+ Post.includes(:comments).pluck(:title, "len(title)")
1172
+ end
1173
+ end
1174
+ end
1175
+ end
1176
+
1177
+
1178
+ class ReservedWordTest < ActiveRecord::TestCase
1179
+ coerce_tests! :test_change_columns
1180
+ def test_change_columns_coerced
1181
+ assert_nothing_raised { @connection.change_column_default(:group, :order, "whatever") }
1182
+ assert_nothing_raised { @connection.change_column("group", "order", :text) }
1183
+ assert_nothing_raised { @connection.change_column_null("group", "order", true) }
1184
+ assert_nothing_raised { @connection.rename_column(:group, :order, :values) }
1185
+ end
1186
+ end
1187
+
1188
+
1189
+
1190
+ class OptimisticLockingTest < ActiveRecord::TestCase
1191
+ # We do not allow updating identities, but we can test using a non-identity key
1192
+ coerce_tests! :test_update_with_dirty_primary_key
1193
+ def test_update_with_dirty_primary_key_coerced
1194
+ assert_raises(ActiveRecord::RecordNotUnique) do
1195
+ record = StringKeyObject.find('record1')
1196
+ record.id = 'record2'
1197
+ record.save!
1198
+ end
1199
+
1200
+ record = StringKeyObject.find('record1')
1201
+ record.id = 'record42'
1202
+ record.save!
1203
+
1204
+ assert StringKeyObject.find('record42')
1205
+ assert_raises(ActiveRecord::RecordNotFound) do
1206
+ StringKeyObject.find('record1')
1207
+ end
1208
+ end
1209
+ end
1210
+
1211
+
1212
+
1213
+ class RelationMergingTest < ActiveRecord::TestCase
1214
+ coerce_tests! :test_merging_with_order_with_binds
1215
+ def test_merging_with_order_with_binds_coerced
1216
+ relation = Post.all.merge(Post.order([Arel.sql("title LIKE ?"), "%suffix"]))
1217
+ assert_equal ["title LIKE N'%suffix'"], relation.order_values
1218
+ end
1219
+ end
1220
+
1221
+
1222
+ class EagerLoadingTooManyIdsTest < ActiveRecord::TestCase
1223
+ # Temporarily coerce this test due to https://github.com/rails/rails/issues/34945
1224
+ coerce_tests! :test_eager_loading_too_may_ids
1225
+ end