activerecord 5.2.8.1 → 6.1.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1347 -624
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +9 -8
  7. data/lib/active_record/association_relation.rb +30 -10
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +100 -41
  10. data/lib/active_record/associations/association_scope.rb +23 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +55 -48
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
  13. data/lib/active_record/associations/builder/association.rb +45 -22
  14. data/lib/active_record/associations/builder/belongs_to.rb +29 -59
  15. data/lib/active_record/associations/builder/collection_association.rb +8 -17
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -2
  18. data/lib/active_record/associations/builder/has_one.rb +33 -2
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -1
  20. data/lib/active_record/associations/collection_association.rb +44 -34
  21. data/lib/active_record/associations/collection_proxy.rb +25 -21
  22. data/lib/active_record/associations/foreign_association.rb +20 -0
  23. data/lib/active_record/associations/has_many_association.rb +26 -13
  24. data/lib/active_record/associations/has_many_through_association.rb +24 -18
  25. data/lib/active_record/associations/has_one_association.rb +43 -31
  26. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  27. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  28. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  29. data/lib/active_record/associations/join_dependency.rb +91 -60
  30. data/lib/active_record/associations/preloader/association.rb +69 -43
  31. data/lib/active_record/associations/preloader/through_association.rb +49 -40
  32. data/lib/active_record/associations/preloader.rb +47 -34
  33. data/lib/active_record/associations/singular_association.rb +3 -17
  34. data/lib/active_record/associations/through_association.rb +1 -1
  35. data/lib/active_record/associations.rb +137 -25
  36. data/lib/active_record/attribute_assignment.rb +17 -19
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
  38. data/lib/active_record/attribute_methods/dirty.rb +101 -40
  39. data/lib/active_record/attribute_methods/primary_key.rb +20 -25
  40. data/lib/active_record/attribute_methods/query.rb +4 -8
  41. data/lib/active_record/attribute_methods/read.rb +14 -56
  42. data/lib/active_record/attribute_methods/serialization.rb +12 -7
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  44. data/lib/active_record/attribute_methods/write.rb +18 -34
  45. data/lib/active_record/attribute_methods.rb +81 -143
  46. data/lib/active_record/attributes.rb +46 -9
  47. data/lib/active_record/autosave_association.rb +57 -42
  48. data/lib/active_record/base.rb +4 -17
  49. data/lib/active_record/callbacks.rb +158 -43
  50. data/lib/active_record/coders/yaml_column.rb +16 -7
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -14
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +107 -47
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +211 -90
  59. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
  60. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
  63. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
  64. data/lib/active_record/connection_adapters/column.rb +30 -12
  65. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  66. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -32
  69. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  70. data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -7
  71. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  72. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  73. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +18 -7
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -19
  75. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
  77. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -54
  81. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  94. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  96. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/quoting.rb +73 -10
  99. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  101. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  102. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  104. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  105. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  106. data/lib/active_record/connection_adapters/postgresql_adapter.rb +225 -121
  107. data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
  108. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  109. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  110. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  111. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  112. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  113. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
  114. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  115. data/lib/active_record/connection_adapters.rb +52 -0
  116. data/lib/active_record/connection_handling.rb +293 -33
  117. data/lib/active_record/core.rb +341 -99
  118. data/lib/active_record/counter_cache.rb +8 -30
  119. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  120. data/lib/active_record/database_configurations/database_config.rb +80 -0
  121. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  122. data/lib/active_record/database_configurations/url_config.rb +53 -0
  123. data/lib/active_record/database_configurations.rb +273 -0
  124. data/lib/active_record/delegated_type.rb +209 -0
  125. data/lib/active_record/destroy_association_async_job.rb +36 -0
  126. data/lib/active_record/dynamic_matchers.rb +3 -4
  127. data/lib/active_record/enum.rb +108 -36
  128. data/lib/active_record/errors.rb +62 -19
  129. data/lib/active_record/explain.rb +10 -6
  130. data/lib/active_record/explain_subscriber.rb +1 -1
  131. data/lib/active_record/fixture_set/file.rb +10 -17
  132. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  133. data/lib/active_record/fixture_set/render_context.rb +17 -0
  134. data/lib/active_record/fixture_set/table_row.rb +152 -0
  135. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  136. data/lib/active_record/fixtures.rb +200 -481
  137. data/lib/active_record/gem_version.rb +4 -4
  138. data/lib/active_record/inheritance.rb +53 -24
  139. data/lib/active_record/insert_all.rb +212 -0
  140. data/lib/active_record/integration.rb +67 -17
  141. data/lib/active_record/internal_metadata.rb +28 -9
  142. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  143. data/lib/active_record/locking/optimistic.rb +37 -23
  144. data/lib/active_record/locking/pessimistic.rb +9 -5
  145. data/lib/active_record/log_subscriber.rb +35 -35
  146. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  147. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  148. data/lib/active_record/middleware/database_selector.rb +77 -0
  149. data/lib/active_record/migration/command_recorder.rb +96 -44
  150. data/lib/active_record/migration/compatibility.rb +145 -64
  151. data/lib/active_record/migration/join_table.rb +0 -1
  152. data/lib/active_record/migration.rb +206 -157
  153. data/lib/active_record/model_schema.rb +148 -22
  154. data/lib/active_record/nested_attributes.rb +4 -7
  155. data/lib/active_record/no_touching.rb +8 -1
  156. data/lib/active_record/null_relation.rb +0 -1
  157. data/lib/active_record/persistence.rb +267 -59
  158. data/lib/active_record/query_cache.rb +21 -4
  159. data/lib/active_record/querying.rb +40 -23
  160. data/lib/active_record/railtie.rb +113 -74
  161. data/lib/active_record/railties/console_sandbox.rb +2 -4
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +411 -80
  164. data/lib/active_record/readonly_attributes.rb +4 -0
  165. data/lib/active_record/reflection.rb +109 -93
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  167. data/lib/active_record/relation/batches.rb +44 -35
  168. data/lib/active_record/relation/calculations.rb +157 -90
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +64 -39
  171. data/lib/active_record/relation/from_clause.rb +5 -1
  172. data/lib/active_record/relation/merger.rb +32 -40
  173. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  174. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  179. data/lib/active_record/relation/predicate_builder.rb +62 -45
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +478 -187
  182. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  183. data/lib/active_record/relation/spawn_methods.rb +9 -9
  184. data/lib/active_record/relation/where_clause.rb +115 -62
  185. data/lib/active_record/relation.rb +379 -115
  186. data/lib/active_record/result.rb +64 -38
  187. data/lib/active_record/runtime_registry.rb +2 -2
  188. data/lib/active_record/sanitization.rb +22 -41
  189. data/lib/active_record/schema.rb +2 -11
  190. data/lib/active_record/schema_dumper.rb +54 -9
  191. data/lib/active_record/schema_migration.rb +7 -9
  192. data/lib/active_record/scoping/default.rb +4 -8
  193. data/lib/active_record/scoping/named.rb +17 -24
  194. data/lib/active_record/scoping.rb +8 -9
  195. data/lib/active_record/secure_token.rb +16 -8
  196. data/lib/active_record/serialization.rb +5 -3
  197. data/lib/active_record/signed_id.rb +116 -0
  198. data/lib/active_record/statement_cache.rb +49 -6
  199. data/lib/active_record/store.rb +94 -10
  200. data/lib/active_record/suppressor.rb +2 -2
  201. data/lib/active_record/table_metadata.rb +42 -43
  202. data/lib/active_record/tasks/database_tasks.rb +277 -81
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  206. data/lib/active_record/test_databases.rb +24 -0
  207. data/lib/active_record/test_fixtures.rb +291 -0
  208. data/lib/active_record/timestamp.rb +43 -32
  209. data/lib/active_record/touch_later.rb +23 -22
  210. data/lib/active_record/transactions.rb +62 -118
  211. data/lib/active_record/translation.rb +1 -1
  212. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  213. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  214. data/lib/active_record/type/serialized.rb +6 -3
  215. data/lib/active_record/type/time.rb +10 -0
  216. data/lib/active_record/type/type_map.rb +0 -1
  217. data/lib/active_record/type/unsigned_integer.rb +0 -1
  218. data/lib/active_record/type.rb +10 -5
  219. data/lib/active_record/type_caster/connection.rb +15 -15
  220. data/lib/active_record/type_caster/map.rb +8 -8
  221. data/lib/active_record/validations/associated.rb +1 -2
  222. data/lib/active_record/validations/numericality.rb +35 -0
  223. data/lib/active_record/validations/uniqueness.rb +38 -30
  224. data/lib/active_record/validations.rb +4 -3
  225. data/lib/active_record.rb +13 -12
  226. data/lib/arel/alias_predication.rb +9 -0
  227. data/lib/arel/attributes/attribute.rb +41 -0
  228. data/lib/arel/collectors/bind.rb +29 -0
  229. data/lib/arel/collectors/composite.rb +39 -0
  230. data/lib/arel/collectors/plain_string.rb +20 -0
  231. data/lib/arel/collectors/sql_string.rb +27 -0
  232. data/lib/arel/collectors/substitute_binds.rb +35 -0
  233. data/lib/arel/crud.rb +42 -0
  234. data/lib/arel/delete_manager.rb +18 -0
  235. data/lib/arel/errors.rb +9 -0
  236. data/lib/arel/expressions.rb +29 -0
  237. data/lib/arel/factory_methods.rb +49 -0
  238. data/lib/arel/insert_manager.rb +49 -0
  239. data/lib/arel/math.rb +45 -0
  240. data/lib/arel/nodes/and.rb +32 -0
  241. data/lib/arel/nodes/ascending.rb +23 -0
  242. data/lib/arel/nodes/binary.rb +126 -0
  243. data/lib/arel/nodes/bind_param.rb +44 -0
  244. data/lib/arel/nodes/case.rb +55 -0
  245. data/lib/arel/nodes/casted.rb +62 -0
  246. data/lib/arel/nodes/comment.rb +29 -0
  247. data/lib/arel/nodes/count.rb +12 -0
  248. data/lib/arel/nodes/delete_statement.rb +45 -0
  249. data/lib/arel/nodes/descending.rb +23 -0
  250. data/lib/arel/nodes/equality.rb +15 -0
  251. data/lib/arel/nodes/extract.rb +24 -0
  252. data/lib/arel/nodes/false.rb +16 -0
  253. data/lib/arel/nodes/full_outer_join.rb +8 -0
  254. data/lib/arel/nodes/function.rb +44 -0
  255. data/lib/arel/nodes/grouping.rb +11 -0
  256. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  257. data/lib/arel/nodes/in.rb +15 -0
  258. data/lib/arel/nodes/infix_operation.rb +92 -0
  259. data/lib/arel/nodes/inner_join.rb +8 -0
  260. data/lib/arel/nodes/insert_statement.rb +37 -0
  261. data/lib/arel/nodes/join_source.rb +20 -0
  262. data/lib/arel/nodes/matches.rb +18 -0
  263. data/lib/arel/nodes/named_function.rb +23 -0
  264. data/lib/arel/nodes/node.rb +51 -0
  265. data/lib/arel/nodes/node_expression.rb +13 -0
  266. data/lib/arel/nodes/ordering.rb +27 -0
  267. data/lib/arel/nodes/outer_join.rb +8 -0
  268. data/lib/arel/nodes/over.rb +15 -0
  269. data/lib/arel/nodes/regexp.rb +16 -0
  270. data/lib/arel/nodes/right_outer_join.rb +8 -0
  271. data/lib/arel/nodes/select_core.rb +67 -0
  272. data/lib/arel/nodes/select_statement.rb +41 -0
  273. data/lib/arel/nodes/sql_literal.rb +19 -0
  274. data/lib/arel/nodes/string_join.rb +11 -0
  275. data/lib/arel/nodes/table_alias.rb +31 -0
  276. data/lib/arel/nodes/terminal.rb +16 -0
  277. data/lib/arel/nodes/true.rb +16 -0
  278. data/lib/arel/nodes/unary.rb +44 -0
  279. data/lib/arel/nodes/unary_operation.rb +20 -0
  280. data/lib/arel/nodes/unqualified_column.rb +22 -0
  281. data/lib/arel/nodes/update_statement.rb +41 -0
  282. data/lib/arel/nodes/values_list.rb +9 -0
  283. data/lib/arel/nodes/window.rb +126 -0
  284. data/lib/arel/nodes/with.rb +11 -0
  285. data/lib/arel/nodes.rb +70 -0
  286. data/lib/arel/order_predications.rb +13 -0
  287. data/lib/arel/predications.rb +250 -0
  288. data/lib/arel/select_manager.rb +270 -0
  289. data/lib/arel/table.rb +118 -0
  290. data/lib/arel/tree_manager.rb +72 -0
  291. data/lib/arel/update_manager.rb +34 -0
  292. data/lib/arel/visitors/dot.rb +308 -0
  293. data/lib/arel/visitors/mysql.rb +93 -0
  294. data/lib/arel/visitors/postgresql.rb +120 -0
  295. data/lib/arel/visitors/sqlite.rb +38 -0
  296. data/lib/arel/visitors/to_sql.rb +899 -0
  297. data/lib/arel/visitors/visitor.rb +45 -0
  298. data/lib/arel/visitors.rb +13 -0
  299. data/lib/arel/window_predications.rb +9 -0
  300. data/lib/arel.rb +54 -0
  301. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  302. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  303. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  304. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  305. data/lib/rails/generators/active_record/migration.rb +19 -2
  306. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  307. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  308. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  309. metadata +118 -32
  310. data/lib/active_record/attribute_decorators.rb +0 -90
  311. data/lib/active_record/collection_cache_key.rb +0 -53
  312. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  313. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  314. data/lib/active_record/define_callbacks.rb +0 -22
  315. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  316. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -4,6 +4,12 @@ module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module PostgreSQL
