activerecord 5.1.7 → 5.2.4.3

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 (261) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +556 -685
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -5
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record.rb +11 -4
  8. data/lib/active_record/aggregations.rb +6 -5
  9. data/lib/active_record/association_relation.rb +7 -5
  10. data/lib/active_record/associations.rb +40 -63
  11. data/lib/active_record/associations/alias_tracker.rb +19 -27
  12. data/lib/active_record/associations/association.rb +41 -37
  13. data/lib/active_record/associations/association_scope.rb +38 -50
  14. data/lib/active_record/associations/belongs_to_association.rb +27 -8
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  16. data/lib/active_record/associations/builder/association.rb +4 -7
  17. data/lib/active_record/associations/builder/belongs_to.rb +12 -4
  18. data/lib/active_record/associations/builder/collection_association.rb +3 -3
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  20. data/lib/active_record/associations/builder/has_many.rb +2 -0
  21. data/lib/active_record/associations/builder/has_one.rb +2 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  23. data/lib/active_record/associations/collection_association.rb +59 -47
  24. data/lib/active_record/associations/collection_proxy.rb +20 -49
  25. data/lib/active_record/associations/foreign_association.rb +2 -0
  26. data/lib/active_record/associations/has_many_association.rb +12 -1
  27. data/lib/active_record/associations/has_many_through_association.rb +36 -30
  28. data/lib/active_record/associations/has_one_association.rb +12 -1
  29. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  30. data/lib/active_record/associations/join_dependency.rb +48 -93
  31. data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
  32. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  33. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  34. data/lib/active_record/associations/preloader.rb +18 -38
  35. data/lib/active_record/associations/preloader/association.rb +45 -61
  36. data/lib/active_record/associations/preloader/through_association.rb +71 -79
  37. data/lib/active_record/associations/singular_association.rb +14 -16
  38. data/lib/active_record/associations/through_association.rb +26 -11
  39. data/lib/active_record/attribute_assignment.rb +2 -5
  40. data/lib/active_record/attribute_decorators.rb +3 -2
  41. data/lib/active_record/attribute_methods.rb +65 -24
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +30 -214
  44. data/lib/active_record/attribute_methods/primary_key.rb +7 -6
  45. data/lib/active_record/attribute_methods/query.rb +2 -0
  46. data/lib/active_record/attribute_methods/read.rb +9 -3
  47. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  49. data/lib/active_record/attribute_methods/write.rb +21 -9
  50. data/lib/active_record/attributes.rb +6 -5
  51. data/lib/active_record/autosave_association.rb +35 -19
  52. data/lib/active_record/base.rb +2 -0
  53. data/lib/active_record/callbacks.rb +8 -6
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +2 -0
  56. data/lib/active_record/collection_cache_key.rb +12 -8
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +139 -41
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -31
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +64 -6
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
  70. data/lib/active_record/connection_adapters/column.rb +3 -1
  71. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
  73. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -2
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  101. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +233 -111
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -73
  118. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +22 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +81 -94
  127. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  128. data/lib/active_record/connection_handling.rb +4 -2
  129. data/lib/active_record/core.rb +41 -61
  130. data/lib/active_record/counter_cache.rb +10 -3
  131. data/lib/active_record/define_callbacks.rb +5 -3
  132. data/lib/active_record/dynamic_matchers.rb +9 -9
  133. data/lib/active_record/enum.rb +18 -13
  134. data/lib/active_record/errors.rb +42 -3
  135. data/lib/active_record/explain.rb +3 -1
  136. data/lib/active_record/explain_registry.rb +2 -0
  137. data/lib/active_record/explain_subscriber.rb +2 -0
  138. data/lib/active_record/fixture_set/file.rb +2 -0
  139. data/lib/active_record/fixtures.rb +67 -60
  140. data/lib/active_record/gem_version.rb +5 -3
  141. data/lib/active_record/inheritance.rb +49 -19
  142. data/lib/active_record/integration.rb +58 -19
  143. data/lib/active_record/internal_metadata.rb +2 -0
  144. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  145. data/lib/active_record/locking/optimistic.rb +14 -17
  146. data/lib/active_record/locking/pessimistic.rb +9 -6
  147. data/lib/active_record/log_subscriber.rb +43 -0
  148. data/lib/active_record/migration.rb +189 -139
  149. data/lib/active_record/migration/command_recorder.rb +11 -9
  150. data/lib/active_record/migration/compatibility.rb +47 -9
  151. data/lib/active_record/migration/join_table.rb +2 -0
  152. data/lib/active_record/model_schema.rb +16 -21
  153. data/lib/active_record/nested_attributes.rb +18 -6
  154. data/lib/active_record/no_touching.rb +3 -1
  155. data/lib/active_record/null_relation.rb +2 -0
  156. data/lib/active_record/persistence.rb +167 -16
  157. data/lib/active_record/query_cache.rb +6 -8
  158. data/lib/active_record/querying.rb +4 -2
  159. data/lib/active_record/railtie.rb +62 -6
  160. data/lib/active_record/railties/console_sandbox.rb +2 -0
  161. data/lib/active_record/railties/controller_runtime.rb +2 -0
  162. data/lib/active_record/railties/databases.rake +46 -36
  163. data/lib/active_record/readonly_attributes.rb +3 -2
  164. data/lib/active_record/reflection.rb +108 -194
  165. data/lib/active_record/relation.rb +120 -214
  166. data/lib/active_record/relation/batches.rb +20 -5
  167. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  168. data/lib/active_record/relation/calculations.rb +45 -19
  169. data/lib/active_record/relation/delegation.rb +45 -27
  170. data/lib/active_record/relation/finder_methods.rb +75 -76
  171. data/lib/active_record/relation/from_clause.rb +2 -8
  172. data/lib/active_record/relation/merger.rb +53 -23
  173. data/lib/active_record/relation/predicate_builder.rb +60 -79
  174. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  175. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  176. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  177. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  178. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  179. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  180. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  181. data/lib/active_record/relation/query_attribute.rb +28 -2
  182. data/lib/active_record/relation/query_methods.rb +128 -99
  183. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  184. data/lib/active_record/relation/spawn_methods.rb +4 -2
  185. data/lib/active_record/relation/where_clause.rb +65 -68
  186. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  187. data/lib/active_record/result.rb +2 -0
  188. data/lib/active_record/runtime_registry.rb +2 -0
  189. data/lib/active_record/sanitization.rb +129 -121
  190. data/lib/active_record/schema.rb +4 -2
  191. data/lib/active_record/schema_dumper.rb +36 -26
  192. data/lib/active_record/schema_migration.rb +2 -0
  193. data/lib/active_record/scoping.rb +9 -8
  194. data/lib/active_record/scoping/default.rb +8 -9
  195. data/lib/active_record/scoping/named.rb +23 -7
  196. data/lib/active_record/secure_token.rb +2 -0
  197. data/lib/active_record/serialization.rb +2 -0
  198. data/lib/active_record/statement_cache.rb +23 -13
  199. data/lib/active_record/store.rb +3 -1
  200. data/lib/active_record/suppressor.rb +2 -0
  201. data/lib/active_record/table_metadata.rb +12 -3
  202. data/lib/active_record/tasks/database_tasks.rb +25 -14
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  206. data/lib/active_record/timestamp.rb +6 -6
  207. data/lib/active_record/touch_later.rb +2 -0
  208. data/lib/active_record/transactions.rb +33 -28
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type.rb +4 -1
  211. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  212. data/lib/active_record/type/date.rb +2 -0
  213. data/lib/active_record/type/date_time.rb +2 -0
  214. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  215. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  216. data/lib/active_record/type/internal/timezone.rb +2 -0
  217. data/lib/active_record/type/json.rb +30 -0
  218. data/lib/active_record/type/serialized.rb +2 -0
  219. data/lib/active_record/type/text.rb +2 -0
  220. data/lib/active_record/type/time.rb +2 -0
  221. data/lib/active_record/type/type_map.rb +2 -0
  222. data/lib/active_record/type/unsigned_integer.rb +2 -0
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/type_caster/connection.rb +2 -0
  225. data/lib/active_record/type_caster/map.rb +3 -1
  226. data/lib/active_record/validations.rb +2 -0
  227. data/lib/active_record/validations/absence.rb +2 -0
  228. data/lib/active_record/validations/associated.rb +2 -0
  229. data/lib/active_record/validations/length.rb +2 -0
  230. data/lib/active_record/validations/presence.rb +2 -0
  231. data/lib/active_record/validations/uniqueness.rb +35 -5
  232. data/lib/active_record/version.rb +2 -0
  233. data/lib/rails/generators/active_record.rb +3 -1
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration.rb +2 -0
  237. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  238. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  239. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  241. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  243. metadata +23 -36
  244. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  245. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  246. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  248. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  249. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  250. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -122
  254. data/lib/active_record/attribute_set.rb +0 -113
  255. data/lib/active_record/attribute_set/builder.rb +0 -126
  256. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  257. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  258. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  259. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  260. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  261. data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record/connection_adapters/abstract_adapter"
