activerecord 5.0.7.2 → 6.0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +708 -2040
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +9 -7
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -22
  8. data/lib/active_record/advisory_lock_base.rb +18 -0
  9. data/lib/active_record/aggregations.rb +249 -247
  10. data/lib/active_record/association_relation.rb +18 -14
  11. data/lib/active_record/associations.rb +1603 -1592
  12. data/lib/active_record/associations/alias_tracker.rb +24 -34
  13. data/lib/active_record/associations/association.rb +114 -55
  14. data/lib/active_record/associations/association_scope.rb +94 -94
  15. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  16. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  17. data/lib/active_record/associations/builder/association.rb +18 -25
  18. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  19. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  20. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
  21. data/lib/active_record/associations/builder/has_many.rb +4 -0
  22. data/lib/active_record/associations/builder/has_one.rb +37 -1
  23. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  24. data/lib/active_record/associations/collection_association.rb +86 -254
  25. data/lib/active_record/associations/collection_proxy.rb +158 -122
  26. data/lib/active_record/associations/foreign_association.rb +9 -0
  27. data/lib/active_record/associations/has_many_association.rb +23 -30
  28. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  29. data/lib/active_record/associations/has_one_association.rb +59 -54
  30. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  31. data/lib/active_record/associations/join_dependency.rb +143 -176
  32. data/lib/active_record/associations/join_dependency/join_association.rb +38 -87
  33. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  34. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  35. data/lib/active_record/associations/preloader.rb +90 -103
  36. data/lib/active_record/associations/preloader/association.rb +86 -100
  37. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  38. data/lib/active_record/associations/singular_association.rb +12 -45
  39. data/lib/active_record/associations/through_association.rb +26 -14
  40. data/lib/active_record/attribute_assignment.rb +54 -61
  41. data/lib/active_record/attribute_decorators.rb +38 -17
  42. data/lib/active_record/attribute_methods.rb +66 -106
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
  44. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  45. data/lib/active_record/attribute_methods/primary_key.rb +85 -92
  46. data/lib/active_record/attribute_methods/query.rb +4 -3
  47. data/lib/active_record/attribute_methods/read.rb +20 -49
  48. data/lib/active_record/attribute_methods/serialization.rb +29 -7
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
  50. data/lib/active_record/attribute_methods/write.rb +34 -33
  51. data/lib/active_record/attributes.rb +38 -25
  52. data/lib/active_record/autosave_association.rb +54 -35
  53. data/lib/active_record/base.rb +27 -24
  54. data/lib/active_record/callbacks.rb +64 -35
  55. data/lib/active_record/coders/json.rb +2 -0
  56. data/lib/active_record/coders/yaml_column.rb +11 -12
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +552 -323
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +228 -147
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -202
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +396 -562
  70. data/lib/active_record/connection_adapters/column.rb +41 -13
  71. data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  73. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  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 +3 -1
  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 +4 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  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 -11
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  101. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -31
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +8 -4
  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 +95 -35
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
  118. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  120. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  121. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  122. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  123. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  124. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  127. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +259 -266
  128. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  129. data/lib/active_record/connection_handling.rb +143 -40
  130. data/lib/active_record/core.rb +201 -163
  131. data/lib/active_record/counter_cache.rb +60 -28
  132. data/lib/active_record/database_configurations.rb +233 -0
  133. data/lib/active_record/database_configurations/database_config.rb +37 -0
  134. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  135. data/lib/active_record/database_configurations/url_config.rb +78 -0
  136. data/lib/active_record/define_callbacks.rb +22 -0
  137. data/lib/active_record/dynamic_matchers.rb +87 -87
  138. data/lib/active_record/enum.rb +60 -23
  139. data/lib/active_record/errors.rb +114 -18
  140. data/lib/active_record/explain.rb +4 -4
  141. data/lib/active_record/explain_registry.rb +3 -1
  142. data/lib/active_record/explain_subscriber.rb +9 -4
  143. data/lib/active_record/fixture_set/file.rb +13 -8
  144. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  145. data/lib/active_record/fixture_set/render_context.rb +17 -0
  146. data/lib/active_record/fixture_set/table_row.rb +152 -0
  147. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  148. data/lib/active_record/fixtures.rb +194 -504
  149. data/lib/active_record/gem_version.rb +5 -3
  150. data/lib/active_record/inheritance.rb +150 -99
  151. data/lib/active_record/insert_all.rb +179 -0
  152. data/lib/active_record/integration.rb +116 -25
  153. data/lib/active_record/internal_metadata.rb +16 -19
  154. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  155. data/lib/active_record/locking/optimistic.rb +77 -87
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +48 -29
  158. data/lib/active_record/middleware/database_selector.rb +74 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +369 -302
  162. data/lib/active_record/migration/command_recorder.rb +134 -100
  163. data/lib/active_record/migration/compatibility.rb +174 -56
  164. data/lib/active_record/migration/join_table.rb +8 -7
  165. data/lib/active_record/model_schema.rb +131 -127
  166. data/lib/active_record/nested_attributes.rb +213 -202
  167. data/lib/active_record/no_touching.rb +12 -3
  168. data/lib/active_record/null_relation.rb +12 -34
  169. data/lib/active_record/persistence.rb +446 -77
  170. data/lib/active_record/query_cache.rb +13 -12
  171. data/lib/active_record/querying.rb +37 -24
  172. data/lib/active_record/railtie.rb +128 -36
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +312 -177
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +214 -252
  179. data/lib/active_record/relation.rb +440 -318
  180. data/lib/active_record/relation/batches.rb +98 -52
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  182. data/lib/active_record/relation/calculations.rb +212 -173
  183. data/lib/active_record/relation/delegation.rb +72 -69
  184. data/lib/active_record/relation/finder_methods.rb +207 -247
  185. data/lib/active_record/relation/from_clause.rb +6 -8
  186. data/lib/active_record/relation/merger.rb +78 -62
  187. data/lib/active_record/relation/predicate_builder.rb +83 -105
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  195. data/lib/active_record/relation/query_attribute.rb +33 -2
  196. data/lib/active_record/relation/query_methods.rb +476 -334
  197. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  198. data/lib/active_record/relation/spawn_methods.rb +8 -8
  199. data/lib/active_record/relation/where_clause.rb +111 -96
  200. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  201. data/lib/active_record/result.rb +69 -40
  202. data/lib/active_record/runtime_registry.rb +5 -3
  203. data/lib/active_record/sanitization.rb +83 -99
  204. data/lib/active_record/schema.rb +7 -14
  205. data/lib/active_record/schema_dumper.rb +71 -69
  206. data/lib/active_record/schema_migration.rb +16 -6
  207. data/lib/active_record/scoping.rb +20 -20
  208. data/lib/active_record/scoping/default.rb +92 -95
  209. data/lib/active_record/scoping/named.rb +47 -27
  210. data/lib/active_record/secure_token.rb +4 -2
  211. data/lib/active_record/serialization.rb +2 -0
  212. data/lib/active_record/statement_cache.rb +63 -28
  213. data/lib/active_record/store.rb +121 -41
  214. data/lib/active_record/suppressor.rb +6 -3
  215. data/lib/active_record/table_metadata.rb +39 -18
  216. data/lib/active_record/tasks/database_tasks.rb +271 -81
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +225 -0
  222. data/lib/active_record/timestamp.rb +70 -36
  223. data/lib/active_record/touch_later.rb +8 -6
  224. data/lib/active_record/transactions.rb +141 -157
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +23 -18
  227. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  228. data/lib/active_record/type/date.rb +2 -0
  229. data/lib/active_record/type/date_time.rb +2 -0
  230. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  232. data/lib/active_record/type/internal/timezone.rb +2 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +16 -9
  235. data/lib/active_record/type/text.rb +11 -0
  236. data/lib/active_record/type/time.rb +2 -1
  237. data/lib/active_record/type/type_map.rb +14 -17
  238. data/lib/active_record/type/unsigned_integer.rb +16 -0
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/type_caster/connection.rb +17 -12
  241. data/lib/active_record/type_caster/map.rb +5 -4
  242. data/lib/active_record/validations.rb +7 -5
  243. data/lib/active_record/validations/absence.rb +2 -0
  244. data/lib/active_record/validations/associated.rb +4 -3
  245. data/lib/active_record/validations/length.rb +2 -0
  246. data/lib/active_record/validations/presence.rb +4 -2
  247. data/lib/active_record/validations/uniqueness.rb +29 -42
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +62 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +203 -0
  317. data/lib/arel/visitors/dot.rb +296 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +156 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +158 -0
  323. data/lib/arel/visitors/oracle12.rb +65 -0
  324. data/lib/arel/visitors/postgresql.rb +109 -0
  325. data/lib/arel/visitors/sqlite.rb +38 -0
  326. data/lib/arel/visitors/to_sql.rb +888 -0
  327. data/lib/arel/visitors/visitor.rb +45 -0
  328. data/lib/arel/visitors/where_sql.rb +22 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +7 -5
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  332. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  333. data/lib/rails/generators/active_record/migration.rb +17 -3
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  335. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
  338. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. metadata +137 -52
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  350. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/attribute_set/builder.rb +0 -132
  353. data/lib/active_record/collection_cache_key.rb +0 -50
  354. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  355. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  356. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  357. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  358. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  359. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,66 +1,70 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MySQL