6
6
  module Quoting
7
+ class IntegerOutOf64BitRange < StandardError
8
+ def initialize(msg)
9
+ super(msg)
10
+ end
11
+ end
12
+
7
13
  # Escapes binary strings for bytea input to the database.
8
14
  def escape_bytea(value)
9
15
  @connection.escape_bytea(value) if value
@@ -18,7 +24,7 @@ module ActiveRecord
18
24
 
19
25
  # Quotes strings for use in SQL input.
20
26
  def quote_string(s) #:nodoc:
21
- @connection.escape(s)
27
+ PG::Connection.escape(s)
22
28
  end
23
29
 
24
30
  # Checks the following cases:
@@ -30,7 +36,7 @@ module ActiveRecord
30
36
  # - "schema.name".table_name
31
37
  # - "schema.name"."table.name"
32
38
  def quote_table_name(name) # :nodoc:
33
- @quoted_table_names[name] ||= Utils.extract_schema_qualified_name(name.to_s).quoted.freeze
39
+ self.class.quoted_table_names[name] ||= Utils.extract_schema_qualified_name(name.to_s).quoted.freeze
34
40
  end
35
41
 
36
42
  # Quotes schema names for use in SQL queries.
@@ -44,7 +50,7 @@ module ActiveRecord
44
50
 
