activerecord 6.0.0 → 6.1.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (270) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1178 -600
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/active_record/aggregations.rb +5 -6
  6. data/lib/active_record/association_relation.rb +30 -10
  7. data/lib/active_record/associations/alias_tracker.rb +19 -16
  8. data/lib/active_record/associations/association.rb +55 -29
  9. data/lib/active_record/associations/association_scope.rb +19 -15
  10. data/lib/active_record/associations/belongs_to_association.rb +23 -10
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
  12. data/lib/active_record/associations/builder/association.rb +32 -5
  13. data/lib/active_record/associations/builder/belongs_to.rb +10 -7
  14. data/lib/active_record/associations/builder/collection_association.rb +5 -4
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -3
  16. data/lib/active_record/associations/builder/has_many.rb +6 -2
  17. data/lib/active_record/associations/builder/has_one.rb +11 -14
  18. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  19. data/lib/active_record/associations/collection_association.rb +25 -8
  20. data/lib/active_record/associations/collection_proxy.rb +14 -7
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -3
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -4
  24. data/lib/active_record/associations/has_one_association.rb +15 -1
  25. data/lib/active_record/associations/join_dependency/join_association.rb +39 -16
  26. data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
  27. data/lib/active_record/associations/join_dependency.rb +77 -42
  28. data/lib/active_record/associations/preloader/association.rb +51 -25
  29. data/lib/active_record/associations/preloader/through_association.rb +2 -2
  30. data/lib/active_record/associations/preloader.rb +13 -8
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations/through_association.rb +1 -1
  33. data/lib/active_record/associations.rb +120 -13
  34. data/lib/active_record/attribute_assignment.rb +10 -9
  35. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
  36. data/lib/active_record/attribute_methods/dirty.rb +3 -13
  37. data/lib/active_record/attribute_methods/primary_key.rb +6 -4
  38. data/lib/active_record/attribute_methods/query.rb +3 -6
  39. data/lib/active_record/attribute_methods/read.rb +8 -12
  40. data/lib/active_record/attribute_methods/serialization.rb +11 -6
  41. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  42. data/lib/active_record/attribute_methods/write.rb +12 -21
  43. data/lib/active_record/attribute_methods.rb +64 -54
  44. data/lib/active_record/attributes.rb +33 -9
  45. data/lib/active_record/autosave_association.rb +63 -44
  46. data/lib/active_record/base.rb +2 -14
  47. data/lib/active_record/callbacks.rb +153 -24
  48. data/lib/active_record/coders/yaml_column.rb +12 -3
  49. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
  50. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  51. data/lib/active_record/connection_adapters/abstract/database_statements.rb +87 -38
  52. data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -10
  53. data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
  54. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  55. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
  56. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +141 -52
  57. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  58. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +267 -105
  59. data/lib/active_record/connection_adapters/abstract/transaction.rb +94 -36
  60. data/lib/active_record/connection_adapters/abstract_adapter.rb +76 -79
  61. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
  62. data/lib/active_record/connection_adapters/column.rb +15 -1
  63. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  64. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  65. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
  67. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  68. data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
  69. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
  70. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  71. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
  72. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
  73. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  74. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
  75. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  76. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  77. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  78. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
  79. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  81. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  83. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
  91. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
  92. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  96. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  97. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
  101. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  102. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql_adapter.rb +83 -65
  104. data/lib/active_record/connection_adapters/schema_cache.rb +106 -15
  105. data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
  106. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
  107. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
  108. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  109. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
  110. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
  111. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  112. data/lib/active_record/connection_adapters.rb +52 -0
  113. data/lib/active_record/connection_handling.rb +219 -81
  114. data/lib/active_record/core.rb +268 -71
  115. data/lib/active_record/counter_cache.rb +4 -1
  116. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  117. data/lib/active_record/database_configurations/database_config.rb +52 -9
  118. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  119. data/lib/active_record/database_configurations/url_config.rb +15 -41
  120. data/lib/active_record/database_configurations.rb +124 -85
  121. data/lib/active_record/delegated_type.rb +209 -0
  122. data/lib/active_record/destroy_association_async_job.rb +36 -0
  123. data/lib/active_record/dynamic_matchers.rb +2 -3
  124. data/lib/active_record/enum.rb +80 -38
  125. data/lib/active_record/errors.rb +47 -12
  126. data/lib/active_record/explain.rb +9 -5
  127. data/lib/active_record/explain_subscriber.rb +1 -1
  128. data/lib/active_record/fixture_set/file.rb +10 -17
  129. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  130. data/lib/active_record/fixture_set/render_context.rb +1 -1
  131. data/lib/active_record/fixture_set/table_row.rb +2 -3
  132. data/lib/active_record/fixture_set/table_rows.rb +0 -1
  133. data/lib/active_record/fixtures.rb +58 -12
  134. data/lib/active_record/gem_version.rb +2 -2
  135. data/lib/active_record/inheritance.rb +40 -21
  136. data/lib/active_record/insert_all.rb +43 -10
  137. data/lib/active_record/integration.rb +3 -5
  138. data/lib/active_record/internal_metadata.rb +16 -7
  139. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  140. data/lib/active_record/locking/optimistic.rb +33 -18
  141. data/lib/active_record/locking/pessimistic.rb +6 -2
  142. data/lib/active_record/log_subscriber.rb +28 -9
  143. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  144. data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
  145. data/lib/active_record/middleware/database_selector.rb +4 -2
  146. data/lib/active_record/migration/command_recorder.rb +53 -45
  147. data/lib/active_record/migration/compatibility.rb +71 -20
  148. data/lib/active_record/migration/join_table.rb +0 -1
  149. data/lib/active_record/migration.rb +115 -85
  150. data/lib/active_record/model_schema.rb +120 -15
  151. data/lib/active_record/nested_attributes.rb +2 -5
  152. data/lib/active_record/no_touching.rb +1 -1
  153. data/lib/active_record/null_relation.rb +0 -1
  154. data/lib/active_record/persistence.rb +50 -46
  155. data/lib/active_record/query_cache.rb +15 -5
  156. data/lib/active_record/querying.rb +12 -7
  157. data/lib/active_record/railtie.rb +65 -45
  158. data/lib/active_record/railties/console_sandbox.rb +2 -4
  159. data/lib/active_record/railties/databases.rake +280 -99
  160. data/lib/active_record/readonly_attributes.rb +4 -0
  161. data/lib/active_record/reflection.rb +77 -63
  162. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  163. data/lib/active_record/relation/batches.rb +38 -32
  164. data/lib/active_record/relation/calculations.rb +106 -45
  165. data/lib/active_record/relation/delegation.rb +9 -7
  166. data/lib/active_record/relation/finder_methods.rb +55 -17
  167. data/lib/active_record/relation/from_clause.rb +5 -1
  168. data/lib/active_record/relation/merger.rb +27 -26
  169. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  170. data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
  171. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
  172. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  173. data/lib/active_record/relation/predicate_builder.rb +59 -40
  174. data/lib/active_record/relation/query_methods.rb +344 -181
  175. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  176. data/lib/active_record/relation/spawn_methods.rb +8 -8
  177. data/lib/active_record/relation/where_clause.rb +111 -62
  178. data/lib/active_record/relation.rb +116 -82
  179. data/lib/active_record/result.rb +41 -34
  180. data/lib/active_record/runtime_registry.rb +2 -2
  181. data/lib/active_record/sanitization.rb +6 -17
  182. data/lib/active_record/schema_dumper.rb +34 -4
  183. data/lib/active_record/schema_migration.rb +2 -8
  184. data/lib/active_record/scoping/default.rb +1 -4
  185. data/lib/active_record/scoping/named.rb +7 -18
  186. data/lib/active_record/scoping.rb +0 -1
  187. data/lib/active_record/secure_token.rb +16 -8
  188. data/lib/active_record/serialization.rb +5 -3
  189. data/lib/active_record/signed_id.rb +116 -0
  190. data/lib/active_record/statement_cache.rb +20 -4
  191. data/lib/active_record/store.rb +3 -3
  192. data/lib/active_record/suppressor.rb +2 -2
  193. data/lib/active_record/table_metadata.rb +42 -36
  194. data/lib/active_record/tasks/database_tasks.rb +140 -113
  195. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
  196. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
  197. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
  198. data/lib/active_record/test_databases.rb +5 -4
  199. data/lib/active_record/test_fixtures.rb +79 -16
  200. data/lib/active_record/timestamp.rb +4 -7
  201. data/lib/active_record/touch_later.rb +20 -21
  202. data/lib/active_record/transactions.rb +26 -73
  203. data/lib/active_record/type/adapter_specific_registry.rb +2 -5
  204. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  205. data/lib/active_record/type/serialized.rb +6 -3
  206. data/lib/active_record/type/time.rb +10 -0
  207. data/lib/active_record/type/type_map.rb +0 -1
  208. data/lib/active_record/type/unsigned_integer.rb +0 -1
  209. data/lib/active_record/type.rb +8 -2
  210. data/lib/active_record/type_caster/connection.rb +0 -1
  211. data/lib/active_record/type_caster/map.rb +8 -5
  212. data/lib/active_record/validations/associated.rb +1 -2
  213. data/lib/active_record/validations/numericality.rb +35 -0
  214. data/lib/active_record/validations/uniqueness.rb +24 -4
  215. data/lib/active_record/validations.rb +3 -3
  216. data/lib/active_record.rb +7 -13
  217. data/lib/arel/attributes/attribute.rb +4 -0
  218. data/lib/arel/collectors/bind.rb +5 -0
  219. data/lib/arel/collectors/composite.rb +8 -0
  220. data/lib/arel/collectors/sql_string.rb +7 -0
  221. data/lib/arel/collectors/substitute_binds.rb +7 -0
  222. data/lib/arel/nodes/binary.rb +82 -8
  223. data/lib/arel/nodes/bind_param.rb +8 -0
  224. data/lib/arel/nodes/casted.rb +21 -9
  225. data/lib/arel/nodes/equality.rb +6 -9
  226. data/lib/arel/nodes/grouping.rb +3 -0
  227. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  228. data/lib/arel/nodes/in.rb +8 -1
  229. data/lib/arel/nodes/infix_operation.rb +13 -1
  230. data/lib/arel/nodes/join_source.rb +1 -1
  231. data/lib/arel/nodes/node.rb +7 -6
  232. data/lib/arel/nodes/ordering.rb +27 -0
  233. data/lib/arel/nodes/sql_literal.rb +3 -0
  234. data/lib/arel/nodes/table_alias.rb +7 -3
  235. data/lib/arel/nodes/unary.rb +0 -1
  236. data/lib/arel/nodes.rb +3 -1
  237. data/lib/arel/predications.rb +17 -24
  238. data/lib/arel/select_manager.rb +1 -2
  239. data/lib/arel/table.rb +13 -5
  240. data/lib/arel/visitors/dot.rb +14 -3
  241. data/lib/arel/visitors/mysql.rb +11 -1
  242. data/lib/arel/visitors/postgresql.rb +15 -5
  243. data/lib/arel/visitors/sqlite.rb +0 -1
  244. data/lib/arel/visitors/to_sql.rb +89 -79
  245. data/lib/arel/visitors/visitor.rb +0 -1
  246. data/lib/arel/visitors.rb +0 -7
  247. data/lib/arel.rb +15 -12
  248. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  249. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  250. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  251. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
  252. data/lib/rails/generators/active_record/migration.rb +6 -2
  253. data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
  254. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  255. metadata +27 -24
  256. data/lib/active_record/attribute_decorators.rb +0 -90
  257. data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
  258. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  259. data/lib/active_record/define_callbacks.rb +0 -22
  260. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  261. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  262. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  263. data/lib/arel/attributes.rb +0 -22
  264. data/lib/arel/visitors/depth_first.rb +0 -204
  265. data/lib/arel/visitors/ibm_db.rb +0 -34
  266. data/lib/arel/visitors/informix.rb +0 -62
  267. data/lib/arel/visitors/mssql.rb +0 -157
  268. data/lib/arel/visitors/oracle.rb +0 -159
  269. data/lib/arel/visitors/oracle12.rb +0 -66
  270. data/lib/arel/visitors/where_sql.rb +0 -23
