activerecord 5.1.7 → 5.2.0.beta1

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 (259) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +221 -900
  3. data/README.rdoc +3 -3
  4. data/examples/performance.rb +2 -0
  5. data/examples/simple.rb +2 -0
  6. data/lib/active_record.rb +10 -3
  7. data/lib/active_record/aggregations.rb +2 -0
  8. data/lib/active_record/association_relation.rb +2 -0
  9. data/lib/active_record/associations.rb +13 -42
  10. data/lib/active_record/associations/alias_tracker.rb +17 -17
  11. data/lib/active_record/associations/association.rb +11 -22
  12. data/lib/active_record/associations/association_scope.rb +32 -44
  13. data/lib/active_record/associations/belongs_to_association.rb +6 -4
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
  15. data/lib/active_record/associations/builder/association.rb +2 -5
  16. data/lib/active_record/associations/builder/belongs_to.rb +7 -12
  17. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  19. data/lib/active_record/associations/builder/has_many.rb +2 -0
  20. data/lib/active_record/associations/builder/has_one.rb +2 -0
  21. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  22. data/lib/active_record/associations/collection_association.rb +41 -33
  23. data/lib/active_record/associations/collection_proxy.rb +11 -14
  24. data/lib/active_record/associations/foreign_association.rb +2 -0
  25. data/lib/active_record/associations/has_many_association.rb +4 -2
  26. data/lib/active_record/associations/has_many_through_association.rb +4 -2
  27. data/lib/active_record/associations/has_one_association.rb +3 -1
  28. data/lib/active_record/associations/has_one_through_association.rb +3 -1
  29. data/lib/active_record/associations/join_dependency.rb +22 -40
  30. data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
  31. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  32. data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
  33. data/lib/active_record/associations/preloader.rb +17 -37
  34. data/lib/active_record/associations/preloader/association.rb +42 -58
  35. data/lib/active_record/associations/preloader/through_association.rb +71 -79
  36. data/lib/active_record/associations/singular_association.rb +14 -10
  37. data/lib/active_record/associations/through_association.rb +3 -1
  38. data/lib/active_record/attribute_assignment.rb +2 -0
  39. data/lib/active_record/attribute_decorators.rb +3 -2
  40. data/lib/active_record/attribute_methods.rb +47 -7
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  42. data/lib/active_record/attribute_methods/dirty.rb +25 -214
  43. data/lib/active_record/attribute_methods/primary_key.rb +7 -6
  44. data/lib/active_record/attribute_methods/query.rb +2 -0
  45. data/lib/active_record/attribute_methods/read.rb +8 -2
  46. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  48. data/lib/active_record/attribute_methods/write.rb +21 -9
  49. data/lib/active_record/attributes.rb +7 -6
  50. data/lib/active_record/autosave_association.rb +5 -11
  51. data/lib/active_record/base.rb +2 -0
  52. data/lib/active_record/callbacks.rb +6 -8
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +2 -0
  55. data/lib/active_record/collection_cache_key.rb +10 -5
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +120 -28
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
  69. data/lib/active_record/connection_adapters/column.rb +3 -1
  70. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +3 -1
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -6
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -1
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +3 -5
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -0
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +47 -82
  116. data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  118. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +19 -2
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  122. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  123. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
  124. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -89
  125. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  126. data/lib/active_record/connection_handling.rb +4 -2
  127. data/lib/active_record/core.rb +27 -57
  128. data/lib/active_record/counter_cache.rb +15 -12
  129. data/lib/active_record/define_callbacks.rb +5 -3
  130. data/lib/active_record/dynamic_matchers.rb +9 -9
  131. data/lib/active_record/enum.rb +15 -13
  132. data/lib/active_record/errors.rb +54 -21
  133. data/lib/active_record/explain.rb +3 -1
  134. data/lib/active_record/explain_registry.rb +2 -0
  135. data/lib/active_record/explain_subscriber.rb +2 -0
  136. data/lib/active_record/fixture_set/file.rb +2 -0
  137. data/lib/active_record/fixtures.rb +40 -24
  138. data/lib/active_record/gem_version.rb +5 -3
  139. data/lib/active_record/inheritance.rb +6 -5
  140. data/lib/active_record/integration.rb +58 -19
  141. data/lib/active_record/internal_metadata.rb +2 -0
  142. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  143. data/lib/active_record/locking/optimistic.rb +31 -20
  144. data/lib/active_record/locking/pessimistic.rb +10 -7
  145. data/lib/active_record/log_subscriber.rb +2 -0
  146. data/lib/active_record/migration.rb +47 -21
  147. data/lib/active_record/migration/command_recorder.rb +11 -9
  148. data/lib/active_record/migration/compatibility.rb +20 -2
  149. data/lib/active_record/migration/join_table.rb +2 -0
  150. data/lib/active_record/model_schema.rb +29 -38
  151. data/lib/active_record/nested_attributes.rb +18 -6
  152. data/lib/active_record/no_touching.rb +3 -1
  153. data/lib/active_record/null_relation.rb +2 -0
  154. data/lib/active_record/persistence.rb +184 -40
  155. data/lib/active_record/query_cache.rb +17 -12
  156. data/lib/active_record/querying.rb +3 -1
  157. data/lib/active_record/railtie.rb +54 -1
  158. data/lib/active_record/railties/console_sandbox.rb +2 -0
  159. data/lib/active_record/railties/controller_runtime.rb +2 -0
  160. data/lib/active_record/railties/databases.rake +41 -28
  161. data/lib/active_record/readonly_attributes.rb +3 -2
  162. data/lib/active_record/reflection.rb +100 -182
  163. data/lib/active_record/relation.rb +61 -193
  164. data/lib/active_record/relation/batches.rb +20 -5
  165. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  166. data/lib/active_record/relation/calculations.rb +40 -23
  167. data/lib/active_record/relation/delegation.rb +10 -27
  168. data/lib/active_record/relation/finder_methods.rb +53 -49
  169. data/lib/active_record/relation/from_clause.rb +2 -8
  170. data/lib/active_record/relation/merger.rb +22 -19
  171. data/lib/active_record/relation/predicate_builder.rb +42 -79
  172. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  173. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  174. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  179. data/lib/active_record/relation/query_attribute.rb +9 -2
  180. data/lib/active_record/relation/query_methods.rb +80 -69
  181. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  182. data/lib/active_record/relation/spawn_methods.rb +2 -0
  183. data/lib/active_record/relation/where_clause.rb +50 -67
  184. data/lib/active_record/relation/where_clause_factory.rb +4 -46
  185. data/lib/active_record/result.rb +2 -0
  186. data/lib/active_record/runtime_registry.rb +2 -0
  187. data/lib/active_record/sanitization.rb +15 -9
  188. data/lib/active_record/schema.rb +3 -1
  189. data/lib/active_record/schema_dumper.rb +24 -23
  190. data/lib/active_record/schema_migration.rb +2 -0
  191. data/lib/active_record/scoping.rb +9 -8
  192. data/lib/active_record/scoping/default.rb +6 -7
  193. data/lib/active_record/scoping/named.rb +15 -7
  194. data/lib/active_record/secure_token.rb +2 -0
  195. data/lib/active_record/serialization.rb +2 -0
  196. data/lib/active_record/statement_cache.rb +22 -12
  197. data/lib/active_record/store.rb +2 -0
  198. data/lib/active_record/suppressor.rb +2 -0
  199. data/lib/active_record/table_metadata.rb +3 -1
  200. data/lib/active_record/tasks/database_tasks.rb +23 -12
  201. data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
  202. data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
  203. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  204. data/lib/active_record/timestamp.rb +5 -12
  205. data/lib/active_record/touch_later.rb +2 -0
  206. data/lib/active_record/transactions.rb +9 -7
  207. data/lib/active_record/translation.rb +2 -0
  208. data/lib/active_record/type.rb +4 -1
  209. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  210. data/lib/active_record/type/date.rb +2 -0
  211. data/lib/active_record/type/date_time.rb +2 -0
  212. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  213. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  214. data/lib/active_record/type/internal/timezone.rb +2 -0
  215. data/lib/active_record/type/json.rb +30 -0
  216. data/lib/active_record/type/serialized.rb +2 -4
  217. data/lib/active_record/type/text.rb +2 -0
  218. data/lib/active_record/type/time.rb +2 -0
  219. data/lib/active_record/type/type_map.rb +2 -0
  220. data/lib/active_record/type/unsigned_integer.rb +2 -0
  221. data/lib/active_record/type_caster.rb +2 -0
  222. data/lib/active_record/type_caster/connection.rb +2 -0
  223. data/lib/active_record/type_caster/map.rb +2 -0
  224. data/lib/active_record/validations.rb +2 -0
  225. data/lib/active_record/validations/absence.rb +2 -0
  226. data/lib/active_record/validations/associated.rb +2 -0
  227. data/lib/active_record/validations/length.rb +2 -0
  228. data/lib/active_record/validations/presence.rb +2 -0
  229. data/lib/active_record/validations/uniqueness.rb +36 -6
  230. data/lib/active_record/version.rb +2 -0
  231. data/lib/rails/generators/active_record.rb +3 -1
  232. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  233. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  234. data/lib/rails/generators/active_record/migration.rb +2 -0
  235. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  236. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  237. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  238. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  239. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  241. metadata +25 -38
  242. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  243. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  244. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  245. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  246. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  248. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  249. data/lib/active_record/attribute.rb +0 -240
  250. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  251. data/lib/active_record/attribute_mutation_tracker.rb +0 -122
  252. data/lib/active_record/attribute_set.rb +0 -113
  253. data/lib/active_record/attribute_set/builder.rb +0 -126
  254. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  255. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  256. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  257. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  258. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  259. data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record/connection_adapters/postgresql/oid/array"
