activerecord 5.0.7.2 → 5.1.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 (216) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +389 -2252
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record.rb +20 -20
  8. data/lib/active_record/aggregations.rb +244 -244
  9. data/lib/active_record/association_relation.rb +5 -5
  10. data/lib/active_record/associations.rb +1579 -1569
  11. data/lib/active_record/associations/alias_tracker.rb +1 -1
  12. data/lib/active_record/associations/association.rb +23 -15
  13. data/lib/active_record/associations/association_scope.rb +83 -81
  14. data/lib/active_record/associations/belongs_to_association.rb +0 -1
  15. data/lib/active_record/associations/builder/belongs_to.rb +16 -14
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  18. data/lib/active_record/associations/collection_association.rb +74 -241
  19. data/lib/active_record/associations/collection_proxy.rb +144 -70
  20. data/lib/active_record/associations/has_many_association.rb +15 -19
  21. data/lib/active_record/associations/has_many_through_association.rb +12 -5
  22. data/lib/active_record/associations/has_one_association.rb +22 -28
  23. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  24. data/lib/active_record/associations/join_dependency.rb +117 -115
  25. data/lib/active_record/associations/join_dependency/join_association.rb +16 -13
  26. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  28. data/lib/active_record/associations/preloader.rb +94 -94
  29. data/lib/active_record/associations/preloader/association.rb +87 -64
  30. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  31. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  32. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  33. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +34 -41
  35. data/lib/active_record/associations/singular_association.rb +8 -25
  36. data/lib/active_record/associations/through_association.rb +3 -6
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  39. data/lib/active_record/attribute_assignment.rb +61 -61
  40. data/lib/active_record/attribute_decorators.rb +35 -13
  41. data/lib/active_record/attribute_methods.rb +56 -65
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  43. data/lib/active_record/attribute_methods/dirty.rb +216 -34
  44. data/lib/active_record/attribute_methods/primary_key.rb +78 -73
  45. data/lib/active_record/attribute_methods/read.rb +39 -35
  46. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  48. data/lib/active_record/attribute_methods/write.rb +36 -30
  49. data/lib/active_record/attribute_mutation_tracker.rb +53 -10
  50. data/lib/active_record/attribute_set.rb +9 -6
  51. data/lib/active_record/attribute_set/builder.rb +41 -49
  52. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  53. data/lib/active_record/attributes.rb +21 -21
  54. data/lib/active_record/autosave_association.rb +13 -13
  55. data/lib/active_record/base.rb +24 -22
  56. data/lib/active_record/callbacks.rb +52 -14
  57. data/lib/active_record/coders/yaml_column.rb +9 -11
  58. data/lib/active_record/collection_cache_key.rb +6 -17
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +320 -278
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -34
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -27
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -57
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +9 -19
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +78 -79
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +99 -93
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -5
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +156 -128
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +424 -382
  71. data/lib/active_record/connection_adapters/column.rb +27 -5
  72. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  73. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -43
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +49 -31
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +5 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +24 -26
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -28
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -35
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +9 -9
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  94. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  95. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  97. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +28 -30
  98. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +38 -36
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +161 -170
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +4 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -7
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +179 -152
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -20
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +187 -130
  116. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  117. data/lib/active_record/connection_handling.rb +14 -26
  118. data/lib/active_record/core.rb +110 -93
  119. data/lib/active_record/counter_cache.rb +62 -13
  120. data/lib/active_record/define_callbacks.rb +20 -0
  121. data/lib/active_record/dynamic_matchers.rb +80 -79
  122. data/lib/active_record/enum.rb +8 -6
  123. data/lib/active_record/errors.rb +58 -15
  124. data/lib/active_record/explain.rb +1 -2
  125. data/lib/active_record/explain_registry.rb +1 -1
  126. data/lib/active_record/explain_subscriber.rb +7 -4
  127. data/lib/active_record/fixture_set/file.rb +11 -8
  128. data/lib/active_record/fixtures.rb +66 -53
  129. data/lib/active_record/gem_version.rb +3 -3
  130. data/lib/active_record/inheritance.rb +93 -79
  131. data/lib/active_record/integration.rb +7 -7
  132. data/lib/active_record/internal_metadata.rb +3 -16
  133. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  134. data/lib/active_record/locking/optimistic.rb +64 -56
  135. data/lib/active_record/locking/pessimistic.rb +10 -1
  136. data/lib/active_record/log_subscriber.rb +29 -29
  137. data/lib/active_record/migration.rb +155 -172
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +76 -37
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/model_schema.rb +85 -119
  142. data/lib/active_record/nested_attributes.rb +200 -199
  143. data/lib/active_record/null_relation.rb +10 -33
  144. data/lib/active_record/persistence.rb +45 -38
  145. data/lib/active_record/query_cache.rb +4 -8
  146. data/lib/active_record/querying.rb +2 -3
  147. data/lib/active_record/railtie.rb +16 -17
  148. data/lib/active_record/railties/controller_runtime.rb +6 -2
  149. data/lib/active_record/railties/databases.rake +125 -140
  150. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  151. data/lib/active_record/readonly_attributes.rb +2 -2
  152. data/lib/active_record/reflection.rb +79 -96
  153. data/lib/active_record/relation.rb +72 -115
  154. data/lib/active_record/relation/batches.rb +87 -58
  155. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  156. data/lib/active_record/relation/calculations.rb +154 -160
  157. data/lib/active_record/relation/delegation.rb +30 -29
  158. data/lib/active_record/relation/finder_methods.rb +195 -226
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder.rb +92 -89
  161. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  162. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  163. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  164. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  165. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  166. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +247 -295
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +79 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/result.rb +29 -31
  174. data/lib/active_record/runtime_registry.rb +3 -3
  175. data/lib/active_record/sanitization.rb +182 -197
  176. data/lib/active_record/schema.rb +3 -3
  177. data/lib/active_record/schema_dumper.rb +14 -37
  178. data/lib/active_record/schema_migration.rb +3 -3
  179. data/lib/active_record/scoping.rb +9 -10
  180. data/lib/active_record/scoping/default.rb +87 -91
  181. data/lib/active_record/scoping/named.rb +16 -28
  182. data/lib/active_record/secure_token.rb +2 -2
  183. data/lib/active_record/statement_cache.rb +13 -15
  184. data/lib/active_record/store.rb +31 -32
  185. data/lib/active_record/suppressor.rb +2 -1
  186. data/lib/active_record/table_metadata.rb +9 -5
  187. data/lib/active_record/tasks/database_tasks.rb +72 -65
  188. data/lib/active_record/tasks/mysql_database_tasks.rb +75 -72
  189. data/lib/active_record/tasks/postgresql_database_tasks.rb +53 -48
  190. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  191. data/lib/active_record/timestamp.rb +39 -25
  192. data/lib/active_record/touch_later.rb +1 -2
  193. data/lib/active_record/transactions.rb +98 -110
  194. data/lib/active_record/type.rb +17 -13
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +9 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/serialized.rb +8 -8
  199. data/lib/active_record/type/text.rb +9 -0
  200. data/lib/active_record/type/time.rb +0 -1
  201. data/lib/active_record/type/type_map.rb +11 -15
  202. data/lib/active_record/type/unsigned_integer.rb +15 -0
  203. data/lib/active_record/type_caster.rb +2 -2
  204. data/lib/active_record/type_caster/connection.rb +8 -6
  205. data/lib/active_record/type_caster/map.rb +3 -1
  206. data/lib/active_record/validations.rb +4 -4
  207. data/lib/active_record/validations/associated.rb +1 -1
  208. data/lib/active_record/validations/presence.rb +2 -2
  209. data/lib/active_record/validations/uniqueness.rb +8 -39
  210. data/lib/active_record/version.rb +1 -1
  211. data/lib/rails/generators/active_record.rb +4 -4
  212. data/lib/rails/generators/active_record/migration.rb +2 -2
  213. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  215. metadata +22 -13
  216. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -8,7 +8,7 @@ module ActiveRecord