45
51
  # Quotes column names for use in SQL queries.
46
52
  def quote_column_name(name) # :nodoc:
47
- @quoted_column_names[name] ||= PG::Connection.quote_ident(super).freeze
53
+ self.class.quoted_column_names[name] ||= PG::Connection.quote_ident(super).freeze
48
54
  end
49
55
 
50
56
  # Quote date/time values for use in SQL input.
@@ -67,8 +73,8 @@ module ActiveRecord
67
73
  elsif column.type == :uuid && value.is_a?(String) && /\(\)/.match?(value)
68
74
  value # Does not quote function default values for UUID columns
69
75
  elsif column.respond_to?(:array?)
70
- value = type_cast_from_column(column, value)
71
- quote(value)
76
+ type = lookup_cast_type_from_column(column)
77
+ quote(type.serialize(value))
72
78
  else
73
79
  super
74
80
  end
@@ -78,12 +84,69 @@ module ActiveRecord
78
84
  type_map.lookup(column.oid, column.fmod, column.sql_type)
79
85
  end
80
86
 
87
+ def column_name_matcher
88
+ COLUMN_NAME
89
+ end
90
+
91
+ def column_name_with_order_matcher
92
+ COLUMN_NAME_WITH_ORDER
93
+ end
94
+
95
+ COLUMN_NAME = /
96
+ \A
97
+ (
98
+ (?:
99
+ # "table_name"."column_name"::type_name | function(one or no argument)::type_name
100
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")(?:::\w+)?) | \w+\((?:|\g<2>)\)(?:::\w+)?
101
+ )
102
+ (?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
103
+ )
104
+ (?:\s*,\s*\g<1>)*
105
+ \z
106
+ /ix
107
+
108
+ COLUMN_NAME_WITH_ORDER = /
109
+ \A
110
+ (
111
+ (?:
112
+ # "table_name"."column_name"::type_name | function(one or no argument)::type_name
113
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")(?:::\w+)?) | \w+\((?:|\g<2>)\)(?:::\w+)?
114
+ )
115
+ (?:\s+ASC|\s+DESC)?
116
+ (?:\s+NULLS\s+(?:FIRST|LAST))?
117
+ )
118
+ (?:\s*,\s*\g<1>)*
119
+ \z
120
+ /ix
121
+
122
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
123
+
81
124
  private
82
125
  def lookup_cast_type(sql_type)
83
126
  super(query_value("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").to_i)
84
127
  end
85
128
 
129
+ def check_int_in_range(value)
130
+ if value.to_int > 9223372036854775807 || value.to_int < -9223372036854775808
131
+ exception = <<~ERROR
132
+ Provided value outside of the range of a signed 64bit integer.
133
+
134
+ PostgreSQL will treat the column type in question as a numeric.
135
+ This may result in a slow sequential scan due to a comparison
136
+ being performed between an integer or bigint value and a numeric value.
137
+
138
+ To allow for this potentially unwanted behavior, set
139
+ ActiveRecord::Base.raise_int_wider_than_64bit to false.
140
+ ERROR
141
+ raise IntegerOutOf64BitRange.new exception
142
+ end
143
+ end
144
+
86
145
  def _quote(value)
146
+ if ActiveRecord::Base.raise_int_wider_than_64bit && value.is_a?(Integer)
147
+ check_int_in_range(value)
148
+ end
149
+
87
150
  case value
88
151
  when OID::Xml::Data
89
152
  "xml '#{quote_string(value.to_s)}'"
@@ -93,11 +156,11 @@ module ActiveRecord
93
156
  elsif value.hex?
94
157
  "X'#{value}'"
95
158
  end
96
- when Float
97
- if value.infinite? || value.nan?
98
- "'#{value}'"
99
- else
159
+ when Numeric
160
+ if value.finite?
100
161
  super
162
+ else
163
+ "'#{value}'"
101
164
  end
102
165
  when OID::Array::Data
103
166
  _quote(encode_array(value))
@@ -138,7 +201,7 @@ module ActiveRecord
138
201
  end
139
202
 
140
203
  def encode_range(range)
141
- "[#{type_cast_range_value(range.first)},#{type_cast_range_value(range.last)}#{range.exclude_end? ? ')' : ']'}"
204
+ "[#{type_cast_range_value(range.begin)},#{type_cast_range_value(range.end)}#{range.exclude_end? ? ')' : ']'}"
142
205
  end
143
206
 
144
207
  def determine_encoding_of_strings_in_array(value)
@@ -24,9 +24,9 @@ WARNING: Rails was not able to disable referential integrity.
24
24
  This is most likely caused due to missing permissions.
25
25
  Rails needs superuser privileges to disable referential integrity.
26
26
 
27
- cause: #{original_exception.try(:message)}
27
+ cause: #{original_exception&.message}
28
28
 
29
- WARNING
29
+ WARNING
30
30
  raise e
31
31
  end
32
32
 
@@ -3,7 +3,7 @@
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module PostgreSQL
6
- class SchemaCreation < AbstractAdapter::SchemaCreation # :nodoc:
6
+ class SchemaCreation < SchemaCreation # :nodoc:
7
7
  private
8
8
  def visit_AlterTable(o)
9
9
  super << o.constraint_validations.map { |fk| visit_ValidateConstraint fk }.join(" ")
@@ -13,16 +13,20 @@ module ActiveRecord
13
13
  super.dup.tap { |sql| sql << " NOT VALID" unless o.validate? }
14
14
  end
15
15
 
16
+ def visit_CheckConstraintDefinition(o)
17
+ super.dup.tap { |sql| sql << " NOT VALID" unless o.validate? }
18
+ end
19
+
16
20
  def visit_ValidateConstraint(name)
17
21
  "VALIDATE CONSTRAINT #{quote_column_name(name)}"
18
22
  end
19
23
 
20
24
  def visit_ChangeColumnDefinition(o)
21
25
  column = o.column
22
- column.sql_type = type_to_sql(column.type, column.options)
26
+ column.sql_type = type_to_sql(column.type, **column.options)
23
27
  quoted_column_name = quote_column_name(o.name)
24
28
 
25
- change_column_sql = "ALTER COLUMN #{quoted_column_name} TYPE #{column.sql_type}".dup
29
+ change_column_sql = +"ALTER COLUMN #{quoted_column_name} TYPE #{column.sql_type}"
26
30
 
27
31
  options = column_options(column)
28
32
 
@@ -33,7 +37,7 @@ module ActiveRecord
33
37
  if options[:using]
34
38
  change_column_sql << " USING #{options[:using]}"
35
39
  elsif options[:cast_as]
36
- cast_as_type = type_to_sql(options[:cast_as], options)
40
+ cast_as_type = type_to_sql(options[:cast_as], **options)
37
41
  change_column_sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})"
