activerecord 5.1.0 → 5.2.0.rc1

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 (260) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +410 -530
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record/aggregations.rb +6 -5
  8. data/lib/active_record/association_relation.rb +4 -2
  9. data/lib/active_record/associations/alias_tracker.rb +23 -32
  10. data/lib/active_record/associations/association.rb +20 -21
  11. data/lib/active_record/associations/association_scope.rb +49 -49
  12. data/lib/active_record/associations/belongs_to_association.rb +12 -10
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
  14. data/lib/active_record/associations/builder/association.rb +4 -7
  15. data/lib/active_record/associations/builder/belongs_to.rb +10 -6
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  18. data/lib/active_record/associations/builder/has_many.rb +2 -0
  19. data/lib/active_record/associations/builder/has_one.rb +2 -0
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  21. data/lib/active_record/associations/collection_association.rb +50 -41
  22. data/lib/active_record/associations/collection_proxy.rb +22 -39
  23. data/lib/active_record/associations/foreign_association.rb +2 -0
  24. data/lib/active_record/associations/has_many_association.rb +4 -2
  25. data/lib/active_record/associations/has_many_through_association.rb +12 -18
  26. data/lib/active_record/associations/has_one_association.rb +5 -1
  27. data/lib/active_record/associations/has_one_through_association.rb +8 -7
  28. data/lib/active_record/associations/join_dependency/join_association.rb +17 -64
  29. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  30. data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
  31. data/lib/active_record/associations/join_dependency.rb +27 -44
  32. data/lib/active_record/associations/preloader/association.rb +53 -92
  33. data/lib/active_record/associations/preloader/through_association.rb +72 -73
  34. data/lib/active_record/associations/preloader.rb +17 -37
  35. data/lib/active_record/associations/singular_association.rb +14 -10
  36. data/lib/active_record/associations/through_association.rb +26 -11
  37. data/lib/active_record/associations.rb +68 -76
  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/before_type_cast.rb +2 -0
  41. data/lib/active_record/attribute_methods/dirty.rb +24 -214
  42. data/lib/active_record/attribute_methods/primary_key.rb +10 -13
  43. data/lib/active_record/attribute_methods/query.rb +2 -0
  44. data/lib/active_record/attribute_methods/read.rb +8 -2
  45. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  47. data/lib/active_record/attribute_methods/write.rb +22 -19
  48. data/lib/active_record/attribute_methods.rb +48 -12
  49. data/lib/active_record/attributes.rb +7 -6
  50. data/lib/active_record/autosave_association.rb +8 -11
  51. data/lib/active_record/base.rb +2 -0
  52. data/lib/active_record/callbacks.rb +8 -6
  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 +14 -10
  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 +175 -33
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -2
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -24
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +58 -3
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +165 -85
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -97
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +118 -180
  69. data/lib/active_record/connection_adapters/column.rb +4 -2
  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 +11 -17
  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 -10
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -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 +30 -1
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +269 -126
  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 +64 -85
  116. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  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 +18 -0
  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 +92 -95
  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 +39 -60
  128. data/lib/active_record/counter_cache.rb +3 -2
  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 +17 -13
  132. data/lib/active_record/errors.rb +42 -3
  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 +67 -60
  138. data/lib/active_record/gem_version.rb +4 -2
  139. data/lib/active_record/inheritance.rb +9 -9
  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 +8 -6
  144. data/lib/active_record/locking/pessimistic.rb +9 -6
  145. data/lib/active_record/log_subscriber.rb +46 -4
  146. data/lib/active_record/migration/command_recorder.rb +11 -9
  147. data/lib/active_record/migration/compatibility.rb +74 -22
  148. data/lib/active_record/migration/join_table.rb +2 -0
  149. data/lib/active_record/migration.rb +181 -137
  150. data/lib/active_record/model_schema.rb +73 -58
  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 +153 -18
  155. data/lib/active_record/query_cache.rb +17 -12
  156. data/lib/active_record/querying.rb +4 -2
  157. data/lib/active_record/railtie.rb +61 -3
  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 +47 -37
  161. data/lib/active_record/readonly_attributes.rb +3 -2
  162. data/lib/active_record/reflection.rb +131 -204
  163. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  164. data/lib/active_record/relation/batches.rb +32 -17
  165. data/lib/active_record/relation/calculations.rb +58 -20
  166. data/lib/active_record/relation/delegation.rb +10 -29
  167. data/lib/active_record/relation/finder_methods.rb +74 -85
  168. data/lib/active_record/relation/from_clause.rb +2 -8
  169. data/lib/active_record/relation/merger.rb +51 -20
  170. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  171. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  172. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  173. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  174. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
  175. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
  176. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  177. data/lib/active_record/relation/predicate_builder.rb +53 -78
  178. data/lib/active_record/relation/query_attribute.rb +9 -2
  179. data/lib/active_record/relation/query_methods.rb +101 -95
  180. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  181. data/lib/active_record/relation/spawn_methods.rb +3 -1
  182. data/lib/active_record/relation/where_clause.rb +65 -67
  183. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  184. data/lib/active_record/relation.rb +99 -202
  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 +129 -121
  188. data/lib/active_record/schema.rb +4 -2
  189. data/lib/active_record/schema_dumper.rb +36 -26
  190. data/lib/active_record/schema_migration.rb +2 -0
  191. data/lib/active_record/scoping/default.rb +10 -7
  192. data/lib/active_record/scoping/named.rb +38 -12
  193. data/lib/active_record/scoping.rb +12 -10
  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 +3 -1
  198. data/lib/active_record/suppressor.rb +2 -0
  199. data/lib/active_record/table_metadata.rb +12 -3
  200. data/lib/active_record/tasks/database_tasks.rb +37 -25
  201. data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
  202. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
  203. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  204. data/lib/active_record/timestamp.rb +5 -5
  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/adapter_specific_registry.rb +2 -0
  209. data/lib/active_record/type/date.rb +2 -0
  210. data/lib/active_record/type/date_time.rb +2 -0
  211. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  212. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  213. data/lib/active_record/type/internal/timezone.rb +2 -0
  214. data/lib/active_record/type/json.rb +30 -0
  215. data/lib/active_record/type/serialized.rb +2 -0
  216. data/lib/active_record/type/text.rb +2 -0
  217. data/lib/active_record/type/time.rb +2 -0
  218. data/lib/active_record/type/type_map.rb +2 -0
  219. data/lib/active_record/type/unsigned_integer.rb +2 -0
  220. data/lib/active_record/type.rb +4 -1
  221. data/lib/active_record/type_caster/connection.rb +2 -0
  222. data/lib/active_record/type_caster/map.rb +3 -1
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/validations/absence.rb +2 -0
  225. data/lib/active_record/validations/associated.rb +2 -0
  226. data/lib/active_record/validations/length.rb +2 -0
  227. data/lib/active_record/validations/presence.rb +2 -0
  228. data/lib/active_record/validations/uniqueness.rb +35 -5
  229. data/lib/active_record/validations.rb +2 -0
  230. data/lib/active_record/version.rb +2 -0
  231. data/lib/active_record.rb +11 -4
  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/migration_generator.rb +3 -1
  235. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  237. data/lib/rails/generators/active_record/migration.rb +2 -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. data/lib/rails/generators/active_record.rb +3 -1
  242. metadata +25 -37
  243. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  244. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  245. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  246. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  247. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  248. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  249. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  250. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute_mutation_tracker.rb +0 -113
  253. data/lib/active_record/attribute_set/builder.rb +0 -124
  254. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  255. data/lib/active_record/attribute_set.rb +0 -113
  256. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  257. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  258. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  259. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  260. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Make sure we're using pg high enough for type casts and Ruby 2.2+ compatibility