8
8
  @type_metadata = type_metadata
9
9
  @oid = oid
10
10
  @fmod = fmod
11
- @array = /\[\]$/ === type_metadata.sql_type
11
+ @array = /\[\]$/.match?(type_metadata.sql_type)
12
12
  end
13
13
 
14
14
  def sql_type
@@ -27,9 +27,9 @@ module ActiveRecord
27
27
 
28
28
  protected
29
29
 
30
- def attributes_for_hash
31
- [self.class, @type_metadata, oid, fmod]
32
- end
30
+ def attributes_for_hash
31
+ [self.class, @type_metadata, oid, fmod]
32
+ end
33
33
  end
34
34
  end
35
35
  end
@@ -19,9 +19,9 @@ module ActiveRecord
19
19
 
20
20
  def quoted
21
21
  if schema
22
- PG::Connection.quote_ident(schema) << SEPARATOR << PG::Connection.quote_ident(identifier)
22
+ PGconn.quote_ident(schema) << SEPARATOR << PGconn.quote_ident(identifier)
23
23
  else
24
- PG::Connection.quote_ident(identifier)
24
+ PGconn.quote_ident(identifier)
25
25
  end
26
26
  end
27
27
 
@@ -35,6 +35,12 @@ module ActiveRecord
35
35
  end
36
36
 
37
37
  protected
38
+
39
+ def parts
40
+ @parts ||= [@schema, @identifier].compact
41
+ end
42
+
43
+ private
38
44
  def unquote(part)
39
45
  if part && part.start_with?('"')
40
46
  part[1..-2]
@@ -42,10 +48,6 @@ module ActiveRecord
42
48
  part
43
49
  end
44
50
  end
45
-
46
- def parts
47
- @parts ||= [@schema, @identifier].compact
48
- end
49
51
  end
50
52
 
51
53
  module Utils # :nodoc:
@@ -53,7 +55,7 @@ module ActiveRecord
53
55
 
54
56
  # Returns an instance of <tt>ActiveRecord::ConnectionAdapters::PostgreSQL::Name</tt>