38
42
  end
39
43
 
@@ -59,6 +63,17 @@ module ActiveRecord
59
63
  end
60
64
  super
61
65
  end
66
+
67
+ # Returns any SQL string to go between CREATE and TABLE. May be nil.
68
+ def table_modifier_in_create(o)
69
+ # A table cannot be both TEMPORARY and UNLOGGED, since all TEMPORARY
70
+ # tables are already UNLOGGED.
71
+ if o.temporary
72
+ " TEMPORARY"
73
+ elsif o.unlogged
74
+ " UNLOGGED"
75
+ end
76
+ end
62
77
  end
63
78
  end
64
79
  end
@@ -4,6 +4,8 @@ module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module PostgreSQL
6
6
  module ColumnMethods
7
+ extend ActiveSupport::Concern
8
+
7
9
  # Defines the primary key field.
8
10
  # Use of the native PostgreSQL UUID type is supported, and can be used
9
11
  # by defining your tables as such:
@@ -13,10 +15,10 @@ module ActiveRecord
13
15
  # t.timestamps
14
16
  # end
15
17
  #
16
- # By default, this will use the +gen_random_uuid()+ function from the
18
+ # By default, this will use the <tt>gen_random_uuid()</tt> function from the
17
19
  # +pgcrypto+ extension. As that extension is only available in
