activerecord 5.2.6 → 6.0.5

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 (294) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +928 -559
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +5 -3
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/advisory_lock_base.rb +18 -0
  7. data/lib/active_record/aggregations.rb +4 -3
  8. data/lib/active_record/association_relation.rb +10 -8
  9. data/lib/active_record/associations/alias_tracker.rb +0 -1
  10. data/lib/active_record/associations/association.rb +55 -19
  11. data/lib/active_record/associations/association_scope.rb +11 -7
  12. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  14. data/lib/active_record/associations/builder/association.rb +14 -18
  15. data/lib/active_record/associations/builder/belongs_to.rb +19 -52
  16. data/lib/active_record/associations/builder/collection_association.rb +3 -13
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
  18. data/lib/active_record/associations/builder/has_many.rb +2 -0
  19. data/lib/active_record/associations/builder/has_one.rb +35 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  21. data/lib/active_record/associations/collection_association.rb +19 -23
  22. data/lib/active_record/associations/collection_proxy.rb +14 -17
  23. data/lib/active_record/associations/foreign_association.rb +7 -0
  24. data/lib/active_record/associations/has_many_association.rb +2 -11
  25. data/lib/active_record/associations/has_many_through_association.rb +14 -14
  26. data/lib/active_record/associations/has_one_association.rb +28 -30
  27. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  28. data/lib/active_record/associations/join_dependency/join_association.rb +16 -10
  29. data/lib/active_record/associations/join_dependency/join_part.rb +4 -4
  30. data/lib/active_record/associations/join_dependency.rb +47 -30
  31. data/lib/active_record/associations/preloader/association.rb +61 -41
  32. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  33. data/lib/active_record/associations/preloader.rb +44 -33
  34. data/lib/active_record/associations/singular_association.rb +2 -16
  35. data/lib/active_record/associations/through_association.rb +1 -1
  36. data/lib/active_record/associations.rb +21 -16
  37. data/lib/active_record/attribute_assignment.rb +7 -11
  38. data/lib/active_record/attribute_decorators.rb +0 -2
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
  40. data/lib/active_record/attribute_methods/dirty.rb +111 -40
  41. data/lib/active_record/attribute_methods/primary_key.rb +15 -24
  42. data/lib/active_record/attribute_methods/query.rb +2 -3
  43. data/lib/active_record/attribute_methods/read.rb +15 -54
  44. data/lib/active_record/attribute_methods/serialization.rb +1 -2
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
  46. data/lib/active_record/attribute_methods/write.rb +17 -25
  47. data/lib/active_record/attribute_methods.rb +28 -100
  48. data/lib/active_record/attributes.rb +13 -1
  49. data/lib/active_record/autosave_association.rb +12 -14
  50. data/lib/active_record/base.rb +2 -3
  51. data/lib/active_record/callbacks.rb +6 -21
  52. data/lib/active_record/coders/yaml_column.rb +0 -1
  53. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -18
  54. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
  55. data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
  56. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
  57. data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
  58. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
  59. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +105 -72
  60. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
  62. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
  63. data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -43
  64. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -217
  65. data/lib/active_record/connection_adapters/column.rb +17 -13
  66. data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
  67. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
  68. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  69. data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
  70. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
  71. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  72. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
  73. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  74. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  75. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
  76. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  77. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
  78. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  79. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  81. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  82. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +8 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  89. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  91. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
  92. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  93. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  94. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
  95. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  96. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  97. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
  98. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  99. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  100. data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
  101. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  102. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  103. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  104. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  105. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
  106. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +137 -147
  107. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  108. data/lib/active_record/connection_handling.rb +139 -26
  109. data/lib/active_record/core.rb +107 -66
  110. data/lib/active_record/counter_cache.rb +8 -30
  111. data/lib/active_record/database_configurations/database_config.rb +37 -0
  112. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  113. data/lib/active_record/database_configurations/url_config.rb +78 -0
  114. data/lib/active_record/database_configurations.rb +233 -0
  115. data/lib/active_record/dynamic_matchers.rb +3 -4
  116. data/lib/active_record/enum.rb +44 -7
  117. data/lib/active_record/errors.rb +15 -7
  118. data/lib/active_record/explain.rb +1 -2
  119. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  120. data/lib/active_record/fixture_set/render_context.rb +17 -0
  121. data/lib/active_record/fixture_set/table_row.rb +152 -0
  122. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  123. data/lib/active_record/fixtures.rb +144 -474
  124. data/lib/active_record/gem_version.rb +3 -3
  125. data/lib/active_record/inheritance.rb +13 -6
  126. data/lib/active_record/insert_all.rb +179 -0
  127. data/lib/active_record/integration.rb +68 -16
  128. data/lib/active_record/internal_metadata.rb +11 -3
  129. data/lib/active_record/locking/optimistic.rb +14 -7
  130. data/lib/active_record/locking/pessimistic.rb +3 -3
  131. data/lib/active_record/log_subscriber.rb +8 -27
  132. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  133. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  134. data/lib/active_record/middleware/database_selector.rb +74 -0
  135. data/lib/active_record/migration/command_recorder.rb +54 -22
  136. data/lib/active_record/migration/compatibility.rb +79 -52
  137. data/lib/active_record/migration/join_table.rb +0 -1
  138. data/lib/active_record/migration.rb +104 -85
  139. data/lib/active_record/model_schema.rb +62 -11
  140. data/lib/active_record/nested_attributes.rb +2 -4
  141. data/lib/active_record/no_touching.rb +9 -2
  142. data/lib/active_record/null_relation.rb +0 -1
  143. data/lib/active_record/persistence.rb +232 -29
  144. data/lib/active_record/query_cache.rb +11 -4
  145. data/lib/active_record/querying.rb +33 -21
  146. data/lib/active_record/railtie.rb +80 -43
  147. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  148. data/lib/active_record/railties/controller_runtime.rb +30 -35
  149. data/lib/active_record/railties/databases.rake +199 -46
  150. data/lib/active_record/reflection.rb +51 -51
  151. data/lib/active_record/relation/batches.rb +13 -11
  152. data/lib/active_record/relation/calculations.rb +55 -49
  153. data/lib/active_record/relation/delegation.rb +35 -50
  154. data/lib/active_record/relation/finder_methods.rb +23 -28
  155. data/lib/active_record/relation/from_clause.rb +4 -0
  156. data/lib/active_record/relation/merger.rb +12 -17
  157. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  158. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  159. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  160. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  161. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  162. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  163. data/lib/active_record/relation/predicate_builder.rb +5 -11
  164. data/lib/active_record/relation/query_attribute.rb +13 -8
  165. data/lib/active_record/relation/query_methods.rb +232 -69
  166. data/lib/active_record/relation/spawn_methods.rb +1 -2
  167. data/lib/active_record/relation/where_clause.rb +14 -11
  168. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  169. data/lib/active_record/relation.rb +326 -81
  170. data/lib/active_record/result.rb +30 -12
  171. data/lib/active_record/sanitization.rb +32 -40
  172. data/lib/active_record/schema.rb +2 -11
  173. data/lib/active_record/schema_dumper.rb +22 -7
  174. data/lib/active_record/schema_migration.rb +6 -2
  175. data/lib/active_record/scoping/default.rb +4 -6
  176. data/lib/active_record/scoping/named.rb +25 -16
  177. data/lib/active_record/scoping.rb +8 -9
  178. data/lib/active_record/statement_cache.rb +30 -3
  179. data/lib/active_record/store.rb +87 -8
  180. data/lib/active_record/suppressor.rb +2 -2
  181. data/lib/active_record/table_metadata.rb +23 -15
  182. data/lib/active_record/tasks/database_tasks.rb +194 -25
  183. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
  184. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
  185. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
  186. data/lib/active_record/test_databases.rb +23 -0
  187. data/lib/active_record/test_fixtures.rb +243 -0
  188. data/lib/active_record/timestamp.rb +39 -26
  189. data/lib/active_record/touch_later.rb +5 -4
  190. data/lib/active_record/transactions.rb +64 -73
  191. data/lib/active_record/translation.rb +1 -1
  192. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  193. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  194. data/lib/active_record/type/serialized.rb +0 -1
  195. data/lib/active_record/type/time.rb +10 -0
  196. data/lib/active_record/type/type_map.rb +0 -1
  197. data/lib/active_record/type/unsigned_integer.rb +0 -1
  198. data/lib/active_record/type.rb +3 -5
  199. data/lib/active_record/type_caster/connection.rb +15 -14
  200. data/lib/active_record/type_caster/map.rb +1 -4
  201. data/lib/active_record/validations/associated.rb +0 -1
  202. data/lib/active_record/validations/uniqueness.rb +15 -27
  203. data/lib/active_record/validations.rb +3 -3
  204. data/lib/active_record.rb +10 -2
  205. data/lib/arel/alias_predication.rb +9 -0
  206. data/lib/arel/attributes/attribute.rb +37 -0
  207. data/lib/arel/attributes.rb +22 -0
  208. data/lib/arel/collectors/bind.rb +24 -0
  209. data/lib/arel/collectors/composite.rb +31 -0
  210. data/lib/arel/collectors/plain_string.rb +20 -0
  211. data/lib/arel/collectors/sql_string.rb +20 -0
  212. data/lib/arel/collectors/substitute_binds.rb +28 -0
  213. data/lib/arel/crud.rb +42 -0
  214. data/lib/arel/delete_manager.rb +18 -0
  215. data/lib/arel/errors.rb +9 -0
  216. data/lib/arel/expressions.rb +29 -0
  217. data/lib/arel/factory_methods.rb +49 -0
  218. data/lib/arel/insert_manager.rb +49 -0
  219. data/lib/arel/math.rb +45 -0
  220. data/lib/arel/nodes/and.rb +32 -0
  221. data/lib/arel/nodes/ascending.rb +23 -0
  222. data/lib/arel/nodes/binary.rb +52 -0
  223. data/lib/arel/nodes/bind_param.rb +36 -0
  224. data/lib/arel/nodes/case.rb +55 -0
  225. data/lib/arel/nodes/casted.rb +50 -0
  226. data/lib/arel/nodes/comment.rb +29 -0
  227. data/lib/arel/nodes/count.rb +12 -0
  228. data/lib/arel/nodes/delete_statement.rb +45 -0
  229. data/lib/arel/nodes/descending.rb +23 -0
  230. data/lib/arel/nodes/equality.rb +18 -0
  231. data/lib/arel/nodes/extract.rb +24 -0
  232. data/lib/arel/nodes/false.rb +16 -0
  233. data/lib/arel/nodes/full_outer_join.rb +8 -0
  234. data/lib/arel/nodes/function.rb +44 -0
  235. data/lib/arel/nodes/grouping.rb +8 -0
  236. data/lib/arel/nodes/in.rb +8 -0
  237. data/lib/arel/nodes/infix_operation.rb +80 -0
  238. data/lib/arel/nodes/inner_join.rb +8 -0
  239. data/lib/arel/nodes/insert_statement.rb +37 -0
  240. data/lib/arel/nodes/join_source.rb +20 -0
  241. data/lib/arel/nodes/matches.rb +18 -0
  242. data/lib/arel/nodes/named_function.rb +23 -0
  243. data/lib/arel/nodes/node.rb +50 -0
  244. data/lib/arel/nodes/node_expression.rb +13 -0
  245. data/lib/arel/nodes/outer_join.rb +8 -0
  246. data/lib/arel/nodes/over.rb +15 -0
  247. data/lib/arel/nodes/regexp.rb +16 -0
  248. data/lib/arel/nodes/right_outer_join.rb +8 -0
  249. data/lib/arel/nodes/select_core.rb +67 -0
  250. data/lib/arel/nodes/select_statement.rb +41 -0
  251. data/lib/arel/nodes/sql_literal.rb +16 -0
  252. data/lib/arel/nodes/string_join.rb +11 -0
  253. data/lib/arel/nodes/table_alias.rb +27 -0
  254. data/lib/arel/nodes/terminal.rb +16 -0
  255. data/lib/arel/nodes/true.rb +16 -0
  256. data/lib/arel/nodes/unary.rb +45 -0
  257. data/lib/arel/nodes/unary_operation.rb +20 -0
  258. data/lib/arel/nodes/unqualified_column.rb +22 -0
  259. data/lib/arel/nodes/update_statement.rb +41 -0
  260. data/lib/arel/nodes/values_list.rb +9 -0
  261. data/lib/arel/nodes/window.rb +126 -0
  262. data/lib/arel/nodes/with.rb +11 -0
  263. data/lib/arel/nodes.rb +68 -0
  264. data/lib/arel/order_predications.rb +13 -0
  265. data/lib/arel/predications.rb +256 -0
  266. data/lib/arel/select_manager.rb +271 -0
  267. data/lib/arel/table.rb +110 -0
  268. data/lib/arel/tree_manager.rb +72 -0
  269. data/lib/arel/update_manager.rb +34 -0
  270. data/lib/arel/visitors/depth_first.rb +203 -0
  271. data/lib/arel/visitors/dot.rb +296 -0
  272. data/lib/arel/visitors/ibm_db.rb +34 -0
  273. data/lib/arel/visitors/informix.rb +62 -0
  274. data/lib/arel/visitors/mssql.rb +156 -0
  275. data/lib/arel/visitors/mysql.rb +83 -0
  276. data/lib/arel/visitors/oracle.rb +158 -0
  277. data/lib/arel/visitors/oracle12.rb +65 -0
  278. data/lib/arel/visitors/postgresql.rb +109 -0
  279. data/lib/arel/visitors/sqlite.rb +38 -0
  280. data/lib/arel/visitors/to_sql.rb +888 -0
  281. data/lib/arel/visitors/visitor.rb +45 -0
  282. data/lib/arel/visitors/where_sql.rb +22 -0
  283. data/lib/arel/visitors.rb +20 -0
  284. data/lib/arel/window_predications.rb +9 -0
  285. data/lib/arel.rb +62 -0
  286. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  287. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  288. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  289. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  290. data/lib/rails/generators/active_record/migration.rb +14 -2
  291. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  292. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  293. metadata +116 -29
  294. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -11,8 +11,6 @@ require "active_record/connection_adapters/mysql/schema_dumper"