55
57
  # extracted from +string+.
56
- # +schema+ is nil if not specified in +string+.
58
+ # +schema+ is +nil+ if not specified in +string+.
57
59
  # +schema+ and +identifier+ exclude surrounding quotes (regardless of whether provided in +string+)
58
60
  # +string+ supports the range of schema/table references understood by PostgreSQL, for example:
59
61
  #
@@ -1,6 +1,6 @@
1
1
  # Make sure we're using pg high enough for type casts and Ruby 2.2+ compatibility
2
- gem "pg", ">= 0.18", "< 2.0"
3
- require 'pg'
2
+ gem "pg", "~> 0.18"
3
+ require "pg"
4
4
 
5
5
  require "active_record/connection_adapters/abstract_adapter"
6
6
  require "active_record/connection_adapters/postgresql/column"
@@ -9,6 +9,7 @@ require "active_record/connection_adapters/postgresql/explain_pretty_printer"
9
9
  require "active_record/connection_adapters/postgresql/oid"
10
10
  require "active_record/connection_adapters/postgresql/quoting"
11
11
  require "active_record/connection_adapters/postgresql/referential_integrity"
12
+ require "active_record/connection_adapters/postgresql/schema_creation"
12
13
  require "active_record/connection_adapters/postgresql/schema_definitions"
13
14
  require "active_record/connection_adapters/postgresql/schema_dumper"
14
15
  require "active_record/connection_adapters/postgresql/schema_statements"
@@ -28,11 +29,11 @@ module ActiveRecord
28
29
  conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
29
30
  conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
30
31
 
31
- # Forward only valid config params to PG::Connection.connect.
32
- valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
32
+ # Forward only valid config params to PGconn.connect.
33
+ valid_conn_param_keys = PGconn.conndefaults_hash.keys + [:requiressl]
33
34
  conn_params.slice!(*valid_conn_param_keys)
34
35
 
35
- # The postgres drivers don't allow the creation of an unconnected PG::Connection object,
36
+ # The postgres drivers don't allow the creation of an unconnected PGconn object,
36
37
  # so just pass a nil connection object for the time being.
37
38
  ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, conn_params, config)
38
39
  end
@@ -67,10 +68,10 @@ module ActiveRecord
67
68
  # In addition, default connection parameters of libpq can be set per environment variables.
68
69
  # See http://www.postgresql.org/docs/current/static/libpq-envars.html .
69
70
  class PostgreSQLAdapter < AbstractAdapter
70
- ADAPTER_NAME = 'PostgreSQL'.freeze
71
+ ADAPTER_NAME = "PostgreSQL".freeze
71
72
 
72
73
  NATIVE_DATABASE_TYPES = {
73
- primary_key: "serial primary key",
74
+ primary_key: "bigserial primary key",
74
75
  string: { name: "character varying" },
75
76
  text: { name: "text" },
76
77
  integer: { name: "integer" },
@@ -108,6 +109,8 @@ module ActiveRecord
108
109
  bit: { name: "bit" },
109
110
  bit_varying: { name: "bit varying" },
110
111
  money: { name: "money" },
112
+ interval: { name: "interval" },
113
+ oid: { name: "oid" },
111
114
  }
112
115
 
113
116
  OID = PostgreSQL::OID #:nodoc:
@@ -173,7 +176,7 @@ module ActiveRecord
173
176
  end
174
177
 
175
178
  def index_algorithms
176
- { concurrently: 'CONCURRENTLY' }
179
+ { concurrently: "CONCURRENTLY" }
177
180
  end
178
181
 
179
182
  class StatementPool < ConnectionAdapters::StatementPool
@@ -198,8 +201,8 @@ module ActiveRecord
198
201
  end
199
202
 
200
203
  def connection_active?
201
- @connection.status == PG::CONNECTION_OK
202
- rescue PG::Error
204
+ @connection.status == PGconn::CONNECTION_OK
205
+ rescue PGError
203
206
  false
204
207
  end
205
208
  end
@@ -212,7 +215,7 @@ module ActiveRecord
212
215
 
213
216
  # @local_tz is initialized as nil to avoid warnings when connect tries to use it
214
217
  @local_tz = nil
215
- @max_identifier_length = nil
218
+ @table_alias_length = nil
216
219
 
217
220
  connect
218
221
  add_pg_encoders
@@ -227,13 +230,15 @@ module ActiveRecord
227
230
 
228
231
  @type_map = Type::HashLookupTypeMap.new
229
232
  initialize_type_map(type_map)
230
- @local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
233
+ @local_tz = execute("SHOW TIME ZONE", "SCHEMA").first["TimeZone"]
231
234
  @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
232
235
  end
233
236
 
234
237
  # Clears the prepared statements cache.
235
238
  def clear_cache!
236
- @statements.clear
239
+ @lock.synchronize do
240
+ @statements.clear
241
+ end
237
242
  end
238
243
 
239
244
  def truncate(table_name, name = nil)
@@ -242,9 +247,9 @@ module ActiveRecord
242
247
 
243
248
  # Is this connection alive and ready for queries?