@@ -6,37 +6,26 @@ require "monitor"
6
6
  require "weakref"
7
7
 
8
8
  module ActiveRecord
9
- # Raised when a connection could not be obtained within the connection
10
- # acquisition timeout period: because max connections in pool
11
- # are in use.
12
- class ConnectionTimeoutError < ConnectionNotEstablished
13
- end
14
-
15
- # Raised when a pool was unable to get ahold of all its connections
16
- # to perform a "group" action such as
17
- # {ActiveRecord::Base.connection_pool.disconnect!}[rdoc-ref:ConnectionAdapters::ConnectionPool#disconnect!]
18
- # or {ActiveRecord::Base.clear_reloadable_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_reloadable_connections!].
19
- class ExclusiveConnectionTimeoutError < ConnectionTimeoutError
20
- end
21
-
22
9
  module ConnectionAdapters
23
10
  module AbstractPool # :nodoc:
24
11
  def get_schema_cache(connection)
25
- @schema_cache ||= SchemaCache.new(connection)
26
- @schema_cache.connection = connection
27
- @schema_cache
12
+ self.schema_cache ||= SchemaCache.new(connection)
13
+ schema_cache.connection = connection
14
+ schema_cache
28
15
  end
29
16
 
30
17
  def set_schema_cache(cache)
