activerecord 5.1.7 → 5.2.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +372 -765
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -5
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +4 -2
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +16 -27
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +20 -10
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +4 -5
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +43 -35
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +3 -1
- data/lib/active_record/associations/has_many_through_association.rb +7 -18
- data/lib/active_record/associations/has_one_association.rb +4 -1
- data/lib/active_record/associations/has_one_through_association.rb +8 -7
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/join_dependency.rb +23 -43
- data/lib/active_record/associations/preloader/association.rb +45 -61
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +25 -10
- data/lib/active_record/associations.rb +31 -54
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +21 -9
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attributes.rb +6 -5
- data/lib/active_record/autosave_association.rb +8 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -10
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +11 -7
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +111 -38
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +157 -29
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -32
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +57 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -78
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +81 -96
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +111 -183
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -2
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +246 -110
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +58 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +18 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +80 -90
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +39 -60
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +17 -13
- data/lib/active_record/errors.rb +54 -21
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +67 -60
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +49 -19
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +14 -17
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +43 -0
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +40 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/model_schema.rb +16 -21
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +166 -16
- data/lib/active_record/query_cache.rb +11 -6
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +61 -3
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +46 -36
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +110 -192
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/calculations.rb +30 -8
- data/lib/active_record/relation/delegation.rb +15 -27
- data/lib/active_record/relation/finder_methods.rb +75 -78
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +51 -20
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +53 -78
- data/lib/active_record/relation/query_attribute.rb +26 -2
- data/lib/active_record/relation/query_methods.rb +89 -88
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -1
- data/lib/active_record/relation/where_clause.rb +65 -68
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +95 -208
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +129 -121
- data/lib/active_record/schema.rb +4 -2
- data/lib/active_record/schema_dumper.rb +36 -26
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +21 -7
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +3 -1
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +12 -3
- data/lib/active_record/tasks/database_tasks.rb +26 -15
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +2 -4
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +35 -5
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/version.rb +2 -0
- data/lib/active_record.rb +11 -4
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +3 -1
- metadata +24 -36
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- data/lib/active_record/attribute_set/builder.rb +0 -126
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,15 +1,9 @@
|
|
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
4
|
gem "pg", ">= 0.18", "< 2.0"
|
3
5
|
require "pg"
|
4
6
|
|
5
|
-
# Use async_exec instead of exec_params on pg versions before 1.1
|
6
|
-
class ::PG::Connection
|
7
|
-
unless self.public_method_defined?(:async_exec_params)
|
8
|
-
remove_method :exec_params
|
9
|
-
alias exec_params async_exec
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
7
|
require "active_record/connection_adapters/abstract_adapter"
|
14
8
|
require "active_record/connection_adapters/statement_pool"
|
15
9
|
require "active_record/connection_adapters/postgresql/column"
|
@@ -70,11 +64,11 @@ module ActiveRecord
|
|
70
64
|
# defaults to true.
|
71
65
|
#
|
72
66
|
# Any further options are used as connection parameters to libpq. See
|
73
|
-
#
|
67
|
+
# https://www.postgresql.org/docs/current/static/libpq-connect.html for the
|
74
68
|
# list of parameters.
|
75
69
|
#
|
76
70
|
# In addition, default connection parameters of libpq can be set per environment variables.
|
77
|
-
# See
|
71
|
+
# See https://www.postgresql.org/docs/current/static/libpq-envars.html .
|
78
72
|
class PostgreSQLAdapter < AbstractAdapter
|
79
73
|
ADAPTER_NAME = "PostgreSQL".freeze
|
80
74
|
|
@@ -82,7 +76,7 @@ module ActiveRecord
|
|
82
76
|
primary_key: "bigserial primary key",
|
83
77
|
string: { name: "character varying" },
|
84
78
|
text: { name: "text" },
|
85
|
-
integer: { name: "integer" },
|
79
|
+
integer: { name: "integer", limit: 4 },
|
86
80
|
float: { name: "float" },
|
87
81
|
decimal: { name: "decimal" },
|
88
82
|
datetime: { name: "timestamp" },
|
@@ -127,19 +121,8 @@ module ActiveRecord
|
|
127
121
|
include PostgreSQL::ReferentialIntegrity
|
128
122
|
include PostgreSQL::SchemaStatements
|
129
123
|
include PostgreSQL::DatabaseStatements
|
130
|
-
include PostgreSQL::ColumnDumper
|
131
|
-
|
132
|
-
def schema_creation # :nodoc:
|
133
|
-
PostgreSQL::SchemaCreation.new self
|
134
|
-
end
|
135
|
-
|
136
|
-
def arel_visitor # :nodoc:
|
137
|
-
Arel::Visitors::PostgreSQL.new(self)
|
138
|
-
end
|
139
124
|
|
140
|
-
|
141
|
-
# caching.
|
142
|
-
def supports_statement_cache?
|
125
|
+
def supports_bulk_alter?
|
143
126
|
true
|
144
127
|
end
|
145
128
|
|
@@ -163,6 +146,10 @@ module ActiveRecord
|
|
163
146
|
true
|
164
147
|
end
|
165
148
|
|
149
|
+
def supports_validate_constraints?
|
150
|
+
true
|
151
|
+
end
|
152
|
+
|
166
153
|
def supports_views?
|
167
154
|
true
|
168
155
|
end
|
@@ -187,7 +174,7 @@ module ActiveRecord
|
|
187
174
|
{ concurrently: "CONCURRENTLY" }
|
188
175
|
end
|
189
176
|
|
190
|
-
class StatementPool < ConnectionAdapters::StatementPool
|
177
|
+
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
191
178
|
def initialize(connection, max)
|
192
179
|
super(max)
|
193
180
|
@connection = connection
|
@@ -203,7 +190,6 @@ module ActiveRecord
|
|
203
190
|
end
|
204
191
|
|
205
192
|
private
|
206
|
-
|
207
193
|
def dealloc(key)
|
208
194
|
@connection.query "DEALLOCATE #{key}" if connection_active?
|
209
195
|
rescue PG::Error
|
@@ -238,7 +224,7 @@ module ActiveRecord
|
|
238
224
|
add_pg_decoders
|
239
225
|
|
240
226
|
@type_map = Type::HashLookupTypeMap.new
|
241
|
-
initialize_type_map
|
227
|
+
initialize_type_map
|
242
228
|
@local_tz = execute("SHOW TIME ZONE", "SCHEMA").first["TimeZone"]
|
243
229
|
@use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
|
244
230
|
end
|
@@ -294,6 +280,11 @@ module ActiveRecord
|
|
294
280
|
end
|
295
281
|
end
|
296
282
|
|
283
|
+
def discard! # :nodoc:
|
284
|
+
@connection.socket_io.reopen(IO::NULL) rescue nil
|
285
|
+
@connection = nil
|
286
|
+
end
|
287
|
+
|
297
288
|
def native_database_types #:nodoc:
|
298
289
|
NATIVE_DATABASE_TYPES
|
299
290
|
end
|
@@ -318,8 +309,8 @@ module ActiveRecord
|
|
318
309
|
true
|
319
310
|
end
|
320
311
|
|
321
|
-
# Range datatypes weren't introduced until PostgreSQL 9.2
|
322
312
|
def supports_ranges?
|
313
|
+
# Range datatypes weren't introduced until PostgreSQL 9.2
|
323
314
|
postgresql_version >= 90200
|
324
315
|
end
|
325
316
|
|
@@ -327,20 +318,24 @@ module ActiveRecord
|
|
327
318
|
postgresql_version >= 90300
|
328
319
|
end
|
329
320
|
|
321
|
+
def supports_foreign_tables?
|
322
|
+
postgresql_version >= 90300
|
323
|
+
end
|
324
|
+
|
330
325
|
def supports_pgcrypto_uuid?
|
331
326
|
postgresql_version >= 90400
|
332
327
|
end
|
333
328
|
|
334
329
|
def get_advisory_lock(lock_id) # :nodoc:
|
335
330
|
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
336
|
-
raise(ArgumentError, "
|
331
|
+
raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
|
337
332
|
end
|
338
333
|
query_value("SELECT pg_try_advisory_lock(#{lock_id})")
|
339
334
|
end
|
340
335
|
|
341
336
|
def release_advisory_lock(lock_id) # :nodoc:
|
342
337
|
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
343
|
-
raise(ArgumentError, "
|
338
|
+
raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
|
344
339
|
end
|
345
340
|
query_value("SELECT pg_advisory_unlock(#{lock_id})")
|
346
341
|
end
|
@@ -358,18 +353,12 @@ module ActiveRecord
|
|
358
353
|
end
|
359
354
|
|
360
355
|
def extension_enabled?(name)
|
361
|
-
|
362
|
-
|
363
|
-
res.cast_values.first
|
364
|
-
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
|
365
358
|
end
|
366
359
|
|
367
360
|
def extensions
|
368
|
-
|
369
|
-
exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
|
370
|
-
else
|
371
|
-
super
|
372
|
-
end
|
361
|
+
exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
|
373
362
|
end
|
374
363
|
|
375
364
|
# Returns the configured supported identifier length supported by PostgreSQL
|
@@ -389,10 +378,6 @@ module ActiveRecord
|
|
389
378
|
@use_insert_returning
|
390
379
|
end
|
391
380
|
|
392
|
-
def update_table_definition(table_name, base) #:nodoc:
|
393
|
-
PostgreSQL::Table.new(table_name, base)
|
394
|
-
end
|
395
|
-
|
396
381
|
def column_name_for_operation(operation, node) # :nodoc:
|
397
382
|
OPERATION_ALIASES.fetch(operation) { operation.downcase }
|
398
383
|
end
|
@@ -413,8 +398,7 @@ module ActiveRecord
|
|
413
398
|
end
|
414
399
|
|
415
400
|
private
|
416
|
-
|
417
|
-
# See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
401
|
+
# See https://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
418
402
|
VALUE_LIMIT_VIOLATION = "22001"
|
419
403
|
NUMERIC_VALUE_OUT_OF_RANGE = "22003"
|
420
404
|
NOT_NULL_VIOLATION = "23502"
|
@@ -422,6 +406,8 @@ module ActiveRecord
|
|
422
406
|
UNIQUE_VIOLATION = "23505"
|
423
407
|
SERIALIZATION_FAILURE = "40001"
|
424
408
|
DEADLOCK_DETECTED = "40P01"
|
409
|
+
LOCK_NOT_AVAILABLE = "55P03"
|
410
|
+
QUERY_CANCELED = "57014"
|
425
411
|
|
426
412
|
def translate_exception(exception, message)
|
427
413
|
return exception unless exception.respond_to?(:result)
|
@@ -441,6 +427,10 @@ module ActiveRecord
|
|
441
427
|
SerializationFailure.new(message)
|
442
428
|
when DEADLOCK_DETECTED
|
443
429
|
Deadlocked.new(message)
|
430
|
+
when LOCK_NOT_AVAILABLE
|
431
|
+
LockWaitTimeout.new(message)
|
432
|
+
when QUERY_CANCELED
|
433
|
+
QueryCanceled.new(message)
|
444
434
|
else
|
445
435
|
super
|
446
436
|
end
|
@@ -448,7 +438,7 @@ module ActiveRecord
|
|
448
438
|
|
449
439
|
def get_oid_type(oid, fmod, column_name, sql_type = "".freeze)
|
450
440
|
if !type_map.key?(oid)
|
451
|
-
load_additional_types(
|
441
|
+
load_additional_types([oid])
|
452
442
|
end
|
453
443
|
|
454
444
|
type_map.fetch(oid, fmod, sql_type) {
|
@@ -459,10 +449,10 @@ module ActiveRecord
|
|
459
449
|
}
|
460
450
|
end
|
461
451
|
|
462
|
-
def initialize_type_map(m)
|
463
|
-
|
464
|
-
|
465
|
-
|
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)
|
466
456
|
m.register_type "oid", OID::Oid.new
|
467
457
|
m.register_type "float4", Type::Float.new
|
468
458
|
m.alias_type "float8", "float4"
|
@@ -475,13 +465,13 @@ module ActiveRecord
|
|
475
465
|
register_class_with_limit m, "bit", OID::Bit
|
476
466
|
register_class_with_limit m, "varbit", OID::BitVarying
|
477
467
|
m.alias_type "timestamptz", "timestamp"
|
478
|
-
m.register_type "date",
|
468
|
+
m.register_type "date", OID::Date.new
|
479
469
|
|
480
470
|
m.register_type "money", OID::Money.new
|
481
471
|
m.register_type "bytea", OID::Bytea.new
|
482
472
|
m.register_type "point", OID::Point.new
|
483
473
|
m.register_type "hstore", OID::Hstore.new
|
484
|
-
m.register_type "json",
|
474
|
+
m.register_type "json", Type::Json.new
|
485
475
|
m.register_type "jsonb", OID::Jsonb.new
|
486
476
|
m.register_type "cidr", OID::Cidr.new
|
487
477
|
m.register_type "inet", OID::Inet.new
|
@@ -526,18 +516,7 @@ module ActiveRecord
|
|
526
516
|
end
|
527
517
|
end
|
528
518
|
|
529
|
-
load_additional_types
|
530
|
-
end
|
531
|
-
|
532
|
-
def extract_limit(sql_type)
|
533
|
-
case sql_type
|
534
|
-
when /^bigint/i, /^int8/i
|
535
|
-
8
|
536
|
-
when /^smallint/i
|
537
|
-
2
|
538
|
-
else
|
539
|
-
super
|
540
|
-
end
|
519
|
+
load_additional_types
|
541
520
|
end
|
542
521
|
|
543
522
|
# Extracts the value from a PostgreSQL column default definition.
|
@@ -575,7 +554,7 @@ module ActiveRecord
|
|
575
554
|
!default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
|
576
555
|
end
|
577
556
|
|
578
|
-
def load_additional_types(
|
557
|
+
def load_additional_types(oids = nil)
|
579
558
|
initializer = OID::TypeMapInitializer.new(type_map)
|
580
559
|
|
581
560
|
if supports_ranges?
|
@@ -594,7 +573,7 @@ module ActiveRecord
|
|
594
573
|
if oids
|
595
574
|
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
596
575
|
else
|
597
|
-
query += initializer.query_conditions_for_initial_load
|
576
|
+
query += initializer.query_conditions_for_initial_load
|
598
577
|
end
|
599
578
|
|
600
579
|
execute_and_clear(query, "SCHEMA", []) do |records|
|
@@ -621,7 +600,7 @@ module ActiveRecord
|
|
621
600
|
type_casted_binds = type_casted_binds(binds)
|
622
601
|
log(sql, name, binds, type_casted_binds) do
|
623
602
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
624
|
-
@connection.
|
603
|
+
@connection.async_exec(sql, type_casted_binds)
|
625
604
|
end
|
626
605
|
end
|
627
606
|
end
|
@@ -659,7 +638,7 @@ module ActiveRecord
|
|
659
638
|
# ActiveRecord::PreparedStatementCacheExpired
|
660
639
|
#
|
661
640
|
# Check here for more details:
|
662
|
-
#
|
641
|
+
# https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
|
663
642
|
CACHED_PLAN_HEURISTIC = "cached plan must not change result type".freeze
|
664
643
|
def is_cached_plan_failure?(e)
|
665
644
|
pgerror = e.cause
|
@@ -724,18 +703,20 @@ module ActiveRecord
|
|
724
703
|
# Use standard-conforming strings so we don't have to do the E'...' dance.
|
725
704
|
set_standard_conforming_strings
|
726
705
|
|
706
|
+
variables = @config.fetch(:variables, {}).stringify_keys
|
707
|
+
|
727
708
|
# If using Active Record's time zone support configure the connection to return
|
728
709
|
# TIMESTAMP WITH ZONE types in UTC.
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
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
|
734
716
|
end
|
735
717
|
|
736
718
|
# SET statements from :variables config hash
|
737
|
-
#
|
738
|
-
variables = @config[:variables] || {}
|
719
|
+
# https://www.postgresql.org/docs/current/static/sql-set.html
|
739
720
|
variables.map do |k, v|
|
740
721
|
if v == ":default" || v == :default
|
741
722
|
# Sets the value to the global or compile default
|
@@ -746,11 +727,6 @@ module ActiveRecord
|
|
746
727
|
end
|
747
728
|
end
|
748
729
|
|
749
|
-
# Returns the current ID of a table's sequence.
|
750
|
-
def last_insert_id_result(sequence_name)
|
751
|
-
exec_query("SELECT currval('#{sequence_name}')", "SQL")
|
752
|
-
end
|
753
|
-
|
754
730
|
# Returns the list of a table's column names, data types, and default values.
|
755
731
|
#
|
756
732
|
# The underlying query is roughly:
|
@@ -789,8 +765,8 @@ module ActiveRecord
|
|
789
765
|
$1.strip if $1
|
790
766
|
end
|
791
767
|
|
792
|
-
def
|
793
|
-
PostgreSQL
|
768
|
+
def arel_visitor
|
769
|
+
Arel::Visitors::PostgreSQL.new(self)
|
794
770
|
end
|
795
771
|
|
796
772
|
def can_perform_case_insensitive_comparison_for?(column)
|
@@ -861,12 +837,12 @@ module ActiveRecord
|
|
861
837
|
ActiveRecord::Type.register(:bit_varying, OID::BitVarying, adapter: :postgresql)
|
862
838
|
ActiveRecord::Type.register(:binary, OID::Bytea, adapter: :postgresql)
|
863
839
|
ActiveRecord::Type.register(:cidr, OID::Cidr, adapter: :postgresql)
|
840
|
+
ActiveRecord::Type.register(:date, OID::Date, adapter: :postgresql)
|
864
841
|
ActiveRecord::Type.register(:datetime, OID::DateTime, adapter: :postgresql)
|
865
842
|
ActiveRecord::Type.register(:decimal, OID::Decimal, adapter: :postgresql)
|
866
843
|
ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
|
867
844
|
ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
|
868
845
|
ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
|
869
|
-
ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
|
870
846
|
ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
|
871
847
|
ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
|
872
848
|
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"] =
|
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 =
|
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
|
module ConnectionAdapters
|
3
5
|
module SQLite3
|
@@ -15,7 +17,6 @@ module ActiveRecord
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def quoted_time(value)
|
18
|
-
value = value.change(year: 2000, month: 1, day: 1)
|
19
20
|
quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "2000-01-01 ")
|
20
21
|
end
|
21
22
|
|
@@ -23,6 +24,22 @@ module ActiveRecord
|
|
23
24
|
"x'#{value.hex}'"
|
24
25
|
end
|
25
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
|
+
|
26
43
|
private
|
27
44
|
|
28
45
|
def _type_cast(value)
|
@@ -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
|
-
|
24
|
-
|
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
|
-
|
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
|