244
249
  def active?
245
- @connection.query 'SELECT 1'
250
+ @connection.query "SELECT 1"
246
251
  true
247
- rescue PG::Error
252
+ rescue PGError
248
253
  false
249
254
  end
250
255
 
@@ -259,9 +264,9 @@ module ActiveRecord
259
264
  clear_cache!
260
265
  reset_transaction
261
266
  unless @connection.transaction_status == ::PG::PQTRANS_IDLE
262
- @connection.query 'ROLLBACK'
267
+ @connection.query "ROLLBACK"
263
268
  end
264
- @connection.query 'DISCARD ALL'
269
+ @connection.query "DISCARD ALL"
265
270
  configure_connection
266
271
  end
267
272
 
@@ -281,13 +286,8 @@ module ActiveRecord
281
286
  true
282
287
  end
283
288
 
284
- # Does PostgreSQL support finding primary key on non-Active Record tables?
285
- def supports_primary_key? #:nodoc:
286
- true
287
- end
288
-
289
289
  def set_standard_conforming_strings
290
- execute('SET standard_conforming_strings = on', 'SCHEMA')
290
+ execute("SET standard_conforming_strings = on", "SCHEMA")
291
291
  end
292
292
 
293
293
  def supports_ddl_transactions?
@@ -315,6 +315,10 @@ module ActiveRecord
315
315
  postgresql_version >= 90300
316
316
  end
317
317
 
318
+ def supports_pgcrypto_uuid?
319
+ postgresql_version >= 90400
320
+ end
321
+
318
322
  def get_advisory_lock(lock_id) # :nodoc:
319
323
  unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
320
324
  raise(ArgumentError, "Postgres requires advisory lock ids to be a signed 64 bit integer")
@@ -344,7 +348,7 @@ module ActiveRecord
344
348
  def extension_enabled?(name)
345
349
  if supports_extensions?
346
350
  res = exec_query "SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled",
347
- 'SCHEMA'
351
+ "SCHEMA"
348
352
  res.cast_values.first
349
353
  end
350
354
  end
@@ -358,11 +362,9 @@ module ActiveRecord
358
362
  end
359
363
 
360
364
  # Returns the configured supported identifier length supported by PostgreSQL
361
- def max_identifier_length
362
- @max_identifier_length ||= query('SHOW max_identifier_length', 'SCHEMA')[0][0].to_i
365
+ def table_alias_length
366
+ @table_alias_length ||= query("SHOW max_identifier_length", "SCHEMA")[0][0].to_i
363
367
  end
364
- alias table_alias_length max_identifier_length
365
- alias index_name_length max_identifier_length
366
368
 
367
369
  # Set the authorized user for this session
368
370
  def session_auth=(user)
@@ -383,7 +385,7 @@ module ActiveRecord
383
385
  end
384
386
 
385
387
  def lookup_cast_type(sql_type) # :nodoc:
386
- oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").first['oid'].to_i
388
+ oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").first["oid"].to_i
387
389
  super(oid)
388
390
  end
389
391
 
@@ -402,89 +404,105 @@ module ActiveRecord
402
404
  @connection.server_version
403
405
  end
404
406
 
405
- protected
407
+ def default_index_type?(index) # :nodoc:
408
+ index.using == :btree || super
409
+ end
410
+
411
+ private
406
412
 
407
413
  # See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
408
414
  VALUE_LIMIT_VIOLATION = "22001"
415
+ NUMERIC_VALUE_OUT_OF_RANGE = "22003"
416
+ NOT_NULL_VIOLATION = "23502"
409
417
  FOREIGN_KEY_VIOLATION = "23503"
410
418
  UNIQUE_VIOLATION = "23505"
419
+ SERIALIZATION_FAILURE = "40001"
420
+ DEADLOCK_DETECTED = "40P01"
411
421
 
412
422
  def translate_exception(exception, message)
413
423
  return exception unless exception.respond_to?(:result)
414
424
 
415
- case exception.result.try(:error_field, PG::PG_DIAG_SQLSTATE)
425
+ case exception.result.try(:error_field, PGresult::PG_DIAG_SQLSTATE)
416
426
  when UNIQUE_VIOLATION
417
427
  RecordNotUnique.new(message)
418
428
  when FOREIGN_KEY_VIOLATION
419
429
  InvalidForeignKey.new(message)
420
430
  when VALUE_LIMIT_VIOLATION
421
431
  ValueTooLong.new(message)
432
+ when NUMERIC_VALUE_OUT_OF_RANGE
433
+ RangeError.new(message)
434
+ when NOT_NULL_VIOLATION
435
+ NotNullViolation.new(message)
436
+ when SERIALIZATION_FAILURE
437
+ SerializationFailure.new(message)
438
+ when DEADLOCK_DETECTED
439
+ Deadlocked.new(message)
422
440
  else
423
441
  super
424
442
  end
425
443
  end
426
444
 
427
- private
428
-
429
- def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
445
+ def get_oid_type(oid, fmod, column_name, sql_type = "".freeze)
430
446
  if !type_map.key?(oid)