2
4
  require "active_record/connection_adapters/postgresql/oid/bit"
3
5
  require "active_record/connection_adapters/postgresql/oid/bit_varying"
@@ -8,7 +10,6 @@ require "active_record/connection_adapters/postgresql/oid/decimal"
8
10
  require "active_record/connection_adapters/postgresql/oid/enum"
9
11
  require "active_record/connection_adapters/postgresql/oid/hstore"
10
12
  require "active_record/connection_adapters/postgresql/oid/inet"
11
- require "active_record/connection_adapters/postgresql/oid/json"
12
13
  require "active_record/connection_adapters/postgresql/oid/jsonb"
13
14
  require "active_record/connection_adapters/postgresql/oid/money"
14
15
  require "active_record/connection_adapters/postgresql/oid/oid"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -31,13 +33,7 @@ module ActiveRecord
31
33
 
32
34
  def cast(value)
33
35
  if value.is_a?(::String)
34
- value = begin
35
- @pg_decoder.decode(value)
36
- rescue TypeError
37
- # malformed array string is treated as [], will raise in PG 2.0 gem
38
- # this keeps a consistent implementation
39
- []
40
- end
36
+ value = @pg_decoder.decode(value)
41
37
  end
42
38
  type_cast_array(value, :cast)
43
39
  end