2
- gem "pg", "~> 0.18"
4
+ gem "pg", ">= 0.18", "< 2.0"
3
5
  require "pg"
4
6
 
5
7
  require "active_record/connection_adapters/abstract_adapter"
@@ -62,11 +64,11 @@ module ActiveRecord
62
64
  # defaults to true.
63
65
  #
64
66
  # Any further options are used as connection parameters to libpq. See
65
- # http://www.postgresql.org/docs/current/static/libpq-connect.html for the
67
+ # https://www.postgresql.org/docs/current/static/libpq-connect.html for the
66
68
  # list of parameters.
67
69
  #
68
70
  # In addition, default connection parameters of libpq can be set per environment variables.
69
- # See http://www.postgresql.org/docs/current/static/libpq-envars.html .
71
+ # See https://www.postgresql.org/docs/current/static/libpq-envars.html .
70
72
  class PostgreSQLAdapter < AbstractAdapter
71
73
  ADAPTER_NAME = "PostgreSQL".freeze
72
74
 
@@ -74,7 +76,7 @@ module ActiveRecord
74
76
  primary_key: "bigserial primary key",
75
77
  string: { name: "character varying" },
76
78
  text: { name: "text" },
77
- integer: { name: "integer" },
79
+ integer: { name: "integer", limit: 4 },
78
80
  float: { name: "float" },