31
- @schema_cache = cache
18
+ self.schema_cache = cache
32
19
  end
33
20
  end
34
21
 
35
22
  class NullPool # :nodoc:
36
23
  include ConnectionAdapters::AbstractPool
37
24
 
38
- def initialize
39
- @schema_cache = nil
25
+ attr_accessor :schema_cache
26
+
27
+ def connection_klass
28
+ nil
40
29
  end
41
30
  end
42
31
 
@@ -150,7 +139,7 @@ module ActiveRecord
150
139
 
151
140
  # Remove the head of the queue.
152
141
  #
153
- # If +timeout+ is not given, remove and return the head the
142
+ # If +timeout+ is not given, remove and return the head of the
154
143
  # queue if the number of available elements is strictly
155
144
  # greater than the number of threads currently waiting (that
156
145
  # is, don't jump ahead in line). Otherwise, return +nil+.
@@ -167,7 +156,6 @@ module ActiveRecord
167
156
  end
168
157
 
169
158
  private
170
-
171
159
  def internal_poll(timeout)
172
160
  no_wait_poll || (timeout && wait_poll(timeout))
173
161
  end
@@ -194,7 +182,7 @@ module ActiveRecord
194
182
  @queue.pop
195
183
  end
196
184
 
197
- # Remove and return the head the queue if the number of
185
+ # Remove and return the head of the queue if the number of
198
186
  # available elements is strictly greater than the number of
199
187
  # threads currently waiting. Otherwise, return +nil+.
200
188
  def no_wait_poll
@@ -317,31 +305,44 @@ module ActiveRecord
317
305
 
318
306
  @mutex = Mutex.new
319
307
  @pools = {}
308
+ @threads = {}
320
309
 
321
310
  class << self
322
311
  def register_pool(pool, frequency) # :nodoc:
323
312
  @mutex.synchronize do
324
- unless @pools.key?(frequency)
325
- @pools[frequency] = []
326
- spawn_thread(frequency)
313
+ unless @threads[frequency]&.alive?
314
+ @threads[frequency] = spawn_thread(frequency)
327
315
  end
316
+ @pools[frequency] ||= []
328
317
  @pools[frequency] << WeakRef.new(pool)
329
318
  end
330
319
  end
331
320
 
332
321
  private
333
-
334
322
  def spawn_thread(frequency)
335
323
  Thread.new(frequency) do |t|