@@ -70,10 +66,6 @@ module ActiveRecord
70
66
  deserialize(raw_old_value) != new_value
71
67
  end
72
68
 
73
- def force_equality?(value)
74
- value.is_a?(::Array)
75
- end
76
-
77
69
  private
78
70
 
79
71
  def type_cast_array(value, method)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "ipaddr"
2
4
 
3
5
  module ActiveRecord
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Decimal < Type::Decimal # :nodoc:
6
8
  def infinity(options = {})
7
- BigDecimal("Infinity") * (options[:negative] ? -1 : 1)
9
+ BigDecimal.new("Infinity") * (options[:negative] ? -1 : 1)
8
10
  end
9
11
  end
10
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
- class Jsonb < Json # :nodoc:
7
+ class Jsonb < Type::Json # :nodoc:
6
8
  def type
7
9
  :jsonb
8
10
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -22,7 +24,7 @@ module ActiveRecord
22
24
  # (3) -$2.55
23
25
  # (4) ($2.55)
24
26
 
25
- value.sub!(/^\((.+)\)$/, '-\1') # (4)
27
+ value = value.sub(/^\((.+)\)$/, '-\1') # (4)
26
28
  case value
27
29
  when /^-?\D+[\d,]+\.\d{2}$/ # (1)
28
30
  value.gsub!(/[^-\d.]/, "")
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  Point = Struct.new(:x, :y)
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -33,7 +35,7 @@ module ActiveRecord
33
35
  if value.is_a?(::Range)