79
81
  decimal: { name: "decimal" },
80
82
  datetime: { name: "timestamp" },
@@ -119,19 +121,8 @@ module ActiveRecord
119
121
  include PostgreSQL::ReferentialIntegrity
120
122
  include PostgreSQL::SchemaStatements
121
123
  include PostgreSQL::DatabaseStatements
122
- include PostgreSQL::ColumnDumper
123
-
124
- def schema_creation # :nodoc:
125
- PostgreSQL::SchemaCreation.new self
126
- end
127
-
128
- def arel_visitor # :nodoc:
129
- Arel::Visitors::PostgreSQL.new(self)
130
- end
131
124
 
132
- # Returns true, since this connection adapter supports prepared statement
133
- # caching.
134
- def supports_statement_cache?
125
+ def supports_bulk_alter?
135
126
  true
136
127
  end
137
128
 
@@ -155,6 +146,10 @@ module ActiveRecord
155
146
  true
156
147
  end
157
148
 
149
+ def supports_validate_constraints?
150
+ true
151
+ end
152
+
158
153
  def supports_views?
159
154
  true
160
155
  end
@@ -179,7 +174,7 @@ module ActiveRecord
179
174
  { concurrently: "CONCURRENTLY" }
180
175
  end
181
176
 
182
- class StatementPool < ConnectionAdapters::StatementPool
177
+ class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
183
178
  def initialize(connection, max)
184
179
  super(max)
185
180
  @connection = connection
@@ -195,9 +190,9 @@ module ActiveRecord
195
190
  end
196
191
 
197
192
  private
198
-
199
193
  def dealloc(key)
200
194
  @connection.query "DEALLOCATE #{key}" if connection_active?
195
+ rescue PG::Error
201
196
  end
202
197
 
203
198
  def connection_active?
@@ -229,7 +224,7 @@ module ActiveRecord
229
224
  add_pg_decoders
230
225
 
231
226
  @type_map = Type::HashLookupTypeMap.new
232
- initialize_type_map(type_map)
227
+ initialize_type_map
233
228
  @local_tz = execute("SHOW TIME ZONE", "SCHEMA").first["TimeZone"]
234
229
  @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
235
230
  end
@@ -285,6 +280,11 @@ module ActiveRecord
285
280
  end
286
281
  end
287
282
 
283
+ def discard! # :nodoc:
284
+ @connection.socket_io.reopen(IO::NULL) rescue nil
285
+ @connection = nil
286
+ end
287
+
288
288
  def native_database_types #:nodoc:
289
289
  NATIVE_DATABASE_TYPES
290
290
  end
@@ -309,8 +309,8 @@ module ActiveRecord
309
309
  true
310
310
  end
311
311
 
312
- # Range datatypes weren't introduced until PostgreSQL 9.2
313
312
  def supports_ranges?