2
4
  require "active_record/connection_adapters/statement_pool"
3
5
  require "active_record/connection_adapters/mysql/column"
@@ -15,21 +17,8 @@ module ActiveRecord
15
17
  module ConnectionAdapters
16
18
  class AbstractMysqlAdapter < AbstractAdapter
17
19
  include MySQL::Quoting
18
- include MySQL::ColumnDumper
19
20
  include MySQL::SchemaStatements
20
21
 
21
- def update_table_definition(table_name, base) # :nodoc:
22
- MySQL::Table.new(table_name, base)
23
- end
24
-
25
- def schema_creation # :nodoc:
26
- MySQL::SchemaCreation.new(self)
27
- end
28
-
29
- def arel_visitor # :nodoc:
30
- Arel::Visitors::MySQL.new(self)
31
- end
32
-
33
22
  ##
34
23
  # :singleton-method:
35
24
  # By default, the Mysql2Adapter will consider all columns of type <tt>tinyint(1)</tt>
@@ -37,15 +26,14 @@ module ActiveRecord
37
26
  # to your application.rb file:
38
27
  #
39
28
  # ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = false
40
- class_attribute :emulate_booleans
41
- self.emulate_booleans = true
29
+ class_attribute :emulate_booleans, default: true
42
30
 
43
31
  NATIVE_DATABASE_TYPES = {
44
32
  primary_key: "bigint auto_increment PRIMARY KEY",
45
33
  string: { name: "varchar", limit: 255 },
46
34
  text: { name: "text", limit: 65535 },
47
35
  integer: { name: "int", limit: 4 },
48
- float: { name: "float" },
36
+ float: { name: "float", limit: 24 },
49
37
  decimal: { name: "decimal" },
50
38
  datetime: { name: "datetime" },
51
39
  timestamp: { name: "timestamp" },
@@ -56,10 +44,7 @@ module ActiveRecord
56
44
  json: { name: "json" },
57
45
  }