18
20
  # PostgreSQL 9.4+, for earlier versions an explicit default can be set
19
- # to use +uuid_generate_v4()+ from the +uuid-ossp+ extension instead:
21
+ # to use <tt>uuid_generate_v4()</tt> from the +uuid-ossp+ extension instead:
20
22
  #
21
23
  # create_table :stuffs, id: false do |t|
22
24
  # t.primary_key :id, :uuid, default: "uuid_generate_v4()"
@@ -51,130 +53,144 @@ module ActiveRecord
51
53
  super
52
54
  end
53
55
 
54
- def bigserial(*args, **options)
55
- args.each { |name| column(name, :bigserial, options) }
56
- end
56
+ ##
57
+ # :method: bigserial
58
+ # :call-seq: bigserial(*names, **options)
57
59
 
58
- def bit(*args, **options)
59
- args.each { |name| column(name, :bit, options) }
60
- end
60
+ ##
61
+ # :method: bit
62
+ # :call-seq: bit(*names, **options)
61
63
 
62
- def bit_varying(*args, **options)
63
- args.each { |name| column(name, :bit_varying, options) }
64
- end
64
+ ##
65
+ # :method: bit_varying
66
+ # :call-seq: bit_varying(*names, **options)
65
67
 
66
- def cidr(*args, **options)
67
- args.each { |name| column(name, :cidr, options) }
68
- end
68
+ ##
69
+ # :method: cidr
70
+ # :call-seq: cidr(*names, **options)
69
71
 