313
+ # Range datatypes weren't introduced until PostgreSQL 9.2
314
314
  postgresql_version >= 90200
315
315
  end
316
316
 
@@ -318,22 +318,26 @@ module ActiveRecord
318
318
  postgresql_version >= 90300
319
319
  end
320
320
 
321
+ def supports_foreign_tables?
322
+ postgresql_version >= 90300
323
+ end
324
+
321
325
  def supports_pgcrypto_uuid?
322
326
  postgresql_version >= 90400
323
327
  end
324
328
 
325
329
  def get_advisory_lock(lock_id) # :nodoc:
326
330
  unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
327
- raise(ArgumentError, "Postgres requires advisory lock ids to be a signed 64 bit integer")
331
+ raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
328
332
  end
329
- select_value("SELECT pg_try_advisory_lock(#{lock_id});")
333
+ query_value("SELECT pg_try_advisory_lock(#{lock_id})")
330
334
  end
331
335
 
332
336
  def release_advisory_lock(lock_id) # :nodoc:
333
337
  unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
334
- raise(ArgumentError, "Postgres requires advisory lock ids to be a signed 64 bit integer")
338
+ raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
335
339
  end
336
- select_value("SELECT pg_advisory_unlock(#{lock_id})")
340
+ query_value("SELECT pg_advisory_unlock(#{lock_id})")
337
341
  end
338
342
 
339
343
  def enable_extension(name)
@@ -349,46 +353,31 @@ module ActiveRecord
349
353
  end
350
354
 
351
355
  def extension_enabled?(name)
352
- if supports_extensions?
353
- res = exec_query "SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled",
354
- "SCHEMA"
355
- res.cast_values.first
356
- end
356
+ res = exec_query("SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled", "SCHEMA")
357
+ res.cast_values.first
357
358
  end
358
359
 
359
360
  def extensions
360
- if supports_extensions?
361
- exec_query("SELECT extname from pg_extension", "SCHEMA").cast_values
362
- else
363
- super
364
- end
361
+ exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
365
362
  end
366
363
 
367
364
  # Returns the configured supported identifier length supported by PostgreSQL
368
- def table_alias_length
369
- @max_identifier_length ||= select_value("SHOW max_identifier_length", "SCHEMA").to_i
365
+ def max_identifier_length
366
+ @max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
370
367
  end
371
- alias index_name_length table_alias_length
368
+ alias table_alias_length max_identifier_length
369
+ alias index_name_length max_identifier_length
372
370
 
373
371
  # Set the authorized user for this session
374
372
  def session_auth=(user)
375
373
  clear_cache!
376
- exec_query "SET SESSION AUTHORIZATION #{user}"
374
+ execute("SET SESSION AUTHORIZATION #{user}")
377
375
  end
378
376
 
379
377
  def use_insert_returning?
380
378
  @use_insert_returning
381
379
  end
382
380
 
383
- def update_table_definition(table_name, base) #:nodoc:
384
- PostgreSQL::Table.new(table_name, base)
385
- end
386
-
387
- def lookup_cast_type(sql_type) # :nodoc:
388
- oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").first["oid"].to_i
389
- super(oid)
390
- end
391
-
392
381
  def column_name_for_operation(operation, node) # :nodoc:
393
382
  OPERATION_ALIASES.fetch(operation) { operation.downcase }
394
383
  end
@@ -409,8 +398,7 @@ module ActiveRecord
409
398
  end
410
399
 
411
400
  private
412
-
413
- # See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
401
+ # See https://www.postgresql.org/docs/current/static/errcodes-appendix.html
414
402
  VALUE_LIMIT_VIOLATION = "22001"
415
403
  NUMERIC_VALUE_OUT_OF_RANGE = "22003"
416
404
  NOT_NULL_VIOLATION = "23502"
@@ -418,6 +406,8 @@ module ActiveRecord
418
406
  UNIQUE_VIOLATION = "23505"
419
407
  SERIALIZATION_FAILURE = "40001"