58
46
 
59
- INDEX_TYPES = [:fulltext, :spatial]
60
- INDEX_USINGS = [:btree, :hash]
61
-
62
- class StatementPool < ConnectionAdapters::StatementPool
47
+ class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
63
48
  private def dealloc(stmt)
64
49
  stmt[:stmt].close
65
50
  end
@@ -87,16 +72,8 @@ module ActiveRecord
87
72
  true
88
73
  end
89
74
 
90
- # Returns true, since this connection adapter supports prepared statement
91
- # caching.
92
- def supports_statement_cache?
93
- true
94
- end
95
-
96
- # Technically MySQL allows to create indexes with the sort order syntax
97
- # but at the moment (5.5) it doesn't yet implement them
98
75
  def supports_index_sort_order?
99
- true
76
+ !mariadb? && version >= "8.0.1"
100
77
  end
101
78
 
102
79
  def supports_transaction_isolation?
@@ -152,7 +129,7 @@ module ActiveRecord
152
129
  end
153
130
 
154
131
  def index_algorithms
155
- { default: "ALGORITHM = DEFAULT", copy: "ALGORITHM = COPY", inplace: "ALGORITHM = INPLACE" }
132
+ { default: "ALGORITHM = DEFAULT".dup, copy: "ALGORITHM = COPY".dup, inplace: "ALGORITHM = INPLACE".dup }
156
133
  end
157
134
 
158
135
  # HELPER METHODS ===========================================
@@ -163,10 +140,6 @@ module ActiveRecord
163
140
  raise NotImplementedError
164
141
  end
165
142
 
166
- def new_column(*args) #:nodoc:
167
- MySQL::Column.new(*args)
168
- end
169
-
170
143
  # Must return the MySQL error number from the exception, if the exception has an