431
447
  load_additional_types(type_map, [oid])
432
448
  end
433
449
 
434
450
  type_map.fetch(oid, fmod, sql_type) {
435
451
  warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String."
436
- Type::Value.new.tap do |cast_type|
452
+ Type.default_value.tap do |cast_type|
437
453
  type_map.register_type(oid, cast_type)
438
454
  end
439
455
  }
440
456
  end
441
457
 
442
- def initialize_type_map(m) # :nodoc:
443
- register_class_with_limit m, 'int2', Type::Integer
444
- register_class_with_limit m, 'int4', Type::Integer
445
- register_class_with_limit m, 'int8', Type::Integer
446
- m.alias_type 'oid', 'int2'
447
- m.register_type 'float4', Type::Float.new
448
- m.alias_type 'float8', 'float4'
449
- m.register_type 'text', Type::Text.new
450
- register_class_with_limit m, 'varchar', Type::String
451
- m.alias_type 'char', 'varchar'
452
- m.alias_type 'name', 'varchar'
453
- m.alias_type 'bpchar', 'varchar'
454
- m.register_type 'bool', Type::Boolean.new
455
- register_class_with_limit m, 'bit', OID::Bit
456
- register_class_with_limit m, 'varbit', OID::BitVarying
457
- m.alias_type 'timestamptz', 'timestamp'
458
- m.register_type 'date', Type::Date.new
459
-
460
- m.register_type 'money', OID::Money.new
461
- m.register_type 'bytea', OID::Bytea.new
462
- m.register_type 'point', OID::Point.new
463
- m.register_type 'hstore', OID::Hstore.new
464
- m.register_type 'json', OID::Json.new
465
- m.register_type 'jsonb', OID::Jsonb.new
466
- m.register_type 'cidr', OID::Cidr.new
467
- m.register_type 'inet', OID::Inet.new
468
- m.register_type 'uuid', OID::Uuid.new
469
- m.register_type 'xml', OID::Xml.new
470
- m.register_type 'tsvector', OID::SpecializedString.new(:tsvector)
471
- m.register_type 'macaddr', OID::SpecializedString.new(:macaddr)
472
- m.register_type 'citext', OID::SpecializedString.new(:citext)
473
- m.register_type 'ltree', OID::SpecializedString.new(:ltree)
474
- m.register_type 'line', OID::SpecializedString.new(:line)
475
- m.register_type 'lseg', OID::SpecializedString.new(:lseg)
476
- m.register_type 'box', OID::SpecializedString.new(:box)
477
- m.register_type 'path', OID::SpecializedString.new(:path)
478
- m.register_type 'polygon', OID::SpecializedString.new(:polygon)
479
- m.register_type 'circle', OID::SpecializedString.new(:circle)
480
-
481
- # FIXME: why are we keeping these types as strings?
482
- m.alias_type 'interval', 'varchar'
483
-
484
- register_class_with_precision m, 'time', Type::Time
485
- register_class_with_precision m, 'timestamp', OID::DateTime
486
-
487
- m.register_type 'numeric' do |_, fmod, sql_type|
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
462
+ m.register_type "oid", OID::Oid.new
463
+ m.register_type "float4", Type::Float.new
464
+ m.alias_type "float8", "float4"
465
+ m.register_type "text", Type::Text.new
466
+ register_class_with_limit m, "varchar", Type::String
467
+ m.alias_type "char", "varchar"
468
+ m.alias_type "name", "varchar"
469
+ m.alias_type "bpchar", "varchar"
470
+ m.register_type "bool", Type::Boolean.new
471
+ register_class_with_limit m, "bit", OID::Bit
472
+ register_class_with_limit m, "varbit", OID::BitVarying
473
+ m.alias_type "timestamptz", "timestamp"
474
+ m.register_type "date", Type::Date.new
475
+
476
+ m.register_type "money", OID::Money.new
477
+ m.register_type "bytea", OID::Bytea.new
478
+ m.register_type "point", OID::Point.new
479
+ m.register_type "hstore", OID::Hstore.new
480
+ m.register_type "json", OID::Json.new
481
+ m.register_type "jsonb", OID::Jsonb.new
482
+ m.register_type "cidr", OID::Cidr.new
483
+ m.register_type "inet", OID::Inet.new
484
+ m.register_type "uuid", OID::Uuid.new
485
+ m.register_type "xml", OID::Xml.new
486
+ m.register_type "tsvector", OID::SpecializedString.new(:tsvector)
487
+ m.register_type "macaddr", OID::SpecializedString.new(:macaddr)
488
+ m.register_type "citext", OID::SpecializedString.new(:citext)
489
+ m.register_type "ltree", OID::SpecializedString.new(:ltree)
490
+ m.register_type "line", OID::SpecializedString.new(:line)
491
+ m.register_type "lseg", OID::SpecializedString.new(:lseg)
492
+ m.register_type "box", OID::SpecializedString.new(:box)
493
+ m.register_type "path", OID::SpecializedString.new(:path)
494
+ m.register_type "polygon", OID::SpecializedString.new(:polygon)
495
+ m.register_type "circle", OID::SpecializedString.new(:circle)
496
+
497
+ m.register_type "interval" do |_, _, sql_type|
498
+ precision = extract_precision(sql_type)
499
+ OID::SpecializedString.new(:interval, precision: precision)
500
+ end
501
+
502
+ register_class_with_precision m, "time", Type::Time
503
+ register_class_with_precision m, "timestamp", OID::DateTime
504
+
505
+ m.register_type "numeric" do |_, fmod, sql_type|
488
506
  precision = extract_precision(sql_type)