336
- loop do
324
+ # Advise multi-threaded app servers to ignore this thread for
325
+ # the purposes of fork safety warnings
326
+ Thread.current.thread_variable_set(:fork_safe, true)
327
+ running = true
328
+ while running
337
329
  sleep t
338
330
  @mutex.synchronize do
339
- @pools[frequency].select!(&:weakref_alive?)
331
+ @pools[frequency].select! do |pool|
332
+ pool.weakref_alive? && !pool.discarded?
333
+ end
334
+
340
335
  @pools[frequency].each do |p|
341
336
  p.reap
342
337
  p.flush
343
338
  rescue WeakRef::RefError
344
339
  end
340
+
341
+ if @pools[frequency].empty?
342
+ @pools.delete(frequency)
343
+ @threads.delete(frequency)
344
+ running = false
345
+ end
345
346
  end
346
347
  end
347
348
  end
@@ -358,35 +359,34 @@ module ActiveRecord
358
359
  include QueryCache::ConnectionPoolConfiguration
359
360
  include ConnectionAdapters::AbstractPool
360
361
 
361
- attr_accessor :automatic_reconnect, :checkout_timeout, :schema_cache
362
- attr_reader :spec, :size, :reaper
362
+ attr_accessor :automatic_reconnect, :checkout_timeout
363
+ attr_reader :db_config, :size, :reaper, :pool_config, :connection_klass
363
364
 
364
- # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
365
+ delegate :schema_cache, :schema_cache=, to: :pool_config
366
+
367
+ # Creates a new ConnectionPool object. +pool_config+ is a PoolConfig
365
368
  # object which describes database connection information (e.g. adapter,
366
369
  # host name, username, password, etc), as well as the maximum size for
367
370
  # this ConnectionPool.
368
371
  #
369
372
  # The default ConnectionPool maximum size is 5.
370
- def initialize(spec)
373
+ def initialize(pool_config)
371
374
  super()
372
375
 
373
- @spec = spec
374
-
375
- @checkout_timeout = (spec.config[:checkout_timeout] && spec.config[:checkout_timeout].to_f) || 5
376
- if @idle_timeout = spec.config.fetch(:idle_timeout, 300)
377
- @idle_timeout = @idle_timeout.to_f
378
- @idle_timeout = nil if @idle_timeout <= 0
379
- end
376
+ @pool_config = pool_config
377
+ @db_config = pool_config.db_config
378
+ @connection_klass = pool_config.connection_klass
380
379
 
381
- # default max pool size to 5
382
- @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
380
+ @checkout_timeout = db_config.checkout_timeout
381
+ @idle_timeout = db_config.idle_timeout
382
+ @size = db_config.pool
383
383
 
384
384
  # This variable tracks the cache of threads mapped to reserved connections, with the
385
385
  # sole purpose of speeding up the +connection+ method. It is not the authoritative
386
386
  # registry of which thread owns which connection. Connection ownership is tracked by
387
387
  # the +connection.owner+ attr on each +connection+ instance.
388
388
  # The invariant works like this: if there is mapping of <tt>thread => conn</tt>,
389
- # then that +thread+ does indeed own that +conn+. However, an absence of a such
389
+ # then that +thread+ does indeed own that +conn+. However, an absence of such
390
390
  # mapping does not mean that the +thread+ doesn't own the said connection. In
391
391
  # that case +conn.owner+ attr should be consulted.
392
392
  # Access and modification of <tt>@thread_cached_conns</tt> does not require
@@ -407,10 +407,7 @@ module ActiveRecord
407
407
 
408
408
  @lock_thread = false
409
409
 
410
- # +reaping_frequency+ is configurable mostly for historical reasons, but it could
411
- # also be useful if someone wants a very low +idle_timeout+.
412
- reaping_frequency = spec.config.fetch(:reaping_frequency, 60)
413
- @reaper = Reaper.new(self, reaping_frequency && reaping_frequency.to_f)
410
+ @reaper = Reaper.new(self, db_config.reaping_frequency)
414
411
  @reaper.run
415
412
  end
416
413
 
@@ -492,7 +489,7 @@ module ActiveRecord
492
489
  # Raises:
493
490
  # - ActiveRecord::ExclusiveConnectionTimeoutError if unable to gain ownership of all
494
491
  # connections in the pool within a timeout interval (default duration is
495
- # <tt>spec.config[:checkout_timeout] * 2</tt> seconds).
492
+ # <tt>spec.db_config.checkout_timeout * 2</tt> seconds).
496
493
  def disconnect(raise_on_acquisition_timeout = true)
497
494
  with_exclusively_acquired_all_connections(raise_on_acquisition_timeout) do
498
495
  synchronize do
@@ -513,7 +510,7 @@ module ActiveRecord
513
510
  #
514
511
  # The pool first tries to gain ownership of all connections. If unable to
515
512
  # do so within a timeout interval (default duration is
516
- # <tt>spec.config[:checkout_timeout] * 2</tt> seconds), then the pool is forcefully
513
+ # <tt>spec.db_config.checkout_timeout * 2</tt> seconds), then the pool is forcefully
517
514
  # disconnected without any regard for other connection owning threads.
518
515
  def disconnect!
519
516
  disconnect(false)
@@ -526,7 +523,7 @@ module ActiveRecord
526
523
  # See AbstractAdapter#discard!
527
524
  def discard! # :nodoc:
528
525
  synchronize do