420
408
  DEADLOCK_DETECTED = "40P01"
409
+ LOCK_NOT_AVAILABLE = "55P03"
410
+ QUERY_CANCELED = "57014"
421
411
 
422
412
  def translate_exception(exception, message)
423
413
  return exception unless exception.respond_to?(:result)
@@ -437,6 +427,10 @@ module ActiveRecord
437
427
  SerializationFailure.new(message)
438
428
  when DEADLOCK_DETECTED
439
429
  Deadlocked.new(message)
430
+ when LOCK_NOT_AVAILABLE
431
+ LockWaitTimeout.new(message)
432
+ when QUERY_CANCELED
433
+ QueryCanceled.new(message)
440
434
  else
441
435
  super
442
436
  end
@@ -444,7 +438,7 @@ module ActiveRecord
444
438
 
445
439
  def get_oid_type(oid, fmod, column_name, sql_type = "".freeze)
446
440
  if !type_map.key?(oid)
447
- load_additional_types(type_map, [oid])
441
+ load_additional_types([oid])
448
442
  end
449
443
 
450
444
  type_map.fetch(oid, fmod, sql_type) {
@@ -455,10 +449,10 @@ module ActiveRecord
455
449
  }
456
450
  end
457
451
 
458
- def initialize_type_map(m)
459
- register_class_with_limit m, "int2", Type::Integer
460
- register_class_with_limit m, "int4", Type::Integer
461
- register_class_with_limit m, "int8", Type::Integer
452
+ def initialize_type_map(m = type_map)
453
+ m.register_type "int2", Type::Integer.new(limit: 2)
454
+ m.register_type "int4", Type::Integer.new(limit: 4)
455
+ m.register_type "int8", Type::Integer.new(limit: 8)
462
456
  m.register_type "oid", OID::Oid.new
463
457
  m.register_type "float4", Type::Float.new
464
458
  m.alias_type "float8", "float4"
@@ -477,7 +471,7 @@ module ActiveRecord
477
471
  m.register_type "bytea", OID::Bytea.new
478
472
  m.register_type "point", OID::Point.new
479
473
  m.register_type "hstore", OID::Hstore.new
480
- m.register_type "json", OID::Json.new
474
+ m.register_type "json", Type::Json.new
481
475
  m.register_type "jsonb", OID::Jsonb.new
482
476
  m.register_type "cidr", OID::Cidr.new
483
477
  m.register_type "inet", OID::Inet.new
@@ -522,18 +516,7 @@ module ActiveRecord
522
516
  end
523
517
  end
524
518
 
525
- load_additional_types(m)
526
- end
527
-
528
- def extract_limit(sql_type)
529
- case sql_type
530
- when /^bigint/i, /^int8/i
531
- 8
532
- when /^smallint/i
533
- 2
534
- else
535
- super
536
- end
519
+ load_additional_types
537
520
  end
538
521
 
539
522
  # Extracts the value from a PostgreSQL column default definition.
@@ -571,7 +554,7 @@ module ActiveRecord
571
554
  !default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
572
555
  end
573
556
 
574
- def load_additional_types(type_map, oids = nil)
557
+ def load_additional_types(oids = nil)
575
558
  initializer = OID::TypeMapInitializer.new(type_map)
576
559
 
577
560
  if supports_ranges?
@@ -590,7 +573,7 @@ module ActiveRecord
590
573
  if oids
591
574
  query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
592
575
  else
593
- query += initializer.query_conditions_for_initial_load(type_map)
576
+ query += initializer.query_conditions_for_initial_load
594
577
  end
595
578
 
596
579
  execute_and_clear(query, "SCHEMA", []) do |records|
@@ -655,7 +638,7 @@ module ActiveRecord
655
638
  # ActiveRecord::PreparedStatementCacheExpired
656
639
  #
657
640
  # Check here for more details:
658
- # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
641
+ # https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
659
642
  CACHED_PLAN_HEURISTIC = "cached plan must not change result type".freeze