11
11
  require "active_record/connection_adapters/mysql/schema_statements"
12
12
  require "active_record/connection_adapters/mysql/type_metadata"
13
13
 
14
- require "active_support/core_ext/string/strip"
15
-
16
14
  module ActiveRecord
17
15
  module ConnectionAdapters
18
16
  class AbstractMysqlAdapter < AbstractAdapter
@@ -31,7 +29,7 @@ module ActiveRecord
31
29
  NATIVE_DATABASE_TYPES = {
32
30
  primary_key: "bigint auto_increment PRIMARY KEY",
33
31
  string: { name: "varchar", limit: 255 },
34
- text: { name: "text", limit: 65535 },
32
+ text: { name: "text" },
35
33
  integer: { name: "int", limit: 4 },
36
34
  float: { name: "float", limit: 24 },
37
35
  decimal: { name: "decimal" },
@@ -39,41 +37,43 @@ module ActiveRecord
39
37
  timestamp: { name: "timestamp" },
40
38
  time: { name: "time" },
41
39
  date: { name: "date" },
42
- binary: { name: "blob", limit: 65535 },
40
+ binary: { name: "blob" },
41
+ blob: { name: "blob" },
43
42
  boolean: { name: "tinyint", limit: 1 },
44
43
  json: { name: "json" },
45
44
  }