529
- return if @connections.nil? # already discarded
526
+ return if self.discarded?
530
527
  @connections.each do |conn|
531
528
  conn.discard!
532
529
  end
@@ -534,13 +531,17 @@ module ActiveRecord
534
531
  end
535
532
  end
536
533
 
534
+ def discarded? # :nodoc:
535
+ @connections.nil?
536
+ end
537
+
537
538
  # Clears the cache which maps classes and re-connects connections that
538
539
  # require reloading.
539
540
  #
540
541
  # Raises:
541
542
  # - ActiveRecord::ExclusiveConnectionTimeoutError if unable to gain ownership of all
542
543
  # connections in the pool within a timeout interval (default duration is
543
- # <tt>spec.config[:checkout_timeout] * 2</tt> seconds).
544
+ # <tt>spec.db_config.checkout_timeout * 2</tt> seconds).
544
545
  def clear_reloadable_connections(raise_on_acquisition_timeout = true)
545
546
  with_exclusively_acquired_all_connections(raise_on_acquisition_timeout) do
546
547
  synchronize do
@@ -562,7 +563,7 @@ module ActiveRecord
562
563
  #
563
564
  # The pool first tries to gain ownership of all connections. If unable to
564
565
  # do so within a timeout interval (default duration is
565
- # <tt>spec.config[:checkout_timeout] * 2</tt> seconds), then the pool forcefully
566
+ # <tt>spec.db_config.checkout_timeout * 2</tt> seconds), then the pool forcefully
566
567
  # clears the cache and reloads connections without any regard for other
567
568
  # connection owning threads.
568
569
  def clear_reloadable_connections!
@@ -642,6 +643,7 @@ module ActiveRecord
642
643
  # or a thread dies unexpectedly.
643
644
  def reap
644
645
  stale_connections = synchronize do
646
+ return if self.discarded?
645
647
  @connections.select do |conn|
646
648
  conn.in_use? && !conn.owner.alive?
647
649
  end.each do |conn|
@@ -666,6 +668,7 @@ module ActiveRecord
666
668
  return if minimum_idle.nil?
667
669
 
668
670
  idle_connections = synchronize do
671
+ return if self.discarded?
669
672
  @connections.select do |conn|
670
673
  !conn.in_use? && conn.seconds_idle >= minimum_idle
671
674
  end.each do |conn|
@@ -876,7 +879,7 @@ module ActiveRecord
876
879
  alias_method :release, :remove_connection_from_thread_cache
877
880
 
878
881
  def new_connection
879
- Base.send(spec.adapter_method, spec.config).tap do |conn|
882
+ Base.public_send(db_config.adapter_method, db_config.configuration_hash).tap do |conn|
880
883
  conn.check_version
881
884
  end
882
885
  end
@@ -980,38 +983,18 @@ module ActiveRecord
980
983
  # should use.
981
984
  #
982
985
  # The ConnectionHandler class is not coupled with the Active models, as it has no knowledge
983
- # about the model. The model needs to pass a specification name to the handler,
986
+ # about the model. The model needs to pass a connection specification name to the handler,
984
987
  # in order to look up the correct connection pool.
985
988
  class ConnectionHandler
986
- def self.create_owner_to_pool # :nodoc:
987
- Concurrent::Map.new(initial_capacity: 2) do |h, k|
988
- # Discard the parent's connection pools immediately; we have no need
989
- # of them
990
- discard_unowned_pools(h)
991
-
992
- h[k] = Concurrent::Map.new(initial_capacity: 2)
993
- end
994
- end
995
-
996
- def self.unowned_pool_finalizer(pid_map) # :nodoc:
997
- lambda do |_|
998
- discard_unowned_pools(pid_map)
999
- end
1000
- end
1001
-
1002
- def self.discard_unowned_pools(pid_map) # :nodoc:
1003
- pid_map.each do |pid, pools|
1004
- pools.values.compact.each(&:discard!) unless pid == Process.pid
1005
- end
1006
- end
989
+ FINALIZER = lambda { |_| ActiveSupport::ForkTracker.check! }
990
+ private_constant :FINALIZER
1007
991
 
1008
992
  def initialize
1009
- # These caches are keyed by spec.name (ConnectionSpecification#name).
1010
- @owner_to_pool = ConnectionHandler.create_owner_to_pool
993
+ # These caches are keyed by pool_config.connection_specification_name (PoolConfig#connection_specification_name).
994
+ @owner_to_pool_manager = Concurrent::Map.new(initial_capacity: 2)
1011
995
 
1012
- # Backup finalizer: if the forked child never needed a pool, the above
1013
- # early discard has not occurred
1014
- ObjectSpace.define_finalizer self, ConnectionHandler.unowned_pool_finalizer(@owner_to_pool)
996
+ # Backup finalizer: if the forked child skipped Kernel#fork the early discard has not occurred
997
+ ObjectSpace.define_finalizer self, FINALIZER
1015
998
  end
1016
999
 
1017
1000
  def prevent_writes # :nodoc:
@@ -1027,85 +1010,119 @@ module ActiveRecord
1027
1010
  # In some cases you may want to prevent writes to the database
1028
1011
  # even if you are on a database that can write. `while_preventing_writes`
1029
1012
  # will prevent writes to the database for the duration of the block.