4
- class SchemaCreation < AbstractAdapter::SchemaCreation
5
- delegate :add_sql_comment!, to: :@conn
6
- private :add_sql_comment!
6
+ class SchemaCreation < AbstractAdapter::SchemaCreation # :nodoc:
7
+ delegate :add_sql_comment!, :mariadb?, to: :@conn, private: true
7
8
 
8
9
  private
10
+ def visit_DropForeignKey(name)
11
+ "DROP FOREIGN KEY #{name}"
12
+ end
9
13
 
10
- def visit_DropForeignKey(name)
11
- "DROP FOREIGN KEY #{name}"
12
- end
14
+ def visit_AddColumnDefinition(o)
15
+ add_column_position!(super, column_options(o.column))
16
+ end
13
17
 
14
- def visit_ColumnDefinition(o)
15
- o.sql_type = type_to_sql(o.type, o.limit, o.precision, o.scale, o.unsigned)
16
- super
17
- end
18
+ def visit_ChangeColumnDefinition(o)
19
+ change_column_sql = +"CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
20
+ add_column_position!(change_column_sql, column_options(o.column))
21
+ end
18
22
 
19
- def visit_AddColumnDefinition(o)
20
- add_column_position!(super, column_options(o.column))
21
- end
23
+ def add_table_options!(create_sql, options)
24
+ add_sql_comment!(super, options[:comment])
25
+ end
22
26
 