46
45
 
47
46
  class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
48
- private def dealloc(stmt)
49
- stmt[:stmt].close
50
- end
47
+ private
48
+ def dealloc(stmt)
49
+ stmt.close
50
+ end
51
51
  end
52
52
 
53
53
  def initialize(connection, logger, connection_options, config)
54
54
  super(connection, logger, config)
55
-
56
- @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
57
-
58
- if version < "5.1.10"
59
- raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.1.10."
60
- end
61
55
  end
62
56
 
63
- def version #:nodoc:
64
- @version ||= Version.new(version_string)
57
+ def get_database_version #:nodoc:
58
+ full_version_string = get_full_version
59
+ version_string = version_string(full_version_string)
60
+ Version.new(version_string, full_version_string)
65
61
  end
66
62
 
67
63
  def mariadb? # :nodoc:
68
64
  /mariadb/i.match?(full_version)
69
65
  end
70
66
 
71
- def supports_bulk_alter? #:nodoc:
67
+ def supports_bulk_alter?
72
68
  true
73
69
  end
74
70
 
75
71
  def supports_index_sort_order?
76
- !mariadb? && version >= "8.0.1"
72
+ !mariadb? && database_version >= "8.0.1"
73
+ end
74
+
75
+ def supports_expression_index?
76
+ !mariadb? && database_version >= "8.0.13"
77
77
  end