1013
+ #
1014
+ # This method does not provide the same protection as a readonly
1015
+ # user and is meant to be a safeguard against accidental writes.
1016
+ #
1017
+ # See `READ_QUERY` for the queries that are blocked by this
1018
+ # method.
1030
1019
  def while_preventing_writes(enabled = true)
1020
+ unless ActiveRecord::Base.legacy_connection_handling
1021
+ raise NotImplementedError, "`while_preventing_writes` is only available on the connection_handler with legacy_connection_handling"
1022
+ end
1023
+
1031
1024
  original, self.prevent_writes = self.prevent_writes, enabled
1032
1025
  yield
1033
1026
  ensure
1034
1027
  self.prevent_writes = original
1035
1028
  end
1036
1029
 
1037
- def connection_pool_list
1038
- owner_to_pool.values.compact
1030
+ def connection_pool_names # :nodoc:
1031
+ owner_to_pool_manager.keys
1032
+ end
1033
+
1034
+ def all_connection_pools
1035
+ owner_to_pool_manager.values.flat_map { |m| m.pool_configs.map(&:pool) }
1036
+ end
1037
+
1038
+ def connection_pool_list(role = ActiveRecord::Base.current_role)
1039
+ owner_to_pool_manager.values.flat_map { |m| m.pool_configs(role).map(&:pool) }
1039
1040
  end
1040
1041
  alias :connection_pools :connection_pool_list
1041
1042
 
1042
- def establish_connection(config)
1043
- resolver = ConnectionSpecification::Resolver.new(Base.configurations)
1044
- spec = resolver.spec(config)
1043
+ def establish_connection(config, owner_name: Base, role: ActiveRecord::Base.current_role, shard: Base.current_shard)
1044
+ owner_name = config.to_s if config.is_a?(Symbol)
1045
+
1046
+ pool_config = resolve_pool_config(config, owner_name)
1047
+ db_config = pool_config.db_config
1045
1048
 
1046
- remove_connection(spec.name)
1049
+ # Protects the connection named `ActiveRecord::Base` from being removed
1050
+ # if the user calls `establish_connection :primary`.
1051
+ if owner_to_pool_manager.key?(pool_config.connection_specification_name)
1052
+ remove_connection_pool(pool_config.connection_specification_name, role: role, shard: shard)
1053
+ end
1047
1054
 
1048
1055
  message_bus = ActiveSupport::Notifications.instrumenter
1049
- payload = {
1050
- connection_id: object_id
1051
- }
1052
- if spec
1053
- payload[:spec_name] = spec.name
1054
- payload[:config] = spec.config
1056
+ payload = {}
1057
+ if pool_config
1058
+ payload[:spec_name] = pool_config.connection_specification_name
1059
+ payload[:shard] = shard
1060
+ payload[:config] = db_config.configuration_hash
1055
1061
  end
1056
1062
 
1057
- message_bus.instrument("!connection.active_record", payload) do
1058
- owner_to_pool[spec.name] = ConnectionAdapters::ConnectionPool.new(spec)
1063
+ if ActiveRecord::Base.legacy_connection_handling
1064
+ owner_to_pool_manager[pool_config.connection_specification_name] ||= LegacyPoolManager.new
1065
+ else
1066
+ owner_to_pool_manager[pool_config.connection_specification_name] ||= PoolManager.new
1059
1067
  end
1068
+ pool_manager = get_pool_manager(pool_config.connection_specification_name)
1069
+ pool_manager.set_pool_config(role, shard, pool_config)
1060
1070
 
1061
- owner_to_pool[spec.name]
1071
+ message_bus.instrument("!connection.active_record", payload) do
1072
+ pool_config.pool
1073
+ end
1062
1074
  end
1063
1075
 
1064
1076
  # Returns true if there are any active connections among the connection
1065
1077
  # pools that the ConnectionHandler is managing.
1066
- def active_connections?
1067
- connection_pool_list.any?(&:active_connection?)
1078
+ def active_connections?(role = ActiveRecord::Base.current_role)
1079
+ connection_pool_list(role).any?(&:active_connection?)
1068
1080
  end
1069
1081
 
1070
1082
  # Returns any connections in use by the current thread back to the pool,
1071
1083
  # and also returns connections to the pool cached by threads that are no
1072
1084
  # longer alive.
1073
- def clear_active_connections!
1074
- connection_pool_list.each(&:release_connection)
1085
+ def clear_active_connections!(role = ActiveRecord::Base.current_role)
1086
+ connection_pool_list(role).each(&:release_connection)
1075
1087
  end
1076
1088
 
1077
1089
  # Clears the cache which maps classes.
1078
1090
  #
1079
1091
  # See ConnectionPool#clear_reloadable_connections! for details.
1080
- def clear_reloadable_connections!
1081
- connection_pool_list.each(&:clear_reloadable_connections!)
1092
+ def clear_reloadable_connections!(role = ActiveRecord::Base.current_role)
1093
+ connection_pool_list(role).each(&:clear_reloadable_connections!)
1082
1094
  end
1083
1095
 
1084
- def clear_all_connections!
1085
- connection_pool_list.each(&:disconnect!)
1096
+ def clear_all_connections!(role = ActiveRecord::Base.current_role)
1097
+ connection_pool_list(role).each(&:disconnect!)
1086
1098
  end
1087
1099
 
1088
1100
  # Disconnects all currently idle connections.
1089
1101
  #
1090
1102
  # See ConnectionPool#flush! for details.