34
36
  from = type_cast_single_for_database(value.begin)
35
37
  to = type_cast_single_for_database(value.end)
36
- "[#{from},#{to}#{value.exclude_end? ? ')' : ']'}"
38
+ ::Range.new(from, to, value.exclude_end?)
37
39
  else
38
40
  super
39
41
  end
@@ -51,10 +53,6 @@ module ActiveRecord
51
53
  ::Range.new(new_begin, new_end, value.exclude_end?)
52
54
  end
53
55
 
54
- def force_equality?(value)
55
- value.is_a?(::Range)
56
- end
57
-
58
56
  private
59
57
 
60
58
  def type_cast_single(value)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -29,8 +31,8 @@ module ActiveRecord
29
31
  composites.each { |row| register_composite_type(row) }
30
32
  end
31
33
 
32
- def query_conditions_for_initial_load(type_map)
33
- known_type_names = type_map.keys.map { |n| "'#{n}'" }
34
+ def query_conditions_for_initial_load
35
+ known_type_names = @store.keys.map { |n| "'#{n}'" }
34
36
  known_type_types = %w('r' 'e' 'd')
35
37
  <<-SQL % [known_type_names.join(", "), known_type_types.join(", ")]
36
38
  WHERE
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Uuid < Type::Value # :nodoc:
6
- ACCEPTABLE_UUID = %r{\A\{?([a-fA-F0-9]{4}-?){8}\}?\z}x
8
+ ACCEPTABLE_UUID = %r{\A(\{)?([a-fA-F0-9]{4}-?){8}(?(1)\}|)\z}
7
9
 
8
10
  alias_method :serialize, :deserialize
9
11
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -99,6 +101,8 @@ module ActiveRecord
99
101
  end
100
102
  when OID::Array::Data
101
103
  _quote(encode_array(value))
104
+ when Range
105
+ _quote(encode_range(value))
102
106
  else
103
107
  super
104
108
  end
@@ -115,6 +119,8 @@ module ActiveRecord
115
119
  value.to_s
116
120
  when OID::Array::Data
117
121
  encode_array(value)
122
+ when Range
123
+ encode_range(value)
118
124
  else
119
125
  super
120
126
  end
@@ -131,6 +137,10 @@ module ActiveRecord
131
137
  result
132
138
  end
133
139
 
140
+ def encode_range(range)
141
+ "[#{type_cast(range.first)},#{type_cast(range.last)}#{range.exclude_end? ? ')' : ']'}"
142
+ end
143
+
134
144
  def determine_encoding_of_strings_in_array(value)
135
145
  case value
136
146
  when ::Array then determine_encoding_of_strings_in_array(value.first)
@@ -1,27 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module ReferentialIntegrity # :nodoc:
5
- def supports_disable_referential_integrity? # :nodoc:
6
- true
7
- end
8
-
9
7
  def disable_referential_integrity # :nodoc:
10
- if supports_disable_referential_integrity?
11
- original_exception = nil
8
+ original_exception = nil
12
9
 
13
- begin
14
- transaction(requires_new: true) do
15
- execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
16
- end
17
- rescue ActiveRecord::ActiveRecordError => e
18
- original_exception = e
10
+ begin
11
+ transaction(requires_new: true) do
12
+ execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
19
13
  end
14
+ rescue ActiveRecord::ActiveRecordError => e
15
+ original_exception = e
16
+ end
20
17
 
21
- begin
22
- yield
23
- rescue ActiveRecord::InvalidForeignKey => e
24
- warn <<-WARNING
18
+ begin
19
+ yield
20
+ rescue ActiveRecord::InvalidForeignKey => e
21
+ warn <<-WARNING
25
22
  WARNING: Rails was not able to disable referential integrity.
26
23
 
27
24
  This is most likely caused due to missing permissions.