70
- def citext(*args, **options)
71
- args.each { |name| column(name, :citext, options) }
72
- end
72
+ ##
73
+ # :method: citext
74
+ # :call-seq: citext(*names, **options)
73
75
 
74
- def daterange(*args, **options)
75
- args.each { |name| column(name, :daterange, options) }
76
- end
76
+ ##
77
+ # :method: daterange
78
+ # :call-seq: daterange(*names, **options)
77
79
 
78
- def hstore(*args, **options)
79
- args.each { |name| column(name, :hstore, options) }
80
- end
80
+ ##
81
+ # :method: hstore
82
+ # :call-seq: hstore(*names, **options)
81
83
 
82
- def inet(*args, **options)
83
- args.each { |name| column(name, :inet, options) }
84
- end
84
+ ##
85
+ # :method: inet
86
+ # :call-seq: inet(*names, **options)
85
87
 
86
- def interval(*args, **options)
87
- args.each { |name| column(name, :interval, options) }
88
- end
88
+ ##
89
+ # :method: interval
90
+ # :call-seq: interval(*names, **options)
89
91
 
90
- def int4range(*args, **options)
91
- args.each { |name| column(name, :int4range, options) }
92
- end
92
+ ##
93
+ # :method: int4range
94
+ # :call-seq: int4range(*names, **options)
93
95
 