171
144
  # error number.
172
145
  def error_number(exception) # :nodoc:
@@ -276,7 +249,7 @@ module ActiveRecord
276
249
  # create_database 'matt_development', charset: :big5
277
250
  def create_database(name, options = {})
278
251
  if options[:collation]
279
- execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset] || 'utf8')} COLLATE #{quote_table_name(options[:collation])}"
252
+ execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT COLLATE #{quote_table_name(options[:collation])}"
280
253
  else
281
254
  execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset] || 'utf8')}"
282
255
  end
@@ -308,50 +281,10 @@ module ActiveRecord
308
281
  execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
309
282
  end
310
283
 
311
- # Returns an array of indexes for the given table.
312
- def indexes(table_name, name = nil) #:nodoc:
313
- if name
314
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
315
- Passing name to #indexes is deprecated without replacement.
316
- MSG
317
- end
318
-
319
- indexes = []
320
- current_index = nil
321
- execute_and_free("SHOW KEYS FROM #{quote_table_name(table_name)}", "SCHEMA") do |result|
322
- each_hash(result) do |row|
323
- if current_index != row[:Key_name]
324
- next if row[:Key_name] == "PRIMARY" # skip the primary key
325
- current_index = row[:Key_name]
326
-
327
- mysql_index_type = row[:Index_type].downcase.to_sym
328
- index_type = INDEX_TYPES.include?(mysql_index_type) ? mysql_index_type : nil
329
- index_using = INDEX_USINGS.include?(mysql_index_type) ? mysql_index_type : nil
330
- indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique].to_i == 0, [], {}, nil, nil, index_type, index_using, row[:Index_comment].presence)
331
- end
332
-
333
- indexes.last.columns << row[:Column_name]
334
- indexes.last.lengths.merge!(row[:Column_name] => row[:Sub_part].to_i) if row[:Sub_part]
335
- end
336
- end
337
-
338
- indexes
339
- end
340
-
341
- def new_column_from_field(table_name, field) # :nodoc:
342
- type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
343
- if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\(\))?\z/i.match?(field[:Default])
344
- default, default_function = nil, "CURRENT_TIMESTAMP"
345
- else
346
- default, default_function = field[:Default], nil
347
- end
348
- new_column(field[:Field], default, type_metadata, field[:Null] == "YES", table_name, default_function, field[:Collation], comment: field[:Comment].presence)
349
- end
350
-
351
284
  def table_comment(table_name) # :nodoc:
352
285
  scope = quoted_scope(table_name)
353
286
 
354
- query_value(<<-SQL.strip_heredoc, "SCHEMA")
287
+ query_value(<<-SQL.strip_heredoc, "SCHEMA").presence
355
288
  SELECT table_comment
356
289
  FROM information_schema.tables
357
290
  WHERE table_schema = #{scope[:schema]}
@@ -359,14 +292,10 @@ module ActiveRecord
359
292
  SQL
360
293
  end
361
294
 
362
- def create_table(table_name, **options) #:nodoc:
363
- super(table_name, options: "ENGINE=InnoDB", **options)
364
- end
365
-
366
295
  def bulk_change_table(table_name, operations) #:nodoc:
367
296
  sqls = operations.flat_map do |command, args|
368
297
  table, arguments = args.shift, args
369
- method = :"#{command}_sql"
298
+ method = :"#{command}_for_alter"
370
299
 
371
300
  if respond_to?(method, true)
372
301
  send(method, table, *arguments)
@@ -378,6 +307,11 @@ module ActiveRecord
378
307
  execute("ALTER TABLE #{quote_table_name(table_name)} #{sqls}")
379
308
  end
380
309
 
310
+ def change_table_comment(table_name, comment) #:nodoc:
311
+ comment = "" if comment.nil?
312
+ execute("ALTER TABLE #{quote_table_name(table_name)} COMMENT #{quote(comment)}")
313
+ end
314
+
381
315
  # Renames a table.
382
316
  #
383
317
  # Example:
@@ -418,32 +352,33 @@ module ActiveRecord
418
352
 
419
353
  def change_column_default(table_name, column_name, default_or_changes) #:nodoc:
420
354
  default = extract_new_default_value(default_or_changes)