@@ -30,17 +27,14 @@ Rails needs superuser privileges to disable referential integrity.
30
27
  cause: #{original_exception.try(:message)}
31
28
 
32
29
  WARNING
33
- raise e
34
- end
30
+ raise e
31
+ end
35
32
 
36
- begin
37
- transaction(requires_new: true) do
38
- execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
39
- end
40
- rescue ActiveRecord::ActiveRecordError
33
+ begin
34
+ transaction(requires_new: true) do
35
+ execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
41
36
  end
42
- else
43
- yield
37
+ rescue ActiveRecord::ActiveRecordError
44
38
  end
45
39
  end
46
40
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -42,15 +44,8 @@ module ActiveRecord
42
44
  # a record (as primary keys cannot be +nil+). This might be done via the
43
45
  # +SecureRandom.uuid+ method and a +before_save+ callback, for instance.
44
46
  def primary_key(name, type = :primary_key, **options)
45
- options[:auto_increment] = true if [:integer, :bigint].include?(type) && !options.key?(:default)
46
47
  if type == :uuid
47
48
  options[:default] = options.fetch(:default, "gen_random_uuid()")
48
- elsif options.delete(:auto_increment) == true && %i(integer bigint).include?(type)
49
- type = if type == :bigint || options[:limit] == 8
50
- :bigserial
51
- else
52
- :serial
53
- end
54
49
  end
55
50
 
56
51
  super
@@ -183,6 +178,15 @@ module ActiveRecord
183
178
 
184
179
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
185
180
  include ColumnMethods
181
+
182
+ private
183
+ def integer_like_primary_key_type(type, options)
184
+ if type == :bigint || options[:limit] == 8
185
+ :bigserial
186
+ else
187
+ :serial
188
+ end
189
+ end
186
190
  end
187
191
 
188
192
  class Table < ActiveRecord::ConnectionAdapters::Table
@@ -1,21 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
- module ColumnDumper # :nodoc:
5
- # Adds +:array+ option to the default set
6
- def prepare_column_options(column)
7
- spec = super
8
- spec[:array] = "true" if column.array?
9
- spec
10
- end
11
-
12
- # Adds +:array+ as a valid migration key
13
- def migration_keys
14
- super + [:array]
15
- end
16
-
6
+ class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
17
7
  private
18
8
 
9
+ def extensions(stream)
10
+ extensions = @connection.extensions
11
+ if extensions.any?
12
+ stream.puts " # These are extensions that must be enabled in order to support this database"
13
+ extensions.sort.each do |extension|
14
+ stream.puts " enable_extension #{extension.inspect}"
15
+ end
16
+ stream.puts
17
+ end
18
+ end
19
+
20
+ def prepare_column_options(column)
21
+ spec = super
22
+ spec[:array] = "true" if column.array?
23
+ spec
24
+ end
25
+
19
26
  def default_primary_key?(column)
20
27
  schema_type(column) == :bigserial
21
28
  end
@@ -1,4 +1,4 @@
1
- require "active_support/core_ext/string/strip"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
@@ -64,12 +64,7 @@ module ActiveRecord
64
64
  end
65
65
 
66
66
  # Verifies existence of an index with a given name.
67
- def index_name_exists?(table_name, index_name, default = nil)
68
- unless default.nil?
69
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
70
- Passing default to #index_name_exists? is deprecated without replacement.
71
- MSG
72
- end
67
+ def index_name_exists?(table_name, index_name)
73
68
  table = quoted_scope(table_name)
74
69
  index = quoted_scope(index_name)
75
70
 
@@ -87,13 +82,7 @@ module ActiveRecord
87
82
  end
88
83
 
89
84
  # Returns an array of indexes for the given table.
90
- def indexes(table_name, name = nil) # :nodoc:
91
- if name
92
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
93
- Passing name to #indexes is deprecated without replacement.
94
- MSG
95
- end
96
-
85
+ def indexes(table_name) # :nodoc:
97
86
  scope = quoted_scope(table_name)
98
87
 
99
88
  result = query(<<-SQL, "SCHEMA")
@@ -122,7 +111,7 @@ module ActiveRecord
122
111
  comment = row[5]