23
- def visit_ChangeColumnDefinition(o)
24
- change_column_sql = "CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
25
- add_column_position!(change_column_sql, column_options(o.column))
26
- end
27
+ def add_column_options!(sql, options)
28
+ # By default, TIMESTAMP columns are NOT NULL, cannot contain NULL values,
29
+ # and assigning NULL assigns the current timestamp. To permit a TIMESTAMP
30
+ # column to contain NULL, explicitly declare it with the NULL attribute.
31
+ # See https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
32
+ if /\Atimestamp\b/.match?(options[:column].sql_type) && !options[:primary_key]
33
+ sql << " NULL" unless options[:null] == false || options_include_default?(options)
34
+ end
27
35
 
28
- def add_table_options!(create_sql, options)
29
- add_sql_comment!(super, options[:comment])
30
- end
36
+ if charset = options[:charset]
37
+ sql << " CHARACTER SET #{charset}"
38
+ end
31
39
 
32
- def column_options(o)
33
- column_options = super
34
- column_options[:charset] = o.charset
35
- column_options
36
- end
40
+ if collation = options[:collation]
41
+ sql << " COLLATE #{collation}"
42
+ end
37
43
 
38
- def add_column_options!(sql, options)
39
- if charset = options[:charset]
40
- sql << " CHARACTER SET #{charset}"
41
- end
44
+ if as = options[:as]
45
+ sql << " AS (#{as})"
46
+ if options[:stored]
47
+ sql << (mariadb? ? " PERSISTENT" : " STORED")
48
+ end
49
+ end
42
50
 