421
- column = column_for(table_name, column_name)
422
- change_column table_name, column_name, column.sql_type, default: default
355
+ change_column table_name, column_name, nil, default: default
423
356
  end
424
357
 
425
358
  def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
426
- column = column_for(table_name, column_name)
427
-
428
359
  unless null || default.nil?
429
360
  execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
430
361
  end
431
362
 
432
- change_column table_name, column_name, column.sql_type, null: null
363
+ change_column table_name, column_name, nil, null: null
364
+ end
365
+
366
+ def change_column_comment(table_name, column_name, comment) #:nodoc:
367
+ change_column table_name, column_name, nil, comment: comment
433
368
  end
434
369
 
435
370
  def change_column(table_name, column_name, type, options = {}) #:nodoc:
436
- execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_sql(table_name, column_name, type, options)}")
371
+ execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_for_alter(table_name, column_name, type, options)}")
437
372
  end
438
373
 
439
374
  def rename_column(table_name, column_name, new_column_name) #:nodoc:
440
- execute("ALTER TABLE #{quote_table_name(table_name)} #{rename_column_sql(table_name, column_name, new_column_name)}")
375
+ execute("ALTER TABLE #{quote_table_name(table_name)} #{rename_column_for_alter(table_name, column_name, new_column_name)}")
441
376
  rename_column_indexes(table_name, column_name, new_column_name)
442
377
  end
443
378
 
444
379
  def add_index(table_name, column_name, options = {}) #:nodoc:
445
380
  index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, options)
446
- sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}"
381
+ sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}".dup
447
382
  execute add_sql_comment!(sql, comment)
448
383
  end
449
384
 
@@ -529,7 +464,7 @@ module ActiveRecord
529
464
  super
530
465
  end
531
466
 
532
- sql << " unsigned" if unsigned && type != :primary_key
467
+ sql = "#{sql} unsigned" if unsigned && type != :primary_key
533
468
  sql
534
469
  end
535
470
 
@@ -580,7 +515,7 @@ module ActiveRecord
580
515
  s.gsub(/\s+(?:ASC|DESC)\b/i, "")
581
516
  }.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" }
582
517
 
583
- [super, *order_columns].join(", ")
518
+ (order_columns << super).join(", ")
584
519
  end
585
520
 
586
521
  def strict_mode?
@@ -591,9 +526,41 @@ module ActiveRecord
591
526
  index.using == :btree || super
592
527
  end
593
528
 
529
+ def insert_fixtures_set(fixture_set, tables_to_delete = [])
530
+ with_multi_statements do
531
+ super { discard_remaining_results }
532
+ end
533
+ end
534
+
594
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
546
+ end
547
+
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
595
557
 
596
- def initialize_type_map(m)
558
+ def max_allowed_packet
559
+ bytes_margin = 2
560
+ @max_allowed_packet ||= (show_variable("max_allowed_packet") - bytes_margin)
561
+ end
562
+
563
+ def initialize_type_map(m = type_map)
597
564
  super
598
565
 
599
566
  register_class_with_limit m, %r(char)i, MysqlString
@@ -608,7 +575,6 @@ module ActiveRecord
608
575
  m.register_type %r(longblob)i, Type::Binary.new(limit: 2**32 - 1)
609
576
  m.register_type %r(^float)i, Type::Float.new(limit: 24)
610
577
  m.register_type %r(^double)i, Type::Float.new(limit: 53)
611
- m.register_type %r(^json)i, MysqlJson.new
612
578
 
613
579
  register_integer_type m, %r(^bigint)i, limit: 8
614
580
  register_integer_type m, %r(^int)i, limit: 4
@@ -651,29 +617,6 @@ module ActiveRecord
651
617
  end
652
618
  end
653
619
 
654
- def fetch_type_metadata(sql_type, extra = "")
655
- MySQL::TypeMetadata.new(super(sql_type), extra: extra)
656
- end
657
-
658
- def add_index_length(quoted_columns, **options)
659
- if length = options[:length]
660
- case length
661
- when Hash
662
- length = length.symbolize_keys
663
- quoted_columns.each { |name, column| column << "(#{length[name]})" if length[name].present? }
664
- when Integer
665
- quoted_columns.each { |name, column| column << "(#{length})" }
666
- end
667
- end
668
-
669
- quoted_columns
670
- end
671
-
672
- def add_options_for_index_columns(quoted_columns, **options)
673
- quoted_columns = add_index_length(quoted_columns, options)
674
- super
675
- end
676
-
677
620
  # See https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