123
112
  opclass = row[6]
124
113
 
125
- using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/m).flatten
114
+ using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/).flatten
126
115
 
127
116
  if indkey.include?(0) || opclass > 0
128
117
  columns = expressions
@@ -140,28 +129,17 @@ module ActiveRecord
140
129
  ]
141
130
  end
142
131
 
143
- IndexDefinition.new(table_name, index_name, unique, columns, [], orders, where, nil, using.to_sym, comment.presence)
144
- end.compact
145
- end
146
-
147
- def new_column_from_field(table_name, field) # :nondoc:
148
- column_name, type, default, notnull, oid, fmod, collation, comment = field
149
- oid = oid.to_i
150
- fmod = fmod.to_i
151
- type_metadata = fetch_type_metadata(column_name, type, oid, fmod)
152
- default_value = extract_value_from_default(default)
153
- default_function = extract_default_function(default_value, default)
154
- PostgreSQLColumn.new(
155
- column_name,
156
- default_value,
157
- type_metadata,
158
- !notnull,
159
- table_name,
160
- default_function,
161
- collation,
162
- comment: comment.presence,
163
- max_identifier_length: max_identifier_length
164
- )
132
+ IndexDefinition.new(
133
+ table_name,
134
+ index_name,
135
+ unique,
136
+ columns,
137
+ orders: orders,
138
+ where: where,
139
+ using: using.to_sym,
140
+ comment: comment.presence
141
+ )
142
+ end
165
143
  end
166
144
 
167
145
  def table_options(table_name) # :nodoc:
@@ -233,7 +211,7 @@ module ActiveRecord
233
211
 
234
212
  # Sets the schema search path to a string of comma-separated schema names.
235
213
  # Names beginning with $ have to be quoted (e.g. $user => '$user').
236
- # See: http://www.postgresql.org/docs/current/static/ddl-schemas.html
214
+ # See: https://www.postgresql.org/docs/current/static/ddl-schemas.html
237
215
  #
238
216
  # This should be not be called manually but set in database.yml.
239
217
  def schema_search_path=(schema_csv)
@@ -334,7 +312,7 @@ module ActiveRecord
334
312
  AND seq.relnamespace = nsp.oid
335
313
  AND cons.contype = 'p'
336
314
  AND dep.classid = 'pg_class'::regclass
337
- AND dep.refobjid = '#{quote_table_name(table)}'::regclass
315
+ AND dep.refobjid = #{quote(quote_table_name(table))}::regclass
338
316
  end_sql
339
317
 
340
318
  if result.nil? || result.empty?
@@ -352,7 +330,7 @@ module ActiveRecord
352
330
  JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
353
331
  JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
354
332
  JOIN pg_namespace nsp ON (t.relnamespace = nsp.oid)
355
- WHERE t.oid = '#{quote_table_name(table)}'::regclass
333
+ WHERE t.oid = #{quote(quote_table_name(table))}::regclass
356
334
  AND cons.contype = 'p'
357
335
  AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate'
358
336
  end_sql
@@ -394,14 +372,15 @@ module ActiveRecord
394
372
  clear_cache!
395
373
  execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
396
374
  pk, seq = pk_and_sequence_for(new_name)
397
- if seq && seq.identifier == "#{table_name}_#{pk}_seq"
398
- new_seq = "#{new_name}_#{pk}_seq"
375
+ if pk
399
376
  idx = "#{table_name}_pkey"
400
377
  new_idx = "#{new_name}_pkey"
401
- execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
402
378
  execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}"
379
+ if seq && seq.identifier == "#{table_name}_#{pk}_seq"
380
+ new_seq = "#{new_name}_#{pk}_seq"
381
+ execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
382
+ end
403
383
  end
404
-
405
384
  rename_table_indexes(table_name, new_name)
406
385
  end
407
386
 
@@ -416,7 +395,7 @@ module ActiveRecord
416
395
  quoted_table_name = quote_table_name(table_name)
417
396
  quoted_column_name = quote_column_name(column_name)
418
397
  sql_type = type_to_sql(type, options)
419
- sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}"
398
+ sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}".dup
420
399
  if options[:collation]