78
78
 
79
79
  def supports_transaction_isolation?
@@ -97,18 +97,23 @@ module ActiveRecord
97
97
  end
98
98
 
99
99
  def supports_datetime_with_precision?
100
- if mariadb?
101
- version >= "5.3.0"
102
- else
103
- version >= "5.6.4"
104
- end
100
+ mariadb? || database_version >= "5.6.4"
105
101
  end
106
102
 
107
103
  def supports_virtual_columns?
104
+ mariadb? || database_version >= "5.7.5"
105
+ end
106
+
107
+ # See https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html for more details.
108
+ def supports_optimizer_hints?
109
+ !mariadb? && database_version >= "5.7.7"
110
+ end
111
+
112
+ def supports_common_table_expressions?
108
113
  if mariadb?
109
- version >= "5.2.0"
114
+ database_version >= "10.2.1"
110
115
  else
111
- version >= "5.7.5"
116
+ database_version >= "8.0.1"
112
117
  end
113
118
  end
114
119
 
@@ -116,6 +121,14 @@ module ActiveRecord
116
121
  true
117
122
  end
118
123
 
124
+ def supports_insert_on_duplicate_skip?
125
+ true
126
+ end
127
+
128
+ def supports_insert_on_duplicate_update?
129
+ true
130
+ end
131
+
119
132
  def get_advisory_lock(lock_name, timeout = 0) # :nodoc:
120
133
  query_value("SELECT GET_LOCK(#{quote(lock_name.to_s)}, #{timeout})") == 1
121
134
  end
@@ -129,7 +142,7 @@ module ActiveRecord
129
142
  end
130
143
 
131
144
  def index_algorithms
132
- { default: "ALGORITHM = DEFAULT".dup, copy: "ALGORITHM = COPY".dup, inplace: "ALGORITHM = INPLACE".dup }
145
+ { default: +"ALGORITHM = DEFAULT", copy: +"ALGORITHM = COPY", inplace: +"ALGORITHM = INPLACE" }
133
146
  end
134
147
 
135
148
  # HELPER METHODS ===========================================
@@ -161,10 +174,9 @@ module ActiveRecord
161
174
 
162
175
  # CONNECTION MANAGEMENT ====================================
163
176
 
164
- # Clears the prepared statements cache.
165
- def clear_cache!
177
+ def clear_cache! # :nodoc:
166
178
  reload_type_map
167
- @statements.clear
179
+ super
168
180
  end
169
181
 
170
182
  #--
@@ -173,15 +185,17 @@ module ActiveRecord
173
185
 
174
186
  def explain(arel, binds = [])
175
187
  sql = "EXPLAIN #{to_sql(arel, binds)}"
176
- start = Time.now
188
+ start = Concurrent.monotonic_time
177
189
  result = exec_query(sql, "EXPLAIN", binds)
178
- elapsed = Time.now - start
190
+ elapsed = Concurrent.monotonic_time - start
179
191
 
180
192
  MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
181
193
  end
182
194
 
183
195
  # Executes the SQL statement in the context of this connection.
184
196
  def execute(sql, name = nil)
197
+ materialize_transactions
198
+
185
199
  log(sql, name) do
186
200
  ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
187
201
  @connection.query(sql)
@@ -213,19 +227,7 @@ module ActiveRecord
213
227
  execute "ROLLBACK"
214
228
  end
215
229
 
216
- # In the simple case, MySQL allows us to place JOINs directly into the UPDATE
217
- # query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
218
- # these, we must use a subquery.
219
- def join_to_update(update, select, key) # :nodoc:
220
- if select.limit || select.offset || select.orders.any?
221
- super
222
- else
223
- update.table select.source
224
- update.wheres = select.constraints
225
- end
226
- end
227
-
228
- def empty_insert_statement_value
230
+ def empty_insert_statement_value(primary_key = nil)
229
231
  "VALUES ()"
230
232
  end
231
233
 
@@ -241,7 +243,7 @@ module ActiveRecord
241
243
  end
242
244
 
243
245
  # Create a new MySQL database with optional <tt>:charset</tt> and <tt>:collation</tt>.
244
- # Charset defaults to utf8.
246
+ # Charset defaults to utf8mb4.
245
247
  #
246
248
  # Example:
247
249
  # create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin'
@@ -250,8 +252,12 @@ module ActiveRecord
250
252
  def create_database(name, options = {})
251
253
  if options[:collation]
252
254
  execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT COLLATE #{quote_table_name(options[:collation])}"
255
+ elsif options[:charset]
256
+ execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset])}"
257
+ elsif row_format_dynamic_by_default?
258
+ execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET `utf8mb4`"
253
259
  else