94
- def int8range(*args, **options)
95
- args.each { |name| column(name, :int8range, options) }
96
- end
96
+ ##
97
+ # :method: int8range
98
+ # :call-seq: int8range(*names, **options)
97
99
 
98
- def jsonb(*args, **options)
99
- args.each { |name| column(name, :jsonb, options) }
100
- end
100
+ ##
101
+ # :method: jsonb
102
+ # :call-seq: jsonb(*names, **options)
101
103
 
102
- def ltree(*args, **options)
103
- args.each { |name| column(name, :ltree, options) }
104
- end
104
+ ##
105
+ # :method: ltree
106
+ # :call-seq: ltree(*names, **options)
105
107
 
106
- def macaddr(*args, **options)
107
- args.each { |name| column(name, :macaddr, options) }
108
- end
108
+ ##
109
+ # :method: macaddr
110
+ # :call-seq: macaddr(*names, **options)
109
111
 
110
- def money(*args, **options)
111
- args.each { |name| column(name, :money, options) }
112
- end
112
+ ##
113
+ # :method: money
114
+ # :call-seq: money(*names, **options)
113
115
 
114
- def numrange(*args, **options)
115
- args.each { |name| column(name, :numrange, options) }
116
- end
116
+ ##
117
+ # :method: numrange
118
+ # :call-seq: numrange(*names, **options)
117
119
 
118
- def oid(*args, **options)
119
- args.each { |name| column(name, :oid, options) }
120
- end
120
+ ##
121
+ # :method: oid
122
+ # :call-seq: oid(*names, **options)
121
123
 