660
643
  def is_cached_plan_failure?(e)
661
644
  pgerror = e.cause
@@ -720,18 +703,20 @@ module ActiveRecord
720
703
  # Use standard-conforming strings so we don't have to do the E'...' dance.
721
704
  set_standard_conforming_strings
722
705
 
706
+ variables = @config.fetch(:variables, {}).stringify_keys
707
+
723
708
  # If using Active Record's time zone support configure the connection to return
724
709
  # TIMESTAMP WITH ZONE types in UTC.
725
- # (SET TIME ZONE does not use an equals sign like other SET variables)
726
- if ActiveRecord::Base.default_timezone == :utc
727
- execute("SET time zone 'UTC'", "SCHEMA")
728
- elsif @local_tz
729
- execute("SET time zone '#{@local_tz}'", "SCHEMA")
710
+ unless variables["timezone"]
711
+ if ActiveRecord::Base.default_timezone == :utc
712
+ variables["timezone"] = "UTC"
713
+ elsif @local_tz
714
+ variables["timezone"] = @local_tz
715
+ end
730
716
  end
731
717
 
732
718
  # SET statements from :variables config hash
733
- # http://www.postgresql.org/docs/current/static/sql-set.html
734
- variables = @config[:variables] || {}
719
+ # https://www.postgresql.org/docs/current/static/sql-set.html
735
720
  variables.map do |k, v|
736
721
  if v == ":default" || v == :default
737
722
  # Sets the value to the global or compile default
@@ -742,11 +727,6 @@ module ActiveRecord
742
727
  end
743
728
  end
744
729
 
745
- # Returns the current ID of a table's sequence.
746
- def last_insert_id_result(sequence_name)
747
- exec_query("SELECT currval('#{sequence_name}')", "SQL")
748
- end
749
-
750
730
  # Returns the list of a table's column names, data types, and default values.
751
731
  #
752
732
  # The underlying query is roughly:
@@ -785,8 +765,8 @@ module ActiveRecord
785
765
  $1.strip if $1
786
766
  end
787
767
 
788
- def create_table_definition(*args)
789
- PostgreSQL::TableDefinition.new(*args)
768
+ def arel_visitor
769
+ Arel::Visitors::PostgreSQL.new(self)
790
770
  end
791
771
 
792
772
  def can_perform_case_insensitive_comparison_for?(column)
@@ -862,7 +842,6 @@ module ActiveRecord
862
842
  ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
863
843
  ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
864
844
  ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
865
- ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
866
845
  ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
867
846
  ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
868
847
  ActiveRecord::Type.register(:point, OID::Point, adapter: :postgresql)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  class SchemaCache
@@ -26,7 +28,7 @@ module ActiveRecord
26
28
  coder["columns_hash"] = @columns_hash
27
29
  coder["primary_keys"] = @primary_keys
28
30
  coder["data_sources"] = @data_sources
29
- coder["version"] = ActiveRecord::Migrator.current_version
31
+ coder["version"] = connection.migration_context.current_version
30
32
  end
31
33
 
32
34
  def init_with(coder)
@@ -98,7 +100,7 @@ module ActiveRecord
98
100
 
99
101
  def marshal_dump
100
102
  # if we get current version during initialization, it happens stack over flow.
101
- @version = ActiveRecord::Migrator.current_version
103
+ @version = connection.migration_context.current_version
102
104
  [@version, @columns, @columns_hash, @primary_keys, @data_sources]
103
105
  end
104
106
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # :stopdoc:
3
5
  module ConnectionAdapters
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
@@ -22,6 +24,22 @@ module ActiveRecord
22
24
  "x'#{value.hex}'"
23
25
  end
24
26
 
27
+ def quoted_true
28
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? "1".freeze : "'t'".freeze
29
+ end
30
+
31
+ def unquoted_true
32
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? 1 : "t".freeze
33
+ end
34
+
35
+ def quoted_false
36
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? "0".freeze : "'f'".freeze
37
+ end
38
+
39
+ def unquoted_false
40
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? 0 : "f".freeze
41
+ end
42
+
25
43
  private