254
- execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset] || 'utf8')}"
260
+ raise "Configure a supported :charset and ensure innodb_large_prefix is enabled to support indexes on varchar(255) string columns."
255
261
  end
256
262
  end
257
263
 
@@ -277,14 +283,10 @@ module ActiveRecord
277
283
  show_variable "collation_database"
278
284
  end
279
285
 
280
- def truncate(table_name, name = nil)
281
- execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
282
- end
283
-
284
286
  def table_comment(table_name) # :nodoc:
285
287
  scope = quoted_scope(table_name)
286
288
 
287
- query_value(<<-SQL.strip_heredoc, "SCHEMA").presence
289
+ query_value(<<~SQL, "SCHEMA").presence
288
290
  SELECT table_comment
289
291
  FROM information_schema.tables
290
292
  WHERE table_schema = #{scope[:schema]}
@@ -292,22 +294,8 @@ module ActiveRecord
292
294
  SQL
293
295
  end
294
296
 
295
- def bulk_change_table(table_name, operations) #:nodoc:
296
- sqls = operations.flat_map do |command, args|
297
- table, arguments = args.shift, args
298
- method = :"#{command}_for_alter"
299
-
300
- if respond_to?(method, true)
301
- send(method, table, *arguments)
302
- else
303
- raise "Unknown method called : #{method}(#{arguments.inspect})"
304
- end
305
- end.join(", ")
306
-
307
- execute("ALTER TABLE #{quote_table_name(table_name)} #{sqls}")
308
- end
309
-
310
- def change_table_comment(table_name, comment) #:nodoc:
297
+ def change_table_comment(table_name, comment_or_changes) # :nodoc:
298
+ comment = extract_new_comment_value(comment_or_changes)
311
299
  comment = "" if comment.nil?
312
300
  execute("ALTER TABLE #{quote_table_name(table_name)} COMMENT #{quote(comment)}")
313
301
  end
@@ -363,7 +351,8 @@ module ActiveRecord
363
351
  change_column table_name, column_name, nil, null: null
364
352
  end
365
353
 
366
- def change_column_comment(table_name, column_name, comment) #:nodoc:
354
+ def change_column_comment(table_name, column_name, comment_or_changes) # :nodoc:
355
+ comment = extract_new_comment_value(comment_or_changes)
367
356
  change_column table_name, column_name, nil, comment: comment
368
357
  end
369
358
 
@@ -377,8 +366,8 @@ module ActiveRecord
377
366
  end
378
367
 
379
368
  def add_index(table_name, column_name, options = {}) #:nodoc:
380
- index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, options)
381
- sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}".dup
369
+ index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, **options)
370
+ sql = +"CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}"
382
371
  execute add_sql_comment!(sql, comment)
383
372
  end
384
373
 
@@ -392,7 +381,7 @@ module ActiveRecord
392
381
 
393
382
  scope = quoted_scope(table_name)
394
383
 
395
- fk_info = exec_query(<<-SQL.strip_heredoc, "SCHEMA")
384
+ fk_info = exec_query(<<~SQL, "SCHEMA")
396
385
  SELECT fk.referenced_table_name AS 'to_table',
397
386
  fk.referenced_column_name AS 'primary_key',
398
387
  fk.column_name AS 'column',
@@ -429,12 +418,13 @@ module ActiveRecord
429
418
  create_table_info = create_table_info(table_name)
430
419
 
431
420
  # strip create_definitions and partition_options
432
- raw_table_options = create_table_info.sub(/\A.*\n\) /m, "").sub(/\n\/\*!.*\*\/\n\z/m, "").strip
421
+ # Be aware that `create_table_info` might not include any table options due to `NO_TABLE_OPTIONS` sql mode.
422
+ raw_table_options = create_table_info.sub(/\A.*\n\) ?/m, "").sub(/\n\/\*!.*\*\/\n\z/m, "").strip
433
423
 
434
424
  # strip AUTO_INCREMENT
435
425
  raw_table_options.sub!(/(ENGINE=\w+)(?: AUTO_INCREMENT=\d+)/, '\1')
436
426
 
437
- table_options[:options] = raw_table_options
427
+ table_options[:options] = raw_table_options unless raw_table_options.blank?
438
428
 
439
429
  # strip COMMENT
440
430
  if raw_table_options.sub!(/ COMMENT='.+'/, "")
@@ -444,30 +434,6 @@ module ActiveRecord
444
434
  table_options
445
435
  end
446
436
 
447
- # Maps logical Rails types to MySQL-specific data types.
448
- def type_to_sql(type, limit: nil, precision: nil, scale: nil, unsigned: nil, **) # :nodoc:
449
- sql = \
450
- case type.to_s
451
- when "integer"
452
- integer_to_sql(limit)
453
- when "text"
454
- text_to_sql(limit)
455
- when "blob"
456
- binary_to_sql(limit)
457
- when "binary"
458
- if (0..0xfff) === limit
459
- "varbinary(#{limit})"
460
- else
461
- binary_to_sql(limit)
462
- end
463
- else
464
- super
465
- end
466
-
467
- sql = "#{sql} unsigned" if unsigned && type != :primary_key
468
- sql
469
- end
470
-
471
437
  # SHOW VARIABLES LIKE 'name'
472
438
  def show_variable(name)
473
439
  query_value("SELECT @@#{name}", "SCHEMA")
@@ -480,19 +446,36 @@ module ActiveRecord
480
446
 