678
621
  ER_DUP_ENTRY = 1062
679
622
  ER_NOT_NULL_VIOLATION = 1048
@@ -684,6 +627,9 @@ module ActiveRecord
684
627
  ER_LOCK_DEADLOCK = 1213
685
628
  ER_CANNOT_ADD_FOREIGN = 1215
686
629
  ER_CANNOT_CREATE_TABLE = 1005
630
+ ER_LOCK_WAIT_TIMEOUT = 1205
631
+ ER_QUERY_INTERRUPTED = 1317
632
+ ER_QUERY_TIMEOUT = 3024
687
633
 
688
634
  def translate_exception(exception, message)
689
635
  case error_number(exception)
@@ -707,19 +653,20 @@ module ActiveRecord
707
653
  NotNullViolation.new(message)
708
654
  when ER_LOCK_DEADLOCK
709
655
  Deadlocked.new(message)
656
+ when ER_LOCK_WAIT_TIMEOUT
657
+ LockWaitTimeout.new(message)
658
+ when ER_QUERY_TIMEOUT
659
+ StatementTimeout.new(message)
660
+ when ER_QUERY_INTERRUPTED
661
+ QueryCanceled.new(message)
710
662
  else
711
663
  super
712
664
  end
713
665
  end
714
666
 
715
- def add_column_sql(table_name, column_name, type, options = {})
716
- td = create_table_definition(table_name)
717
- cd = td.new_column_definition(column_name, type, options)
718
- schema_creation.accept(AddColumnDefinition.new(cd))
719
- end
720
-
721
- def change_column_sql(table_name, column_name, type, options = {})
667
+ def change_column_for_alter(table_name, column_name, type, options = {})
722
668
  column = column_for(table_name, column_name)
669
+ type ||= column.sql_type
723
670
 
724
671
  unless options.key?(:default)
725
672
  options[:default] = column.default
@@ -738,7 +685,7 @@ module ActiveRecord
738
685
  schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
739
686
  end
740
687
 
741
- def rename_column_sql(table_name, column_name, new_column_name)
688
+ def rename_column_for_alter(table_name, column_name, new_column_name)
742
689
  column = column_for(table_name, column_name)
743
690
  options = {
744
691
  default: column.default,
@@ -752,46 +699,37 @@ module ActiveRecord
752
699
  schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
753
700
  end
754
701
 
755
- def remove_column_sql(table_name, column_name, type = nil, options = {})
756
- "DROP #{quote_column_name(column_name)}"
757
- end
758
-
759
- def remove_columns_sql(table_name, *column_names)
760
- column_names.map { |column_name| remove_column_sql(table_name, column_name) }
761
- end
762
-
763
- def add_index_sql(table_name, column_name, options = {})
702
+ def add_index_for_alter(table_name, column_name, options = {})
764
703
  index_name, index_type, index_columns, _, index_algorithm, index_using = add_index_options(table_name, column_name, options)
765
704
  index_algorithm[0, 0] = ", " if index_algorithm.present?
766
705
  "ADD #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_algorithm}"
767
706
  end
768
707
 
769
- def remove_index_sql(table_name, options = {})
708
+ def remove_index_for_alter(table_name, options = {})
770
709
  index_name = index_name_for_remove(table_name, options)
771
- "DROP INDEX #{index_name}"
710
+ "DROP INDEX #{quote_column_name(index_name)}"
772
711
  end
773
712
 
774
- def add_timestamps_sql(table_name, options = {})
775
- [add_column_sql(table_name, :created_at, :datetime, options), add_column_sql(table_name, :updated_at, :datetime, options)]
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)]
776
715
  end
777
716
 
778
- def remove_timestamps_sql(table_name, options = {})
779
- [remove_column_sql(table_name, :updated_at), remove_column_sql(table_name, :created_at)]
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)]
780
719
  end
781
720
 
782
721
  # MySQL is too stupid to create a temporary table for use subquery, so we have
783
722
  # to give it some prompting in the form of a subsubquery. Ugh!