43
- if collation = options[:collation]
44
- sql << " COLLATE #{collation}"
51
+ add_sql_comment!(super, options[:comment])
45
52
  end
46
53
 
47
- add_sql_comment!(super, options[:comment])
48
- end
54
+ def add_column_position!(sql, options)
55
+ if options[:first]
56
+ sql << " FIRST"
57
+ elsif options[:after]
58
+ sql << " AFTER #{quote_column_name(options[:after])}"
59
+ end
49
60
 
50
- def add_column_position!(sql, options)
51
- if options[:first]
52
- sql << " FIRST"
53
- elsif options[:after]
54
- sql << " AFTER #{quote_column_name(options[:after])}"
61
+ sql
55
62
  end
56
63
 
57
- sql
58
- end
59
-
60
- def index_in_create(table_name, column_name, options)
61
- index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, options)
62
- add_sql_comment!("#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})", comment)
63
- end
64
+ def index_in_create(table_name, column_name, options)
65
+ index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, **options)
66
+ add_sql_comment!((+"#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})"), comment)
67
+ end
64
68
  end
65
69
  end
66
70
  end
@@ -1,88 +1,90 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MySQL
4
6
  module ColumnMethods
5
- def primary_key(name, type = :primary_key, **options)
6
- options[:auto_increment] = true if type == :bigint && !options.key?(:default)
7
- super
8
- end
7
+ extend ActiveSupport::Concern
9
8
 
10
- def blob(*args, **options)
11
- args.each { |name| column(name, :blob, options) }
12
- end
9
+ ##
10
+ # :method: blob
11
+ # :call-seq: blob(*names, **options)
13
12
 
14
- def tinyblob(*args, **options)
15
- args.each { |name| column(name, :tinyblob, options) }
16
- end
13
+ ##
14
+ # :method: tinyblob
15
+ # :call-seq: tinyblob(*names, **options)
17
16
 
18
- def mediumblob(*args, **options)
19
- args.each { |name| column(name, :mediumblob, options) }
20
- end
17
+ ##
18
+ # :method: mediumblob
19
+ # :call-seq: mediumblob(*names, **options)
21
20
 
22
- def longblob(*args, **options)
23
- args.each { |name| column(name, :longblob, options) }
24
- end
21
+ ##
22
+ # :method: longblob
23
+ # :call-seq: longblob(*names, **options)
25
24
 
26
- def tinytext(*args, **options)
27
- args.each { |name| column(name, :tinytext, options) }
28
- end
25
+ ##
26
+ # :method: tinytext
27
+ # :call-seq: tinytext(*names, **options)
29
28
 
30
- def mediumtext(*args, **options)
31
- args.each { |name| column(name, :mediumtext, options) }
32
- end
29
+ ##
30
+ # :method: mediumtext
31
+ # :call-seq: mediumtext(*names, **options)
33
32
 
34
- def longtext(*args, **options)
35
- args.each { |name| column(name, :longtext, options) }
36
- end
33
+ ##
34
+ # :method: longtext
35
+ # :call-seq: longtext(*names, **options)
37
36
 
38
- def json(*args, **options)
39
- args.each { |name| column(name, :json, options) }
40
- end
37
+ ##
38
+ # :method: unsigned_integer
39
+ # :call-seq: unsigned_integer(*names, **options)
41
40
 
42
- def unsigned_integer(*args, **options)
43
- args.each { |name| column(name, :unsigned_integer, options) }
44
- end
41
+ ##
42
+ # :method: unsigned_bigint
43
+ # :call-seq: unsigned_bigint(*names, **options)
45
44
 
46
- def unsigned_bigint(*args, **options)
47
- args.each { |name| column(name, :unsigned_bigint, options) }
48
- end
45
+ ##
46
+ # :method: unsigned_float
47
+ # :call-seq: unsigned_float(*names, **options)
49
48
 