1091
- def flush_idle_connections!
1092
- connection_pool_list.each(&:flush!)
1103
+ def flush_idle_connections!(role = ActiveRecord::Base.current_role)
1104
+ connection_pool_list(role).each(&:flush!)
1093
1105
  end
1094
1106
 
1095
1107
  # Locate the connection of the nearest super class. This can be an
1096
1108
  # active or defined connection: if it is the latter, it will be
1097
1109
  # opened and set as the active connection for the class it was defined
1098
1110
  # for (not necessarily the current class).
1099
- def retrieve_connection(spec_name) #:nodoc:
1100
- pool = retrieve_connection_pool(spec_name)
1111
+ def retrieve_connection(spec_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard) # :nodoc:
1112
+ pool = retrieve_connection_pool(spec_name, role: role, shard: shard)
1101
1113
 
1102
1114
  unless pool
1103
- # multiple database application
1104
- if ActiveRecord::Base.connection_handler != ActiveRecord::Base.default_connection_handler
1105
- raise ConnectionNotEstablished, "No connection pool with '#{spec_name}' found for the '#{ActiveRecord::Base.current_role}' role."
1115
+ if shard != ActiveRecord::Base.default_shard
1116
+ message = "No connection pool for '#{spec_name}' found for the '#{shard}' shard."
1117
+ elsif ActiveRecord::Base.connection_handler != ActiveRecord::Base.default_connection_handler
1118
+ message = "No connection pool for '#{spec_name}' found for the '#{ActiveRecord::Base.current_role}' role."
1119
+ elsif role != ActiveRecord::Base.default_role
1120
+ message = "No connection pool for '#{spec_name}' found for the '#{role}' role."
1106
1121
  else
1107
- raise ConnectionNotEstablished, "No connection pool with '#{spec_name}' found."
1122
+ message = "No connection pool for '#{spec_name}' found."
1108
1123
  end
1124
+
1125
+ raise ConnectionNotEstablished, message
1109
1126
  end
1110
1127
 
1111
1128
  pool.connection
@@ -1113,8 +1130,8 @@ module ActiveRecord
1113
1130
 
1114
1131
  # Returns true if a connection that's accessible to this class has
1115
1132
  # already been opened.