481
447
  scope = quoted_scope(table_name)
482
448
 
483
- query_values(<<-SQL.strip_heredoc, "SCHEMA")
449
+ query_values(<<~SQL, "SCHEMA")
484
450
  SELECT column_name
485
- FROM information_schema.key_column_usage
486
- WHERE constraint_name = 'PRIMARY'
451
+ FROM information_schema.statistics
452
+ WHERE index_name = 'PRIMARY'
487
453
  AND table_schema = #{scope[:schema]}
488
454
  AND table_name = #{scope[:name]}
489
- ORDER BY ordinal_position
455
+ ORDER BY seq_in_index
490
456
  SQL
491
457
  end
492
458
 
493
- def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
459
+ def default_uniqueness_comparison(attribute, value, klass) # :nodoc:
460
+ column = column_for_attribute(attribute)
461
+
462
+ if column.collation && !column.case_sensitive? && !value.nil?
463
+ ActiveSupport::Deprecation.warn(<<~MSG.squish)
464
+ Uniqueness validator will no longer enforce case sensitive comparison in Rails 6.1.
465
+ To continue case sensitive comparison on the :#{attribute.name} attribute in #{klass} model,
466
+ pass `case_sensitive: true` option explicitly to the uniqueness validator.
467
+ MSG
468
+ attribute.eq(Arel::Nodes::Bin.new(value))
469
+ else
470
+ super
471
+ end
472
+ end
473
+
474
+ def case_sensitive_comparison(attribute, value) # :nodoc:
475
+ column = column_for_attribute(attribute)
476
+
494
477
  if column.collation && !column.case_sensitive?
495
- table[attribute].eq(Arel::Nodes::Bin.new(value))
478
+ attribute.eq(Arel::Nodes::Bin.new(value))
496
479
  else
497
480
  super
498
481
  end
@@ -510,7 +493,7 @@ module ActiveRecord
510
493
  def columns_for_distinct(columns, orders) # :nodoc:
511
494
  order_columns = orders.reject(&:blank?).map { |s|
512
495
  # Convert Arel node to string
513
- s = s.to_sql unless s.is_a?(String)
496
+ s = visitor.compile(s) unless s.is_a?(String)
514
497
  # Remove any ASC/DESC modifiers
515
498
  s.gsub(/\s+(?:ASC|DESC)\b/i, "")
516
499
  }.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" }
@@ -526,40 +509,27 @@ module ActiveRecord
526
509
  index.using == :btree || super
527
510
  end
528
511
 
529
- def insert_fixtures_set(fixture_set, tables_to_delete = [])
530
- with_multi_statements do
531
- super { discard_remaining_results }
532
- end
533
- end
512
+ def build_insert_sql(insert) # :nodoc:
513
+ sql = +"INSERT #{insert.into} #{insert.values_list}"
534
514
 
535
- private
536
- def combine_multi_statements(total_sql)
537
- total_sql.each_with_object([]) do |sql, total_sql_chunks|
538
- previous_packet = total_sql_chunks.last
539
- sql << ";\n"
540
- if max_allowed_packet_reached?(sql, previous_packet) || total_sql_chunks.empty?
541
- total_sql_chunks << sql
542
- else
543
- previous_packet << sql
544
- end
545
- end
515
+ if insert.skip_duplicates?
516
+ no_op_column = quote_column_name(insert.keys.first)
517
+ sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
518
+ elsif insert.update_duplicates?
519
+ sql << " ON DUPLICATE KEY UPDATE "
520
+ sql << insert.updatable_columns.map { |column| "#{column}=VALUES(#{column})" }.join(",")
546
521
  end
547
522
 
548
- def max_allowed_packet_reached?(current_packet, previous_packet)
549
- if current_packet.bytesize > max_allowed_packet
550
- raise ActiveRecordError, "Fixtures set is too large #{current_packet.bytesize}. Consider increasing the max_allowed_packet variable."
551
- elsif previous_packet.nil?
552
- false
553
- else
554
- (current_packet.bytesize + previous_packet.bytesize) > max_allowed_packet
555
- end
556
- end
523
+ sql
524
+ end
557
525
 
558
- def max_allowed_packet
559
- bytes_margin = 2
560
- @max_allowed_packet ||= (show_variable("max_allowed_packet") - bytes_margin)
526
+ def check_version # :nodoc:
527
+ if database_version < "5.5.8"
528
+ raise "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.5.8."
561
529
  end
530
+ end
562
531
 
532
+ private
563
533
  def initialize_type_map(m = type_map)
564
534
  super
565
535
 
@@ -587,24 +557,24 @@ module ActiveRecord
587
557
  m.alias_type %r(bit)i, "binary"
588
558
 
589
559
  m.register_type(%r(enum)i) do |sql_type|
590
- limit = sql_type[/^enum\((.+)\)/i, 1]
560
+ limit = sql_type[/^enum\s*\((.+)\)/i, 1]
591
561
  .split(",").map { |enum| enum.strip.length - 2 }.max
592
562
  MysqlString.new(limit: limit)
593
563
  end
594
564
 
595
565
  m.register_type(%r(^set)i) do |sql_type|
596
- limit = sql_type[/^set\((.+)\)/i, 1]
566
+ limit = sql_type[/^set\s*\((.+)\)/i, 1]
597
567
  .split(",").map { |set| set.strip.length - 1 }.sum - 1
598
568
  MysqlString.new(limit: limit)
599
569
  end
600
570
  end
601
571
 