50
- def unsigned_float(*args, **options)
51
- args.each { |name| column(name, :unsigned_float, options) }
52
- end
49
+ ##
50
+ # :method: unsigned_decimal
51
+ # :call-seq: unsigned_decimal(*names, **options)
53
52
 
54
- def unsigned_decimal(*args, **options)
55
- args.each { |name| column(name, :unsigned_decimal, options) }
53
+ included do
54
+ define_column_methods :blob, :tinyblob, :mediumblob, :longblob,
55
+ :tinytext, :mediumtext, :longtext, :unsigned_integer, :unsigned_bigint,
56
+ :unsigned_float, :unsigned_decimal
56
57
  end
57
58
  end
58
59
 
59
- class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
60
- attr_accessor :charset, :unsigned
61
- end
62
-
63
60
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
64
61
  include ColumnMethods
65
62
 
66
- def new_column_definition(name, type, options) # :nodoc:
67
- column = super
68
- case column.type
63
+ def new_column_definition(name, type, **options) # :nodoc:
64
+ case type
65
+ when :virtual
66
+ type = options[:type]
69
67
  when :primary_key
70
- column.type = :integer
71
- column.auto_increment = true
68
+ type = :integer
69
+ options[:limit] ||= 8
70
+ options[:primary_key] = true
72
71
  when /\Aunsigned_(?<type>.+)\z/
73
- column.type = $~[:type].to_sym
74
- column.unsigned = true
72
+ type = $~[:type].to_sym
73
+ options[:unsigned] = true
75
74
  end
76
- column.unsigned ||= options[:unsigned]
77
- column.charset = options[:charset]
78
- column
75
+
76
+ super
79
77
  end
80
78
 
81
79
  private
80
+ def aliased_types(name, fallback)
81
+ fallback
82
+ end
82
83
 
83
- def create_column_definition(name, type)
84
- MySQL::ColumnDefinition.new(name, type)
85
- end
84
+ def integer_like_primary_key_type(type, options)
85
+ options[:auto_increment] = true
86
+ type
87
+ end
86
88
  end
87
89
 
88
90
  class Table < ActiveRecord::ConnectionAdapters::Table
@@ -1,53 +1,87 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module MySQL
4
- module ColumnDumper
5
- def column_spec_for_primary_key(column)
6
- if column.bigint?
7
- spec = { id: :bigint.inspect }
8
- spec[:default] = schema_default(column) || 'nil' unless column.auto_increment?
9
- else
6
+ class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
7
+ private
8
+ def prepare_column_options(column)
9
+ spec = super
10
+ spec[:unsigned] = "true" if column.unsigned?
11
+ spec[:auto_increment] = "true" if column.auto_increment?
12
+
13
+ if /\A(?<size>tiny|medium|long)(?:text|blob)/ =~ column.sql_type
14
+ spec = { size: size.to_sym.inspect }.merge!(spec)
15
+ end
16
+
17
+ if @connection.supports_virtual_columns? && column.virtual?
18
+ spec[:as] = extract_expression_for_virtual_column(column)
19
+ spec[:stored] = "true" if /\b(?:STORED|PERSISTENT)\b/.match?(column.extra)
20
+ spec = { type: schema_type(column).inspect }.merge!(spec)
21
+ end
22
+
23
+ spec
24
+ end
25
+
26
+ def column_spec_for_primary_key(column)
10
27
  spec = super
28
+ spec.delete(:auto_increment) if column.type == :integer && column.auto_increment?
29
+ spec
11
30
  end
12
- spec[:unsigned] = 'true' if column.unsigned?
13
- spec
14
- end
15
31
 
16
- def prepare_column_options(column)
17
- spec = super
18
- spec[:unsigned] = 'true' if column.unsigned?
19
- spec
20
- end
32
+ def default_primary_key?(column)
33
+ super && column.auto_increment? && !column.unsigned?
34
+ end
21
35
 