122
- def point(*args, **options)
123
- args.each { |name| column(name, :point, options) }
124
- end
124
+ ##
125
+ # :method: point
126
+ # :call-seq: point(*names, **options)
125
127
 
126
- def line(*args, **options)
127
- args.each { |name| column(name, :line, options) }
128
- end
128
+ ##
129
+ # :method: line
130
+ # :call-seq: line(*names, **options)
129
131
 
130
- def lseg(*args, **options)
131
- args.each { |name| column(name, :lseg, options) }
132
- end
132
+ ##
133
+ # :method: lseg
134
+ # :call-seq: lseg(*names, **options)
133
135
 
134
- def box(*args, **options)
135
- args.each { |name| column(name, :box, options) }
136
- end
136
+ ##
137
+ # :method: box
138
+ # :call-seq: box(*names, **options)
137
139
 
138
- def path(*args, **options)
139
- args.each { |name| column(name, :path, options) }
140
- end
140
+ ##
141
+ # :method: path
142
+ # :call-seq: path(*names, **options)
141
143
 
142
- def polygon(*args, **options)
143
- args.each { |name| column(name, :polygon, options) }
144
- end
144
+ ##
145
+ # :method: polygon
146
+ # :call-seq: polygon(*names, **options)
145
147
 
146
- def circle(*args, **options)
147
- args.each { |name| column(name, :circle, options) }
148
- end
148
+ ##
149
+ # :method: circle
150
+ # :call-seq: circle(*names, **options)
149
151
 
150
- def serial(*args, **options)
151
- args.each { |name| column(name, :serial, options) }
152
- end
152
+ ##
153
+ # :method: serial
154
+ # :call-seq: serial(*names, **options)
153
155
 
154
- def tsrange(*args, **options)
155
- args.each { |name| column(name, :tsrange, options) }
156
- end
156
+ ##
157
+ # :method: tsrange
158
+ # :call-seq: tsrange(*names, **options)
157
159
 
158
- def tstzrange(*args, **options)
159
- args.each { |name| column(name, :tstzrange, options) }
160
- end
160
+ ##
161
+ # :method: tstzrange
162
+ # :call-seq: tstzrange(*names, **options)
161
163
 
162
- def tsvector(*args, **options)
163
- args.each { |name| column(name, :tsvector, options) }
164
- end
164
+ ##
165
+ # :method: tsvector
166
+ # :call-seq: tsvector(*names, **options)
165
167
 
166
- def uuid(*args, **options)
167
- args.each { |name| column(name, :uuid, options) }
168
- end
168
+ ##
169
+ # :method: uuid
170
+ # :call-seq: uuid(*names, **options)
171
+
172
+ ##
173
+ # :method: xml
174
+ # :call-seq: xml(*names, **options)
169
175
 
170
- def xml(*args, **options)
171
- args.each { |name| column(name, :xml, options) }
176
+ included do
177
+ define_column_methods :bigserial, :bit, :bit_varying, :cidr, :citext, :daterange,
178
+ :hstore, :inet, :interval, :int4range, :int8range, :jsonb, :ltree, :macaddr,
179
+ :money, :numrange, :oid, :point, :line, :lseg, :box, :path, :polygon, :circle,
180
+ :serial, :tsrange, :tstzrange, :tsvector, :uuid, :xml
172
181
  end
173
182
  end
174
183
 
175
184
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
176
185
  include ColumnMethods
177
186
 
187
+ attr_reader :unlogged
188
+
189
+ def initialize(*, **)
190
+ super
191
+ @unlogged = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables
192
+ end
193
+
178
194
  private
179
195
  def integer_like_primary_key_type(type, options)
180
196
  if type == :bigint || options[:limit] == 8
@@ -5,7 +5,6 @@ module ActiveRecord
5
5
  module PostgreSQL
6
6
  class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
7
7
  private
8
-
9
8
  def extensions(stream)
10
9
  extensions = @connection.extensions
11
10
  if extensions.any?