489
507
  scale = extract_scale(sql_type)
490
508
 
@@ -507,7 +525,7 @@ module ActiveRecord
507
525
  load_additional_types(m)
508
526
  end
509
527
 
510
- def extract_limit(sql_type) # :nodoc:
528
+ def extract_limit(sql_type)
511
529
  case sql_type
512
530
  when /^bigint/i, /^int8/i
513
531
  8
@@ -519,41 +537,41 @@ module ActiveRecord
519
537
  end
520
538
 
521
539
  # Extracts the value from a PostgreSQL column default definition.
522
- def extract_value_from_default(default) # :nodoc:
540
+ def extract_value_from_default(default)
523
541
  case default
524
542
  # Quoted types
525
- when /\A[\(B]?'(.*)'.*::"?([\w. ]+)"?(?:\[\])?\z/m
526
- # The default 'now'::date is CURRENT_DATE
527
- if $1 == "now".freeze && $2 == "date".freeze
528
- nil
529
- else
530
- $1.gsub("''".freeze, "'".freeze)
531
- end
543
+ when /\A[\(B]?'(.*)'.*::"?([\w. ]+)"?(?:\[\])?\z/m
544
+ # The default 'now'::date is CURRENT_DATE
545
+ if $1 == "now".freeze && $2 == "date".freeze
546
+ nil
547
+ else
548
+ $1.gsub("''".freeze, "'".freeze)
549
+ end
532
550
  # Boolean types
533
- when 'true'.freeze, 'false'.freeze
534
- default
551
+ when "true".freeze, "false".freeze
552
+ default
535
553
  # Numeric types
536
- when /\A\(?(-?\d+(\.\d*)?)\)?(::bigint)?\z/
537
- $1
554
+ when /\A\(?(-?\d+(\.\d*)?)\)?(::bigint)?\z/
555
+ $1
538
556
  # Object identifier types
539
- when /\A-?\d+\z/
540
- $1
541
- else
542
- # Anything else is blank, some user type, or some function
543
- # and we can't know the value of that, so return nil.
544
- nil
557
+ when /\A-?\d+\z/
558
+ $1
559
+ else
560
+ # Anything else is blank, some user type, or some function
561
+ # and we can't know the value of that, so return nil.
562
+ nil
545
563
  end
546
564
  end
547
565
 
548
- def extract_default_function(default_value, default) # :nodoc:
566
+ def extract_default_function(default_value, default)
549
567
  default if has_default_function?(default_value, default)
550
568
  end
551
569
 
552
- def has_default_function?(default_value, default) # :nodoc:
570
+ def has_default_function?(default_value, default)
553
571
  !default_value && (%r{\w+\(.*\)|\(.*\)::\w+} === default)
554
572
  end
555
573
 
556
- def load_additional_types(type_map, oids = nil) # :nodoc:
574
+ def load_additional_types(type_map, oids = nil)
557
575
  initializer = OID::TypeMapInitializer.new(type_map)
558
576
 
559
577
  if supports_ranges?
@@ -575,7 +593,7 @@ module ActiveRecord
575
593
  query += initializer.query_conditions_for_initial_load(type_map)
576
594
  end
577
595
 
578
- execute_and_clear(query, 'SCHEMA', []) do |records|
596
+ execute_and_clear(query, "SCHEMA", []) do |records|
579
597
  initializer.run(records)
580
598
  end
581
599
  end
@@ -597,7 +615,11 @@ module ActiveRecord
597
615
 
598
616
  def exec_no_cache(sql, name, binds)
599
617
  type_casted_binds = type_casted_binds(binds)
600
- log(sql, name, binds, type_casted_binds) { @connection.async_exec(sql, type_casted_binds) }
618
+ log(sql, name, binds, type_casted_binds) do
619
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
620
+ @connection.async_exec(sql, type_casted_binds)
621
+ end
622
+ end
601
623
  end
602
624
 
603
625
  def exec_cache(sql, name, binds)
@@ -605,7 +627,9 @@ module ActiveRecord
605
627
  type_casted_binds = type_casted_binds(binds)
606
628
 
607
629
  log(sql, name, binds, type_casted_binds, stmt_key) do
608
- @connection.exec_prepared(stmt_key, type_casted_binds)
630
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
631
+ @connection.exec_prepared(stmt_key, type_casted_binds)
632
+ end
609
633
  end
610
634
  rescue ActiveRecord::StatementInvalid => e
611
635
  raise unless is_cached_plan_failure?(e)
@@ -615,8 +639,10 @@ module ActiveRecord
615
639
  if in_transaction?
616
640
  raise ActiveRecord::PreparedStatementCacheExpired.new(e.cause.message)
617
641
  else
618
- # outside of transactions we can simply flush this query and retry
619
- @statements.delete sql_key(sql)
642
+ @lock.synchronize do
643
+ # outside of transactions we can simply flush this query and retry
644
+ @statements.delete sql_key(sql)
645
+ end
620
646
  retry
621
647
  end
622
648
  end
@@ -630,10 +656,10 @@ module ActiveRecord
630
656
  #
631
657
  # Check here for more details:
632
658
  # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
633
- CACHED_PLAN_HEURISTIC = 'cached plan must not change result type'.freeze
659
+ CACHED_PLAN_HEURISTIC = "cached plan must not change result type".freeze
634
660
  def is_cached_plan_failure?(e)
635
661
  pgerror = e.cause
636
- code = pgerror.result.result_error_field(PG::PG_DIAG_SQLSTATE)
662
+ code = pgerror.result.result_error_field(PGresult::PG_DIAG_SQLSTATE)
637
663
  code == FEATURE_NOT_SUPPORTED && pgerror.message.include?(CACHED_PLAN_HEURISTIC)
638
664
  rescue
639
665
  false
@@ -652,25 +678,27 @@ module ActiveRecord
652
678
  # Prepare the statement if it hasn't been prepared, return
653
679
  # the statement key.
654
680
  def prepare_statement(sql)
655
- sql_key = sql_key(sql)
656
- unless @statements.key? sql_key
657
- nextkey = @statements.next_key
658
- begin
659
- @connection.prepare nextkey, sql
660
- rescue => e
661
- raise translate_exception_class(e, sql)
681
+ @lock.synchronize do
682
+ sql_key = sql_key(sql)
683
+ unless @statements.key? sql_key
684
+ nextkey = @statements.next_key
685
+ begin
686
+ @connection.prepare nextkey, sql
687
+ rescue => e
688
+ raise translate_exception_class(e, sql)
689
+ end
690
+ # Clear the queue
691
+ @connection.get_last_result
692
+ @statements[sql_key] = nextkey
662
693
  end
663
- # Clear the queue
664
- @connection.get_last_result
665
- @statements[sql_key] = nextkey
694
+ @statements[sql_key]
666
695
  end
667
- @statements[sql_key]
668
696
  end
669
697
 
670
698
  # Connects to a PostgreSQL server and sets up the adapter depending on the
671
699
  # connected server's characteristics.
672
700
  def connect
673
- @connection = PG.connect(@connection_parameters)
701
+ @connection = PGconn.connect(@connection_parameters)
674
702
  configure_connection
675
703
  rescue ::PG::Error => error
676
704
  if error.message.include?("does not exist")
@@ -686,7 +714,7 @@ module ActiveRecord
686
714
  if @config[:encoding]
687
715
  @connection.set_client_encoding(@config[:encoding])
688
716
  end
689
- self.client_min_messages = @config[:min_messages] || 'warning'
717
+ self.client_min_messages = @config[:min_messages] || "warning"
690
718
  self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]
691
719
 
692
720
  # Use standard-conforming strings so we don't have to do the E'...' dance.
@@ -696,27 +724,27 @@ module ActiveRecord
696
724
  # TIMESTAMP WITH ZONE types in UTC.
697
725
  # (SET TIME ZONE does not use an equals sign like other SET variables)
698
726
  if ActiveRecord::Base.default_timezone == :utc
699
- execute("SET time zone 'UTC'", 'SCHEMA')
727
+ execute("SET time zone 'UTC'", "SCHEMA")
700
728
  elsif @local_tz
701
- execute("SET time zone '#{@local_tz}'", 'SCHEMA')
729
+ execute("SET time zone '#{@local_tz}'", "SCHEMA")
702
730
  end
703
731
 
704
732
  # SET statements from :variables config hash
705
733
  # http://www.postgresql.org/docs/current/static/sql-set.html
706
734
  variables = @config[:variables] || {}
707
735
  variables.map do |k, v|
708
- if v == ':default' || v == :default
736
+ if v == ":default" || v == :default
709
737
  # Sets the value to the global or compile default
710
- execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA')
738
+ execute("SET SESSION #{k} TO DEFAULT", "SCHEMA")
711
739
  elsif !v.nil?
712
- execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA')
740
+ execute("SET SESSION #{k} TO #{quote(v)}", "SCHEMA")
713
741
  end
714
742
  end
715
743
  end
716
744
 
717
745
  # Returns the current ID of a table's sequence.
718
- def last_insert_id_result(sequence_name) # :nodoc:
719
- exec_query("SELECT currval('#{sequence_name}')", 'SQL')
746
+ def last_insert_id_result(sequence_name)
747
+ exec_query("SELECT currval('#{sequence_name}')", "SQL")
720
748
  end
721
749
 
722
750
  # Returns the list of a table's column names, data types, and default values.
@@ -737,27 +765,27 @@ module ActiveRecord
737
765
  # Query implementation notes:
738
766
  # - format_type includes the column size constraint, e.g. varchar(50)
739
767
  # - ::regclass is a function that gives the id for a table name
740
- def column_definitions(table_name) # :nodoc:
741
- query(<<-end_sql, 'SCHEMA')
768
+ def column_definitions(table_name)
769
+ query(<<-end_sql, "SCHEMA")
742
770
  SELECT a.attname, format_type(a.atttypid, a.atttypmod),
743
771
  pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
744
- (SELECT c.collname FROM pg_collation c, pg_type t
745
- WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation),
746
- col_description(a.attrelid, a.attnum) AS comment
747
- FROM pg_attribute a LEFT JOIN pg_attrdef d
748
- ON a.attrelid = d.adrelid AND a.attnum = d.adnum
749
- WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
772
+ c.collname, col_description(a.attrelid, a.attnum) AS comment
773
+ FROM pg_attribute a
774
+ LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
775
+ LEFT JOIN pg_type t ON a.atttypid = t.oid
776
+ LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
777
+ WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
750
778
  AND a.attnum > 0 AND NOT a.attisdropped
751
779
  ORDER BY a.attnum
752
780
  end_sql
753
781
  end
754
782
 
755
- def extract_table_ref_from_insert_sql(sql) # :nodoc:
783
+ def extract_table_ref_from_insert_sql(sql)
756
784
  sql[/into\s("[A-Za-z0-9_."\[\]\s]+"|[A-Za-z0-9_."\[\]]+)\s*/im]