1116
- def connected?(spec_name)
1117
- pool = retrieve_connection_pool(spec_name)
1133
+ def connected?(spec_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
1134
+ pool = retrieve_connection_pool(spec_name, role: role, shard: shard)
1118
1135
  pool && pool.connected?
1119
1136
  end
1120
1137
 
@@ -1122,43 +1139,90 @@ module ActiveRecord
1122
1139
  # connection and the defined connection (if they exist). The result
1123
1140
  # can be used as an argument for #establish_connection, for easily
1124
1141
  # re-establishing the connection.
1125
- def remove_connection(spec_name)
1126
- if pool = owner_to_pool.delete(spec_name)
1127
- pool.automatic_reconnect = false
1128
- pool.disconnect!
1129
- pool.spec.config
1142
+ def remove_connection(owner, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
1143
+ remove_connection_pool(owner, role: role, shard: shard)&.configuration_hash
1144
+ end
1145
+ deprecate remove_connection: "Use #remove_connection_pool, which now returns a DatabaseConfig object instead of a Hash"
1146
+
1147
+ def remove_connection_pool(owner, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
1148
+ if pool_manager = get_pool_manager(owner)
1149
+ pool_config = pool_manager.remove_pool_config(role, shard)
1150
+
1151
+ if pool_config
1152
+ pool_config.disconnect!
1153
+ pool_config.db_config
1154
+ end
1130
1155
  end
1131
1156
  end
1132
1157
 
1133
- # Retrieving the connection pool happens a lot, so we cache it in @owner_to_pool.
1158
+ # Retrieving the connection pool happens a lot, so we cache it in @owner_to_pool_manager.
1134
1159
  # This makes retrieving the connection pool O(1) once the process is warm.
1135
1160
  # When a connection is established or removed, we invalidate the cache.
1136
- def retrieve_connection_pool(spec_name)
1137
- owner_to_pool.fetch(spec_name) do
1138
- # Check if a connection was previously established in an ancestor process,
1139
- # which may have been forked.
1140
- if ancestor_pool = pool_from_any_process_for(spec_name)
1141
- # A connection was established in an ancestor process that must have
1142
- # subsequently forked. We can't reuse the connection, but we can copy
1143
- # the specification and establish a new connection with it.
1144
- establish_connection(ancestor_pool.spec.to_hash).tap do |pool|
1145
- pool.schema_cache = ancestor_pool.schema_cache if ancestor_pool.schema_cache
1146
- end
1147
- else
1148
- owner_to_pool[spec_name] = nil
1149
- end
1150
- end
1161
+ def retrieve_connection_pool(owner, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
1162
+ pool_config = get_pool_manager(owner)&.get_pool_config(role, shard)
1163
+ pool_config&.pool
1151
1164
  end
1152
1165
 
1153
1166
  private
1167
+ attr_reader :owner_to_pool_manager
1154
1168
 
1155
- def owner_to_pool
1156
- @owner_to_pool[Process.pid]
1169
+ # Returns the pool manager for an owner.
1170
+ #
1171
+ # Using `"primary"` to look up the pool manager for `ActiveRecord::Base` is
1172
+ # deprecated in favor of looking it up by `"ActiveRecord::Base"`.
1173
+ #
1174
+ # During the deprecation period, if `"primary"` is passed, the pool manager
1175
+ # for `ActiveRecord::Base` will still be returned.
1176
+ def get_pool_manager(owner)
1177
+ return owner_to_pool_manager[owner] if owner_to_pool_manager.key?(owner)
1178
+
1179
+ if owner == "primary"
1180
+ ActiveSupport::Deprecation.warn("Using `\"primary\"` as a `connection_specification_name` is deprecated and will be removed in Rails 6.2.0. Please use `ActiveRecord::Base`.")
1181
+ owner_to_pool_manager[Base.name]
1182
+ end
1157
1183
  end
1158
1184
 
1159
- def pool_from_any_process_for(spec_name)
1160
- owner_to_pool = @owner_to_pool.values.reverse.find { |v| v[spec_name] }
1161
- owner_to_pool && owner_to_pool[spec_name]
1185
+ # Returns an instance of PoolConfig for a given adapter.
1186
+ # Accepts a hash one layer deep that contains all connection information.
1187
+ #
1188
+ # == Example
1189
+ #
1190
+ # config = { "production" => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } }
1191
+ # pool_config = Base.configurations.resolve_pool_config(:production)
1192
+ # pool_config.db_config.configuration_hash
1193
+ # # => { host: "localhost", database: "foo", adapter: "sqlite3" }
1194
+ #
1195
+ def resolve_pool_config(config, owner_name)
1196
+ db_config = Base.configurations.resolve(config)
1197
+
1198
+ raise(AdapterNotSpecified, "database configuration does not specify adapter") unless db_config.adapter
1199
+
1200
+ # Require the adapter itself and give useful feedback about
1201
+ # 1. Missing adapter gems and
1202
+ # 2. Adapter gems' missing dependencies.
1203
+ path_to_adapter = "active_record/connection_adapters/#{db_config.adapter}_adapter"
1204
+ begin
1205
+ require path_to_adapter
1206
+ rescue LoadError => e
1207
+ # We couldn't require the adapter itself. Raise an exception that
1208
+ # points out config typos and missing gems.
1209
+ if e.path == path_to_adapter
1210
+ # We can assume that a non-builtin adapter was specified, so it's
1211
+ # either misspelled or missing from Gemfile.
1212
+ raise LoadError, "Could not load the '#{db_config.adapter}' Active Record adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.", e.backtrace
1213
+
1214
+ # Bubbled up from the adapter require. Prefix the exception message
1215
+ # with some guidance about how to address it and reraise.
1216
+ else
1217
+ raise LoadError, "Error loading the '#{db_config.adapter}' Active Record adapter. Missing a gem it depends on? #{e.message}", e.backtrace
1218
+ end
1219
+ end
1220
+
1221
+ unless ActiveRecord::Base.respond_to?(db_config.adapter_method)
1222
+ raise AdapterNotFound, "database configuration specifies nonexistent #{db_config.adapter} adapter"
1223
+ end
1224
+
1225
+ ConnectionAdapters::PoolConfig.new(owner_name, db_config)
1162
1226
  end
1163
1227
  end
1164
1228
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/deprecation"
4
-
5
3
  module ActiveRecord
6
4
  module ConnectionAdapters # :nodoc:
7
5
  module DatabaseLimits
@@ -14,18 +12,6 @@ module ActiveRecord
14
12
  max_identifier_length
15
13
  end
16
14
 
17
- # Returns the maximum length of a column name.
18
- def column_name_length
19
- max_identifier_length
20
- end
21
- deprecate :column_name_length
22
-
23
- # Returns the maximum length of a table name.
24
- def table_name_length
25
- max_identifier_length
26
- end
27
- deprecate :table_name_length
28
-
29
15
  # Returns the maximum allowed length for an index name. This
30
16
  # limit is enforced by \Rails and is less than or equal to
31
17
  # #index_name_length. The gap between
@@ -34,47 +20,19 @@ module ActiveRecord
34
20
  def allowed_index_name_length
35
21
  index_name_length
36
22
  end
23
+ deprecate :allowed_index_name_length
37
24
 
38
25
  # Returns the maximum length of an index name.
39
26
  def index_name_length
40
27
  max_identifier_length
41
28
  end
42
29
 
43
- # Returns the maximum number of columns per table.
44
- def columns_per_table
45
- 1024
46
- end
47
- deprecate :columns_per_table
48
-
49
- # Returns the maximum number of indexes per table.
50
- def indexes_per_table
51
- 16
52
- end
53
- deprecate :indexes_per_table
54
-
55
- # Returns the maximum number of columns in a multicolumn index.
56
- def columns_per_multicolumn_index
57
- 16
58
- end
59
- deprecate :columns_per_multicolumn_index
60
-
61
30
  # Returns the maximum number of elements in an IN (x,y,z) clause.
62
31
  # +nil+ means no limit.
63
32
  def in_clause_length
64
33
  nil
65
34
  end
66
-
67
- # Returns the maximum length of an SQL query.
68
- def sql_query_length
69
- 1048575
70
- end
71
- deprecate :sql_query_length
72
-
73
- # Returns maximum number of joins in a single query.
74
- def joins_per_query
75
- 256
76
- end
77
- deprecate :joins_per_query
35
+ deprecate :in_clause_length
78
36
 
79
37
  private
80
38
  def bind_params_length