784
723
  def subquery_for(key, select)
785
- subsubselect = select.clone
786
- subsubselect.projections = [key]
724
+ subselect = select.clone
725
+ subselect.projections = [key]
787
726
 
788
727
  # Materialize subquery by adding distinct
789
728
  # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
790
- subsubselect.distinct unless select.limit || select.offset || select.orders.any?
729
+ subselect.distinct unless select.limit || select.offset || select.orders.any?
791
730
 
792
- subselect = Arel::SelectManager.new(select.engine)
793
- subselect.project Arel.sql(key.name)
794
- subselect.from subsubselect.as("__active_record_temp")
731
+ key_name = quote_column_name(key.name)
732
+ Arel::SelectManager.new(subselect.as("__active_record_temp")).project(Arel.sql(key_name))
795
733
  end
796
734
 
797
735
  def supports_rename_index?
@@ -812,7 +750,7 @@ module ActiveRecord
812
750
  defaults = [":default", :default].to_set
813
751
 
814
752
  # Make MySQL reject illegal values rather than truncating or blanking them, see
815
- # http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_strict_all_tables
753
+ # https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_strict_all_tables
816
754
  # If the user has provided another value for sql_mode, don't replace it.
817
755
  if sql_mode = variables.delete("sql_mode")
818
756
  sql_mode = quote(sql_mode)
@@ -829,10 +767,10 @@ module ActiveRecord
829
767
  sql_mode_assignment = "@@SESSION.sql_mode = #{sql_mode}, " if sql_mode
830
768
 
831
769
  # NAMES does not have an equals sign, see
832
- # http://dev.mysql.com/doc/refman/5.7/en/set-statement.html#id944430
770
+ # https://dev.mysql.com/doc/refman/5.7/en/set-names.html
833
771
  # (trailing comma because variable_assignments will always have content)
834
772
  if @config[:encoding]
835
- encoding = "NAMES #{@config[:encoding]}"
773
+ encoding = "NAMES #{@config[:encoding]}".dup
836
774
  encoding << " COLLATE #{@config[:collation]}" if @config[:collation]
837
775
  encoding << ", "
838
776
  end
@@ -857,19 +795,12 @@ module ActiveRecord
857
795
  end
858
796
  end
859
797
 
860
- def extract_foreign_key_action(specifier) # :nodoc:
861
- case specifier
862
- when "CASCADE"; :cascade
863
- when "SET NULL"; :nullify
864
- end
865
- end
866
-
867
798
  def create_table_info(table_name) # :nodoc:
868
799
  exec_query("SHOW CREATE TABLE #{quote_table_name(table_name)}", "SCHEMA").first["Create Table"]
869
800
  end
870
801
 
871
- def create_table_definition(*args) # :nodoc:
872
- MySQL::TableDefinition.new(*args)
802
+ def arel_visitor
803
+ Arel::Visitors::MySQL.new(self)
873
804
  end
874
805
 
875
806
  def mismatched_foreign_key(message)
@@ -929,14 +860,11 @@ module ActiveRecord
929
860
  full_version.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
930
861
  end
931
862
 
932
- class MysqlJson < Type::Internal::AbstractJson # :nodoc:
933
- end
934
-
935
863
  class MysqlString < Type::String # :nodoc:
936
864
  def serialize(value)
937
865
  case value
938
- when true then MySQL::Quoting::QUOTED_TRUE
939
- when false then MySQL::Quoting::QUOTED_FALSE
866
+ when true then "1"
867
+ when false then "0"
940
868
  else super
941
869
  end
942
870
  end
@@ -945,14 +873,13 @@ module ActiveRecord
945
873
 
946
874
  def cast_value(value)
947
875
  case value
948
- when true then MySQL::Quoting::QUOTED_TRUE
949
- when false then MySQL::Quoting::QUOTED_FALSE
876
+ when true then "1"
877
+ when false then "0"
950
878
  else super
951
879
  end
952
880
  end
953
881
  end
954
882
 
955
- ActiveRecord::Type.register(:json, MysqlJson, adapter: :mysql2)
956
883
  ActiveRecord::Type.register(:string, MysqlString, adapter: :mysql2)
957
884
  ActiveRecord::Type.register(:unsigned_integer, Type::UnsignedInteger, adapter: :mysql2)
958
885
  end