602
- def register_integer_type(mapping, key, options)
572
+ def register_integer_type(mapping, key, **options)
603
573
  mapping.register_type(key) do |sql_type|
604
574
  if /\bunsigned\b/.match?(sql_type)
605
- Type::UnsignedInteger.new(options)
575
+ Type::UnsignedInteger.new(**options)
606
576
  else
607
- Type::Integer.new(options)
577
+ Type::Integer.new(**options)
608
578
  end
609
579
  end
610
580
  end
@@ -618,9 +588,13 @@ module ActiveRecord
618
588
  end
619
589
 
620
590
  # See https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
591
+ ER_FILSORT_ABORT = 1028
621
592
  ER_DUP_ENTRY = 1062
622
593
  ER_NOT_NULL_VIOLATION = 1048
594
+ ER_NO_REFERENCED_ROW = 1216
595
+ ER_ROW_IS_REFERENCED = 1217
623
596
  ER_DO_NOT_HAVE_DEFAULT = 1364
597
+ ER_ROW_IS_REFERENCED_2 = 1451
624
598
  ER_NO_REFERENCED_ROW_2 = 1452
625
599
  ER_DATA_TOO_LONG = 1406
626
600
  ER_OUT_OF_RANGE = 1264
@@ -630,35 +604,36 @@ module ActiveRecord
630
604
  ER_LOCK_WAIT_TIMEOUT = 1205
631
605
  ER_QUERY_INTERRUPTED = 1317
632
606
  ER_QUERY_TIMEOUT = 3024
607
+ ER_FK_INCOMPATIBLE_COLUMNS = 3780
633
608
 
634
- def translate_exception(exception, message)
609
+ def translate_exception(exception, message:, sql:, binds:)
635
610
  case error_number(exception)
636
611
  when ER_DUP_ENTRY
637
- RecordNotUnique.new(message)
638
- when ER_NO_REFERENCED_ROW_2
639
- InvalidForeignKey.new(message)
640
- when ER_CANNOT_ADD_FOREIGN
641
- mismatched_foreign_key(message)
612
+ RecordNotUnique.new(message, sql: sql, binds: binds)
613
+ when ER_NO_REFERENCED_ROW, ER_ROW_IS_REFERENCED, ER_ROW_IS_REFERENCED_2, ER_NO_REFERENCED_ROW_2
614
+ InvalidForeignKey.new(message, sql: sql, binds: binds)
615
+ when ER_CANNOT_ADD_FOREIGN, ER_FK_INCOMPATIBLE_COLUMNS
616
+ mismatched_foreign_key(message, sql: sql, binds: binds)
642
617
  when ER_CANNOT_CREATE_TABLE
643
618
  if message.include?("errno: 150")
644
- mismatched_foreign_key(message)
619
+ mismatched_foreign_key(message, sql: sql, binds: binds)
645
620
  else
646
621
  super
647
622
  end
648
623
  when ER_DATA_TOO_LONG
649
- ValueTooLong.new(message)
624
+ ValueTooLong.new(message, sql: sql, binds: binds)
650
625
  when ER_OUT_OF_RANGE
651
- RangeError.new(message)
626
+ RangeError.new(message, sql: sql, binds: binds)
652
627
  when ER_NOT_NULL_VIOLATION, ER_DO_NOT_HAVE_DEFAULT
653
- NotNullViolation.new(message)
628
+ NotNullViolation.new(message, sql: sql, binds: binds)
654
629
  when ER_LOCK_DEADLOCK
655
- Deadlocked.new(message)
630
+ Deadlocked.new(message, sql: sql, binds: binds)
656
631
  when ER_LOCK_WAIT_TIMEOUT
657
- LockWaitTimeout.new(message)
658
- when ER_QUERY_TIMEOUT
659
- StatementTimeout.new(message)
632
+ LockWaitTimeout.new(message, sql: sql, binds: binds)
633
+ when ER_QUERY_TIMEOUT, ER_FILSORT_ABORT
634
+ StatementTimeout.new(message, sql: sql, binds: binds)
660
635
  when ER_QUERY_INTERRUPTED
661
- QueryCanceled.new(message)
636
+ QueryCanceled.new(message, sql: sql, binds: binds)
662
637
  else
663
638
  super
664
639
  end
@@ -681,7 +656,7 @@ module ActiveRecord
681
656
  end
682
657
 
683
658
  td = create_table_definition(table_name)
684
- cd = td.new_column_definition(column.name, type, options)
659
+ cd = td.new_column_definition(column.name, type, **options)
685
660
  schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
686
661
  end
687
662
 
@@ -695,14 +670,15 @@ module ActiveRecord
695
670
 
696
671
  current_type = exec_query("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE #{quote(column_name)}", "SCHEMA").first["Type"]
697
672
  td = create_table_definition(table_name)
698
- cd = td.new_column_definition(new_column_name, current_type, options)
673
+ cd = td.new_column_definition(new_column_name, current_type, **options)
699
674
  schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
700
675
  end
701
676
 
702
677
  def add_index_for_alter(table_name, column_name, options = {})
703
- index_name, index_type, index_columns, _, index_algorithm, index_using = add_index_options(table_name, column_name, options)
678
+ index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, **options)
704
679
  index_algorithm[0, 0] = ", " if index_algorithm.present?
705
- "ADD #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_algorithm}"
680
+ sql = +"ADD #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_algorithm}"
681
+ add_sql_comment!(sql, comment)
706
682
  end