421
400
  sql << " COLLATE \"#{options[:collation]}\""
422
401
  end
@@ -547,14 +526,6 @@ module ActiveRecord
547
526
  end
548
527
  end
549
528
 
550
- def extract_foreign_key_action(specifier) # :nodoc:
551
- case specifier
552
- when "c"; :cascade
553
- when "n"; :nullify
554
- when "r"; :restrict
555
- end
556
- end
557
-
558
529
  # Maps logical Rails types to PostgreSQL-specific data types.
559
530
  def type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil, **) # :nodoc:
560
531
  sql = \
@@ -584,7 +555,7 @@ module ActiveRecord
584
555
  super
585
556
  end
586
557
 
587
- sql << "[]" if array && type != :primary_key
558
+ sql = "#{sql}[]" if array && type != :primary_key
588
559
  sql
589
560
  end
590
561
 
@@ -602,24 +573,67 @@ module ActiveRecord
602
573
  [super, *order_columns].join(", ")
603
574
  end
604
575
 
605
- def fetch_type_metadata(column_name, sql_type, oid, fmod)
606
- cast_type = get_oid_type(oid, fmod, column_name, sql_type)
607
- simple_type = SqlTypeMetadata.new(
608
- sql_type: sql_type,
609
- type: cast_type.type,
610
- limit: cast_type.limit,
611
- precision: cast_type.precision,
612
- scale: cast_type.scale,
613
- )
614
- PostgreSQLTypeMetadata.new(simple_type, oid: oid, fmod: fmod)
576
+ def update_table_definition(table_name, base) # :nodoc:
577
+ PostgreSQL::Table.new(table_name, base)
578
+ end
579
+
580
+ def create_schema_dumper(options) # :nodoc:
581
+ PostgreSQL::SchemaDumper.create(self, options)
615
582
  end
616
583
 
617
584
  private
585
+ def schema_creation
586
+ PostgreSQL::SchemaCreation.new(self)
587
+ end
588
+
589
+ def create_table_definition(*args)
590
+ PostgreSQL::TableDefinition.new(*args)
591
+ end
592
+
593
+ def new_column_from_field(table_name, field)
594
+ column_name, type, default, notnull, oid, fmod, collation, comment = field
595
+ type_metadata = fetch_type_metadata(column_name, type, oid.to_i, fmod.to_i)
596
+ default_value = extract_value_from_default(default)
597
+ default_function = extract_default_function(default_value, default)
598
+
599
+ PostgreSQLColumn.new(
600
+ column_name,
601
+ default_value,
602
+ type_metadata,
603
+ !notnull,
604
+ table_name,
605
+ default_function,
606
+ collation,
607
+ comment: comment.presence,
608
+ max_identifier_length: max_identifier_length
609
+ )
610
+ end
611
+
612
+ def fetch_type_metadata(column_name, sql_type, oid, fmod)
613
+ cast_type = get_oid_type(oid, fmod, column_name, sql_type)
614
+ simple_type = SqlTypeMetadata.new(
615
+ sql_type: sql_type,
616
+ type: cast_type.type,
617
+ limit: cast_type.limit,
618
+ precision: cast_type.precision,
619
+ scale: cast_type.scale,
620
+ )
621
+ PostgreSQLTypeMetadata.new(simple_type, oid: oid, fmod: fmod)
622
+ end
623
+
624
+ def extract_foreign_key_action(specifier)
625
+ case specifier
626
+ when "c"; :cascade
627
+ when "n"; :nullify
628
+ when "r"; :restrict
629
+ end
630
+ end
631
+
618
632
  def data_source_sql(name = nil, type: nil)
619
633
  scope = quoted_scope(name, type: type)
620
634
  scope[:type] ||= "'r','v','m'" # (r)elation/table, (v)iew, (m)aterialized view
621
635
 
622
- sql = "SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace"
636
+ sql = "SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace".dup
623
637
  sql << " WHERE n.nspname = #{scope[:schema]}"
624
638
  sql << " AND c.relname = #{scope[:name]}" if scope[:name]
625
639
  sql << " AND c.relkind IN (#{scope[:type]})"