757
785
  $1.strip if $1
758
786
  end
759
787
 
760
- def create_table_definition(*args) # :nodoc:
788
+ def create_table_definition(*args)
761
789
  PostgreSQL::TableDefinition.new(*args)
762
790
  end
763
791
 
@@ -788,19 +816,18 @@ module ActiveRecord
788
816
  map[Integer] = PG::TextEncoder::Integer.new
789
817
  map[TrueClass] = PG::TextEncoder::Boolean.new
790
818
  map[FalseClass] = PG::TextEncoder::Boolean.new
791
- map[Float] = PG::TextEncoder::Float.new
792
819
  @connection.type_map_for_queries = map
793
820
  end
794
821
 
795
822
  def add_pg_decoders
796
823
  coders_by_name = {
797
- 'int2' => PG::TextDecoder::Integer,
798
- 'int4' => PG::TextDecoder::Integer,
799
- 'int8' => PG::TextDecoder::Integer,
800
- 'oid' => PG::TextDecoder::Integer,
801
- 'float4' => PG::TextDecoder::Float,
802
- 'float8' => PG::TextDecoder::Float,
803
- 'bool' => PG::TextDecoder::Boolean,
824
+ "int2" => PG::TextDecoder::Integer,
825
+ "int4" => PG::TextDecoder::Integer,
826
+ "int8" => PG::TextDecoder::Integer,
827
+ "oid" => PG::TextDecoder::Integer,
828
+ "float4" => PG::TextDecoder::Float,
829
+ "float8" => PG::TextDecoder::Float,
830
+ "bool" => PG::TextDecoder::Boolean,
804
831
  }