707
683
 
708
684
  def remove_index_for_alter(table_name, options = {})
@@ -710,30 +686,12 @@ module ActiveRecord
710
686
  "DROP INDEX #{quote_column_name(index_name)}"
711
687
  end
712
688
 
713
- def add_timestamps_for_alter(table_name, options = {})
714
- [add_column_for_alter(table_name, :created_at, :datetime, options), add_column_for_alter(table_name, :updated_at, :datetime, options)]
715
- end
716
-
717
- def remove_timestamps_for_alter(table_name, options = {})
718
- [remove_column_for_alter(table_name, :updated_at), remove_column_for_alter(table_name, :created_at)]
719
- end
720
-
721
- # MySQL is too stupid to create a temporary table for use subquery, so we have
722
- # to give it some prompting in the form of a subsubquery. Ugh!
723
- def subquery_for(key, select)
724
- subselect = select.clone
725
- subselect.projections = [key]
726
-
727
- # Materialize subquery by adding distinct
728
- # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
729
- subselect.distinct unless select.limit || select.offset || select.orders.any?
730
-
731
- key_name = quote_column_name(key.name)
732
- Arel::SelectManager.new(subselect.as("__active_record_temp")).project(Arel.sql(key_name))
733
- end
734
-
735
689
  def supports_rename_index?
736
- mariadb? ? false : version >= "5.7.6"
690
+ if mariadb?
691
+ database_version >= "10.5.2"
692
+ else
693
+ database_version >= "5.7.6"
694
+ end
737
695
  end
738
696
 
739
697
  def configure_connection
@@ -770,7 +728,7 @@ module ActiveRecord
770
728
  # https://dev.mysql.com/doc/refman/5.7/en/set-names.html
771
729
  # (trailing comma because variable_assignments will always have content)
772
730
  if @config[:encoding]
773
- encoding = "NAMES #{@config[:encoding]}".dup
731
+ encoding = +"NAMES #{@config[:encoding]}"
774
732
  encoding << " COLLATE #{@config[:collation]}" if @config[:collation]
775
733
  encoding << ", "
776
734
  end
@@ -786,7 +744,7 @@ module ActiveRecord
786
744
  end.compact.join(", ")
787
745
 
788
746
  # ...and send them all in one query
789
- execute "SET #{encoding} #{sql_mode_assignment} #{variable_assignments}"
747
+ execute("SET #{encoding} #{sql_mode_assignment} #{variable_assignments}", "SCHEMA")
790
748
  end
791
749
 
792
750
  def column_definitions(table_name) # :nodoc:
@@ -803,15 +761,21 @@ module ActiveRecord
803
761
  Arel::Visitors::MySQL.new(self)
804
762
  end
805
763
 
806
- def mismatched_foreign_key(message)
764
+ def build_statement_pool
765
+ StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
766
+ end
767
+
768
+ def mismatched_foreign_key(message, sql:, binds:)
807
769
  match = %r/
808
770
  (?:CREATE|ALTER)\s+TABLE\s*(?:`?\w+`?\.)?`?(?<table>\w+)`?.+?
809
771
  FOREIGN\s+KEY\s*\(`?(?<foreign_key>\w+)`?\)\s*
810
772
  REFERENCES\s*(`?(?<target_table>\w+)`?)\s*\(`?(?<primary_key>\w+)`?\)
811
- /xmi.match(message)
773
+ /xmi.match(sql)
812
774
 
813
775
  options = {
814
776
  message: message,
777
+ sql: sql,
778
+ binds: binds,
815
779
  }
816
780
 
817
781
  if match
@@ -822,42 +786,11 @@ module ActiveRecord
822
786
  options[:primary_key_column] = column_for(match[:target_table], match[:primary_key])
823
787
  end
824
788
 
825
- MismatchedForeignKey.new(options)
789
+ MismatchedForeignKey.new(**options)
826
790
  end
827
791
 
828
- def integer_to_sql(limit) # :nodoc:
829
- case limit
830
- when 1; "tinyint"
831
- when 2; "smallint"
832
- when 3; "mediumint"
833
- when nil, 4; "int"
834
- when 5..8; "bigint"
835
- else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a decimal with scale 0 instead.")
836
- end
837
- end
838
-
839
- def text_to_sql(limit) # :nodoc:
840
- case limit
841
- when 0..0xff; "tinytext"
842
- when nil, 0x100..0xffff; "text"
843
- when 0x10000..0xffffff; "mediumtext"
844
- when 0x1000000..0xffffffff; "longtext"
845
- else raise(ActiveRecordError, "No text type has byte length #{limit}")
846
- end
847
- end
848
-
849
- def binary_to_sql(limit) # :nodoc:
850
- case limit
851
- when 0..0xff; "tinyblob"
852
- when nil, 0x100..0xffff; "blob"
853
- when 0x10000..0xffffff; "mediumblob"
854
- when 0x1000000..0xffffffff; "longblob"
855
- else raise(ActiveRecordError, "No binary type has byte length #{limit}")
856
- end
857
- end
858
-
859
- def version_string
860
- full_version.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
792
+ def version_string(full_version_string)
793
+ full_version_string.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
861
794
  end
862
795
 
863
796
  class MysqlString < Type::String # :nodoc:
@@ -870,7 +803,6 @@ module ActiveRecord
870
803
  end
871
804
 
872
805
  private
873
-
874
806
  def cast_value(value)
875
807
  case value
876
808
  when true then "1"