22
- def migration_keys
23
- super + [:unsigned]
24
- end
36
+ def explicit_primary_key_default?(column)
37
+ column.type == :integer && !column.auto_increment?
38
+ end
25
39
 
26
- private
40
+ def schema_type(column)
41
+ case column.sql_type
42
+ when /\Atimestamp\b/
43
+ :timestamp
44
+ when /\A(?:enum|set)\b/
45
+ column.sql_type
46
+ else
47
+ super
48
+ end
49
+ end
27
50
 
28
- def default_primary_key?(column)
29
- super && column.auto_increment?
30
- end
51
+ def schema_limit(column)
52
+ super unless /\A(?:enum|set|(?:tiny|medium|long)?(?:text|blob))\b/.match?(column.sql_type)
53
+ end
31
54
 
32
- def schema_type(column)
33
- if column.sql_type == 'tinyblob'
34
- :blob
35
- else
36
- super
55
+ def schema_precision(column)
56
+ super unless /\A(?:date)?time(?:stamp)?\b/.match?(column.sql_type) && column.precision == 0
37
57
  end
38
- end
39
58
 
40
- def schema_precision(column)
41
- super unless /time/ === column.sql_type && column.precision == 0
42
- end
59
+ def schema_collation(column)
60
+ if column.collation
61
+ @table_collation_cache ||= {}
62
+ @table_collation_cache[table_name] ||=
63
+ @connection.exec_query("SHOW TABLE STATUS LIKE #{@connection.quote(table_name)}", "SCHEMA").first["Collation"]
64
+ column.collation.inspect if column.collation != @table_collation_cache[table_name]
65
+ end
66
+ end
43
67
 
44
- def schema_collation(column)
45
- if column.collation && table_name = column.table_name
46
- @table_collation_cache ||= {}
47
- @table_collation_cache[table_name] ||= select_one("SHOW TABLE STATUS LIKE '#{table_name}'")["Collation"]
48
- column.collation.inspect if column.collation != @table_collation_cache[table_name]
68
+ def extract_expression_for_virtual_column(column)
69
+ if @connection.mariadb? && @connection.database_version < "10.2.5"
70
+ create_table_info = @connection.send(:create_table_info, table_name)
71
+ column_name = @connection.quote_column_name(column.name)
72
+ if %r/#{column_name} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info
73
+ $~[:expression].inspect
74
+ end
75
+ else
76
+ scope = @connection.send(:quoted_scope, table_name)
77
+ column_name = @connection.quote(column.name)
78
+ sql = "SELECT generation_expression FROM information_schema.columns" \
79
+ " WHERE table_schema = #{scope[:schema]}" \
80
+ " AND table_name = #{scope[:name]}" \
81
+ " AND column_name = #{column_name}"
82
+ @connection.query_value(sql, "SCHEMA").inspect
83
+ end
49
84
  end
50
- end
51
85
  end
52
86
  end
53
87
  end