805
832
  known_coder_types = coders_by_name.keys.map { |n| quote(n) }
806
833
  query = <<-SQL % known_coder_types.join(", ")
@@ -810,7 +837,7 @@ module ActiveRecord
810
837
  SQL
811
838
  coders = execute_and_clear(query, "SCHEMA", []) do |result|
812
839
  result
813
- .map { |row| construct_coder(row, coders_by_name[row['typname']]) }
840
+ .map { |row| construct_coder(row, coders_by_name[row["typname"]]) }
814
841
  .compact
815
842
  end
816
843
 
@@ -821,7 +848,7 @@ module ActiveRecord
821
848
 
822
849
  def construct_coder(row, coder_class)
823
850
  return unless coder_class
824
- coder_class.new(oid: row['oid'].to_i, name: row['typname'])
851
+ coder_class.new(oid: row["oid"].to_i, name: row["typname"])
825
852
  end
826
853
 
827
854
  ActiveRecord::Type.add_modifier({ array: true }, OID::Array, adapter: :postgresql)
@@ -838,8 +865,8 @@ module ActiveRecord
838
865
  ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
839
866
  ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
840
867
  ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
841
- ActiveRecord::Type.register(:point, OID::Rails51Point, adapter: :postgresql)
842
- ActiveRecord::Type.register(:legacy_point, OID::Point, adapter: :postgresql)
868
+ ActiveRecord::Type.register(:point, OID::Point, adapter: :postgresql)
869
+ ActiveRecord::Type.register(:legacy_point, OID::LegacyPoint, adapter: :postgresql)
843
870
  ActiveRecord::Type.register(:uuid, OID::Uuid, adapter: :postgresql)
844
871
  ActiveRecord::Type.register(:vector, OID::Vector, adapter: :postgresql)
845
872
  ActiveRecord::Type.register(:xml, OID::Xml, adapter: :postgresql)