26
44
 
27
45
  def _type_cast(value)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
@@ -1,27 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
4
- module ColumnMethods
5
- def primary_key(name, type = :primary_key, **options)
6
- if %i(integer bigint).include?(type) && (options.delete(:auto_increment) == true || !options.key?(:default))
7
- type = :primary_key
8
- end
9
-
10
- super
11
- end
12
- end
13
-
14
6
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
15
- include ColumnMethods
16
-
17
7
  def references(*args, **options)
18
8
  super(*args, type: :integer, **options)
19
9
  end
20
10
  alias :belongs_to :references
21
- end
22
11
 
23
- class Table < ActiveRecord::ConnectionAdapters::Table
24
- include ColumnMethods
12
+ private
13
+ def integer_like_primary_key_type(type, options)
14
+ :primary_key
15
+ end
25
16
  end
26
17
  end
27
18
  end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
4
- module ColumnDumper # :nodoc:
6
+ class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
5
7
  private
6
-
7
8
  def default_primary_key?(column)
8
9
  schema_type(column) == :integer
9
10
  end
@@ -1,13 +1,83 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
4
6
  module SchemaStatements # :nodoc:
7
+ # Returns an array of indexes for the given table.
8
+ def indexes(table_name)
9
+ exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
10
+ index_sql = query_value(<<-SQL, "SCHEMA")
11
+ SELECT sql
12
+ FROM sqlite_master
13
+ WHERE name = #{quote(row['name'])} AND type = 'index'
14
+ UNION ALL
15
+ SELECT sql
16
+ FROM sqlite_temp_master
17
+ WHERE name = #{quote(row['name'])} AND type = 'index'
18
+ SQL
19
+
20
+ /\sWHERE\s+(?<where>.+)$/i =~ index_sql
21
+
22
+ columns = exec_query("PRAGMA index_info(#{quote(row['name'])})", "SCHEMA").map do |col|
23
+ col["name"]
24
+ end
25
+
26
+ # Add info on sort order for columns (only desc order is explicitly specified, asc is
27
+ # the default)
28
+ orders = {}
29
+ if index_sql # index_sql can be null in case of primary key indexes
30
+ index_sql.scan(/"(\w+)" DESC/).flatten.each { |order_column|
31
+ orders[order_column] = :desc
32
+ }
33
+ end
34
+
35
+ IndexDefinition.new(
36
+ table_name,
37
+ row["name"],
38
+ row["unique"] != 0,
39
+ columns,
40
+ where: where,
41
+ orders: orders
42
+ )
43
+ end
44
+ end
45
+
46
+ def create_schema_dumper(options)
47
+ SQLite3::SchemaDumper.create(self, options)
48
+ end
49
+
5
50
  private
51
+ def schema_creation
52
+ SQLite3::SchemaCreation.new(self)
53
+ end
54
+
55
+ def create_table_definition(*args)
56
+ SQLite3::TableDefinition.new(*args)
57
+ end
58
+
59
+ def new_column_from_field(table_name, field)
60
+ default = \
61
+ case field["dflt_value"]
62
+ when /^null$/i
63
+ nil
64
+ when /^'(.*)'$/m
65
+ $1.gsub("''", "'")
66
+ when /^"(.*)"$/m
67
+ $1.gsub('""', '"')
68
+ else
69
+ field["dflt_value"]
70
+ end
71
+
72
+ type_metadata = fetch_type_metadata(field["type"])
73
+ Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, table_name, nil, field["collation"])
74
+ end
75
+
6
76
  def data_source_sql(name = nil, type: nil)
7
77
  scope = quoted_scope(name, type: type)
8
78
  scope[:type] ||= "'table','view'"
9
79
 
10
- sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'"
80
+ sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'".dup
11
81
  sql << " AND name = #{scope[:name]}" if scope[:name]
12
82
  sql << " AND type IN (#{scope[:type]})"
13
83
  sql