@@ -0,0 +1,264 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module MySQL
6
+ module SchemaStatements # :nodoc:
7
+ # Returns an array of indexes for the given table.
8
+ def indexes(table_name)
9
+ indexes = []
10
+ current_index = nil
11
+ execute_and_free("SHOW KEYS FROM #{quote_table_name(table_name)}", "SCHEMA") do |result|
12
+ each_hash(result) do |row|
13
+ if current_index != row[:Key_name]
14
+ next if row[:Key_name] == "PRIMARY" # skip the primary key
15
+ current_index = row[:Key_name]
16
+
17
+ mysql_index_type = row[:Index_type].downcase.to_sym
18
+ case mysql_index_type
19
+ when :fulltext, :spatial
20
+ index_type = mysql_index_type
21
+ when :btree, :hash
22
+ index_using = mysql_index_type
23
+ end
24
+
25
+ indexes << [
26
+ row[:Table],
27
+ row[:Key_name],
28
+ row[:Non_unique].to_i == 0,
29
+ [],
30
+ lengths: {},
31
+ orders: {},
32
+ type: index_type,
33
+ using: index_using,
34
+ comment: row[:Index_comment].presence
35
+ ]
36
+ end
37
+
38
+ if row[:Expression]
39
+ expression = row[:Expression]
40
+ expression = +"(#{expression})" unless expression.start_with?("(")
41
+ indexes.last[-2] << expression
42
+ indexes.last[-1][:expressions] ||= {}
43
+ indexes.last[-1][:expressions][expression] = expression
44
+ indexes.last[-1][:orders][expression] = :desc if row[:Collation] == "D"
45
+ else
46
+ indexes.last[-2] << row[:Column_name]
47
+ indexes.last[-1][:lengths][row[:Column_name]] = row[:Sub_part].to_i if row[:Sub_part]
48
+ indexes.last[-1][:orders][row[:Column_name]] = :desc if row[:Collation] == "D"
49
+ end
50
+ end
51
+ end
52
+
53
+ indexes.map do |index|
54
+ options = index.pop
55
+
56
+ if expressions = options.delete(:expressions)
57
+ orders = options.delete(:orders)
58
+ lengths = options.delete(:lengths)
59
+
60
+ columns = index[-1].map { |name|
61
+ [ name.to_sym, expressions[name] || +quote_column_name(name) ]
62
+ }.to_h
63
+
64
+ index[-1] = add_options_for_index_columns(
65
+ columns, order: orders, length: lengths
66
+ ).values.join(", ")
67
+ end
68
+
69
+ IndexDefinition.new(*index, **options)
70
+ end
71
+ end
72
+
73
+ def remove_column(table_name, column_name, type = nil, **options)
74
+ if foreign_key_exists?(table_name, column: column_name)
75
+ remove_foreign_key(table_name, column: column_name)
76
+ end
77
+ super
78
+ end
79
+
80
+ def create_table(table_name, options: default_row_format, **)
81
+ super
82
+ end
83
+
84
+ def internal_string_options_for_primary_key
85
+ super.tap do |options|
86
+ if !row_format_dynamic_by_default? && CHARSETS_OF_4BYTES_MAXLEN.include?(charset)
87
+ options[:collation] = collation.sub(/\A[^_]+/, "utf8")
88
+ end
89
+ end
90
+ end
91
+
92
+ def update_table_definition(table_name, base)
93
+ MySQL::Table.new(table_name, base)
94
+ end
95
+
96
+ def create_schema_dumper(options)
97
+ MySQL::SchemaDumper.create(self, options)
98
+ end
99
+
100
+ # Maps logical Rails types to MySQL-specific data types.
101
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, size: limit_to_size(limit, type), unsigned: nil, **)
102
+ sql =
103
+ case type.to_s
104
+ when "integer"
105
+ integer_to_sql(limit)
106
+ when "text"
107
+ type_with_size_to_sql("text", size)
108
+ when "blob"
109
+ type_with_size_to_sql("blob", size)
110
+ when "binary"
111
+ if (0..0xfff) === limit
112
+ "varbinary(#{limit})"
113
+ else
114
+ type_with_size_to_sql("blob", size)
115
+ end
116
+ else
117
+ super
118
+ end
119
+
120
+ sql = "#{sql} unsigned" if unsigned && type != :primary_key
121
+ sql
122
+ end
123
+
124
+ def table_alias_length
125
+ 256 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
126
+ end
127
+
128
+ private
129
+ CHARSETS_OF_4BYTES_MAXLEN = ["utf8mb4", "utf16", "utf16le", "utf32"]
130
+
131
+ def row_format_dynamic_by_default?
132
+ if mariadb?
133
+ database_version >= "10.2.2"
134
+ else
135
+ database_version >= "5.7.9"
136
+ end
137
+ end
138
+
139
+ def default_row_format
140
+ return if row_format_dynamic_by_default?
141
+
142
+ unless defined?(@default_row_format)
143
+ if query_value("SELECT @@innodb_file_per_table = 1 AND @@innodb_file_format = 'Barracuda'") == 1
144
+ @default_row_format = "ROW_FORMAT=DYNAMIC"
145
+ else
146
+ @default_row_format = nil
147
+ end
148
+ end
149
+
150
+ @default_row_format
151
+ end
152
+
153
+ def schema_creation
154
+ MySQL::SchemaCreation.new(self)
155
+ end
156
+
157
+ def create_table_definition(*args, **options)
158
+ MySQL::TableDefinition.new(self, *args, **options)
159
+ end
160
+
161
+ def new_column_from_field(table_name, field)
162
+ type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
163
+ default, default_function = field[:Default], nil
164
+
165
+ if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)
166
+ default, default_function = nil, default
167
+ elsif type_metadata.extra == "DEFAULT_GENERATED"
168
+ default = +"(#{default})" unless default.start_with?("(")
169
+ default, default_function = nil, default
170
+ end
171
+
172
+ MySQL::Column.new(
173
+ field[:Field],
174
+ default,
175
+ type_metadata,
176
+ field[:Null] == "YES",
177
+ default_function,
178
+ collation: field[:Collation],
179
+ comment: field[:Comment].presence
180
+ )
181
+ end
182
+
183
+ def fetch_type_metadata(sql_type, extra = "")
184
+ MySQL::TypeMetadata.new(super(sql_type), extra: extra)
185
+ end
186
+
187
+ def extract_foreign_key_action(specifier)
188
+ super unless specifier == "RESTRICT"
189
+ end
190
+
191
+ def add_index_length(quoted_columns, **options)
192
+ lengths = options_for_index_columns(options[:length])
193
+ quoted_columns.each do |name, column|
194
+ column << "(#{lengths[name]})" if lengths[name].present?
195
+ end
196
+ end
197
+
198
+ def add_options_for_index_columns(quoted_columns, **options)
199
+ quoted_columns = add_index_length(quoted_columns, **options)
200
+ super
201
+ end
202
+
203
+ def data_source_sql(name = nil, type: nil)
204
+ scope = quoted_scope(name, type: type)
205
+
206
+ sql = +"SELECT table_name FROM information_schema.tables"
207
+ sql << " WHERE table_schema = #{scope[:schema]}"
208
+ sql << " AND table_name = #{scope[:name]}" if scope[:name]
209
+ sql << " AND table_type = #{scope[:type]}" if scope[:type]
210
+ sql
211
+ end
212
+
213
+ def quoted_scope(name = nil, type: nil)
214
+ schema, name = extract_schema_qualified_name(name)
215
+ scope = {}
216
+ scope[:schema] = schema ? quote(schema) : "database()"
217
+ scope[:name] = quote(name) if name
218
+ scope[:type] = quote(type) if type
219
+ scope
220
+ end
221
+
222
+ def extract_schema_qualified_name(string)
223
+ schema, name = string.to_s.scan(/[^`.\s]+|`[^`]*`/)
224
+ schema, name = nil, schema unless name
225
+ [schema, name]
226
+ end
227
+
228
+ def type_with_size_to_sql(type, size)
229
+ case size&.to_s
230
+ when nil, "tiny", "medium", "long"
231
+ "#{size}#{type}"
232
+ else
233
+ raise ArgumentError,
234
+ "#{size.inspect} is invalid :size value. Only :tiny, :medium, and :long are allowed."
235
+ end
236
+ end
237
+
238
+ def limit_to_size(limit, type)
239
+ case type.to_s
240
+ when "text", "blob", "binary"
241
+ case limit
242
+ when 0..0xff; "tiny"
243
+ when nil, 0x100..0xffff; nil
244
+ when 0x10000..0xffffff; "medium"
245
+ when 0x1000000..0xffffffff; "long"
246
+ else raise ArgumentError, "No #{type} type has byte size #{limit}"
247
+ end
248
+ end
249
+ end
250
+
251
+ def integer_to_sql(limit)
252
+ case limit
253
+ when 1; "tinyint"
254
+ when 2; "smallint"
255
+ when 3; "mediumint"
256
+ when nil, 4; "int"
257
+ when 5..8; "bigint"
258
+ else raise ArgumentError, "No integer type has byte size #{limit}. Use a decimal with scale 0 instead."
259
+ end
260
+ end
261
+ end
262
+ end
263
+ end
264
+ end