activerecord 5.1.5 → 5.2.8.1
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 +655 -608
- 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 +7 -5
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +41 -37
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +28 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +14 -5
- data/lib/active_record/associations/builder/collection_association.rb +3 -3
- 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 +59 -47
- data/lib/active_record/associations/collection_proxy.rb +20 -49
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +12 -1
- data/lib/active_record/associations/has_many_through_association.rb +36 -30
- data/lib/active_record/associations/has_one_association.rb +12 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
- data/lib/active_record/associations/join_dependency.rb +48 -93
- 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 +18 -38
- data/lib/active_record/associations/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +26 -11
- data/lib/active_record/associations.rb +40 -63
- 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 +32 -216
- 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 +9 -3
- 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 +7 -6
- data/lib/active_record/autosave_association.rb +35 -19
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +12 -6
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +15 -1
- data/lib/active_record/collection_cache_key.rb +12 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +142 -42
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -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 +64 -6
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +110 -173
- 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 +13 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -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 +13 -1
- 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 +3 -1
- 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 +5 -3
- 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 +8 -2
- 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 +50 -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 +234 -112
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +66 -74
- 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 +24 -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 +75 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +82 -95
- 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 +51 -61
- data/lib/active_record/counter_cache.rb +20 -15
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +18 -13
- data/lib/active_record/errors.rb +60 -15
- 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 +5 -3
- 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 +30 -42
- 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 +47 -9
- 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 +19 -24
- 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 +198 -49
- data/lib/active_record/query_cache.rb +12 -14
- data/lib/active_record/querying.rb +4 -2
- data/lib/active_record/railtie.rb +80 -6
- 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 +108 -194
- 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 +46 -20
- data/lib/active_record/relation/delegation.rb +45 -27
- data/lib/active_record/relation/finder_methods.rb +77 -78
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +53 -23
- 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 +60 -79
- data/lib/active_record/relation/query_attribute.rb +28 -2
- data/lib/active_record/relation/query_methods.rb +129 -100
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +4 -2
- 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 +120 -214
- 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 +8 -9
- data/lib/active_record/scoping/named.rb +23 -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 +23 -13
- 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 +13 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +33 -28
- 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 +6 -0
- 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 +36 -6
- 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 +26 -40
- 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 -114
- data/lib/active_record/attribute_set/builder.rb +0 -124
- 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,7 +1,17 @@
|
|
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
|
|
7
|
+
# Use async_exec instead of exec_params on pg versions before 1.1
|
8
|
+
class ::PG::Connection
|
9
|
+
unless self.public_method_defined?(:async_exec_params)
|
10
|
+
remove_method :exec_params
|
11
|
+
alias exec_params async_exec
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
require "active_record/connection_adapters/abstract_adapter"
|
6
16
|
require "active_record/connection_adapters/statement_pool"
|
7
17
|
require "active_record/connection_adapters/postgresql/column"
|
@@ -62,11 +72,11 @@ module ActiveRecord
|
|
62
72
|
# defaults to true.
|
63
73
|
#
|
64
74
|
# Any further options are used as connection parameters to libpq. See
|
65
|
-
#
|
75
|
+
# https://www.postgresql.org/docs/current/static/libpq-connect.html for the
|
66
76
|
# list of parameters.
|
67
77
|
#
|
68
78
|
# In addition, default connection parameters of libpq can be set per environment variables.
|
69
|
-
# See
|
79
|
+
# See https://www.postgresql.org/docs/current/static/libpq-envars.html .
|
70
80
|
class PostgreSQLAdapter < AbstractAdapter
|
71
81
|
ADAPTER_NAME = "PostgreSQL".freeze
|
72
82
|
|
@@ -74,7 +84,7 @@ module ActiveRecord
|
|
74
84
|
primary_key: "bigserial primary key",
|
75
85
|
string: { name: "character varying" },
|
76
86
|
text: { name: "text" },
|
77
|
-
integer: { name: "integer" },
|
87
|
+
integer: { name: "integer", limit: 4 },
|
78
88
|
float: { name: "float" },
|
79
89
|
decimal: { name: "decimal" },
|
80
90
|
datetime: { name: "timestamp" },
|
@@ -119,19 +129,8 @@ module ActiveRecord
|
|
119
129
|
include PostgreSQL::ReferentialIntegrity
|
120
130
|
include PostgreSQL::SchemaStatements
|
121
131
|
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
132
|
|
132
|
-
|
133
|
-
# caching.
|
134
|
-
def supports_statement_cache?
|
133
|
+
def supports_bulk_alter?
|
135
134
|
true
|
136
135
|
end
|
137
136
|
|
@@ -155,6 +154,10 @@ module ActiveRecord
|
|
155
154
|
true
|
156
155
|
end
|
157
156
|
|
157
|
+
def supports_validate_constraints?
|
158
|
+
true
|
159
|
+
end
|
160
|
+
|
158
161
|
def supports_views?
|
159
162
|
true
|
160
163
|
end
|
@@ -179,7 +182,7 @@ module ActiveRecord
|
|
179
182
|
{ concurrently: "CONCURRENTLY" }
|
180
183
|
end
|
181
184
|
|
182
|
-
class StatementPool < ConnectionAdapters::StatementPool
|
185
|
+
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
183
186
|
def initialize(connection, max)
|
184
187
|
super(max)
|
185
188
|
@connection = connection
|
@@ -195,7 +198,6 @@ module ActiveRecord
|
|
195
198
|
end
|
196
199
|
|
197
200
|
private
|
198
|
-
|
199
201
|
def dealloc(key)
|
200
202
|
@connection.query "DEALLOCATE #{key}" if connection_active?
|
201
203
|
rescue PG::Error
|
@@ -230,7 +232,7 @@ module ActiveRecord
|
|
230
232
|
add_pg_decoders
|
231
233
|
|
232
234
|
@type_map = Type::HashLookupTypeMap.new
|
233
|
-
initialize_type_map
|
235
|
+
initialize_type_map
|
234
236
|
@local_tz = execute("SHOW TIME ZONE", "SCHEMA").first["TimeZone"]
|
235
237
|
@use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
|
236
238
|
end
|
@@ -286,6 +288,11 @@ module ActiveRecord
|
|
286
288
|
end
|
287
289
|
end
|
288
290
|
|
291
|
+
def discard! # :nodoc:
|
292
|
+
@connection.socket_io.reopen(IO::NULL) rescue nil
|
293
|
+
@connection = nil
|
294
|
+
end
|
295
|
+
|
289
296
|
def native_database_types #:nodoc:
|
290
297
|
NATIVE_DATABASE_TYPES
|
291
298
|
end
|
@@ -310,8 +317,8 @@ module ActiveRecord
|
|
310
317
|
true
|
311
318
|
end
|
312
319
|
|
313
|
-
# Range datatypes weren't introduced until PostgreSQL 9.2
|
314
320
|
def supports_ranges?
|
321
|
+
# Range datatypes weren't introduced until PostgreSQL 9.2
|
315
322
|
postgresql_version >= 90200
|
316
323
|
end
|
317
324
|
|
@@ -319,20 +326,24 @@ module ActiveRecord
|
|
319
326
|
postgresql_version >= 90300
|
320
327
|
end
|
321
328
|
|
329
|
+
def supports_foreign_tables?
|
330
|
+
postgresql_version >= 90300
|
331
|
+
end
|
332
|
+
|
322
333
|
def supports_pgcrypto_uuid?
|
323
334
|
postgresql_version >= 90400
|
324
335
|
end
|
325
336
|
|
326
337
|
def get_advisory_lock(lock_id) # :nodoc:
|
327
338
|
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
328
|
-
raise(ArgumentError, "
|
339
|
+
raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
|
329
340
|
end
|
330
341
|
query_value("SELECT pg_try_advisory_lock(#{lock_id})")
|
331
342
|
end
|
332
343
|
|
333
344
|
def release_advisory_lock(lock_id) # :nodoc:
|
334
345
|
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
335
|
-
raise(ArgumentError, "
|
346
|
+
raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
|
336
347
|
end
|
337
348
|
query_value("SELECT pg_advisory_unlock(#{lock_id})")
|
338
349
|
end
|
@@ -350,18 +361,12 @@ module ActiveRecord
|
|
350
361
|
end
|
351
362
|
|
352
363
|
def extension_enabled?(name)
|
353
|
-
|
354
|
-
|
355
|
-
res.cast_values.first
|
356
|
-
end
|
364
|
+
res = exec_query("SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled", "SCHEMA")
|
365
|
+
res.cast_values.first
|
357
366
|
end
|
358
367
|
|
359
368
|
def extensions
|
360
|
-
|
361
|
-
exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
|
362
|
-
else
|
363
|
-
super
|
364
|
-
end
|
369
|
+
exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
|
365
370
|
end
|
366
371
|
|
367
372
|
# Returns the configured supported identifier length supported by PostgreSQL
|
@@ -381,10 +386,6 @@ module ActiveRecord
|
|
381
386
|
@use_insert_returning
|
382
387
|
end
|
383
388
|
|
384
|
-
def update_table_definition(table_name, base) #:nodoc:
|
385
|
-
PostgreSQL::Table.new(table_name, base)
|
386
|
-
end
|
387
|
-
|
388
389
|
def column_name_for_operation(operation, node) # :nodoc:
|
389
390
|
OPERATION_ALIASES.fetch(operation) { operation.downcase }
|
390
391
|
end
|
@@ -405,8 +406,7 @@ module ActiveRecord
|
|
405
406
|
end
|
406
407
|
|
407
408
|
private
|
408
|
-
|
409
|
-
# See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
409
|
+
# See https://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
410
410
|
VALUE_LIMIT_VIOLATION = "22001"
|
411
411
|
NUMERIC_VALUE_OUT_OF_RANGE = "22003"
|
412
412
|
NOT_NULL_VIOLATION = "23502"
|
@@ -414,6 +414,8 @@ module ActiveRecord
|
|
414
414
|
UNIQUE_VIOLATION = "23505"
|
415
415
|
SERIALIZATION_FAILURE = "40001"
|
416
416
|
DEADLOCK_DETECTED = "40P01"
|
417
|
+
LOCK_NOT_AVAILABLE = "55P03"
|
418
|
+
QUERY_CANCELED = "57014"
|
417
419
|
|
418
420
|
def translate_exception(exception, message)
|
419
421
|
return exception unless exception.respond_to?(:result)
|
@@ -433,6 +435,10 @@ module ActiveRecord
|
|
433
435
|
SerializationFailure.new(message)
|
434
436
|
when DEADLOCK_DETECTED
|
435
437
|
Deadlocked.new(message)
|
438
|
+
when LOCK_NOT_AVAILABLE
|
439
|
+
LockWaitTimeout.new(message)
|
440
|
+
when QUERY_CANCELED
|
441
|
+
QueryCanceled.new(message)
|
436
442
|
else
|
437
443
|
super
|
438
444
|
end
|
@@ -440,7 +446,7 @@ module ActiveRecord
|
|
440
446
|
|
441
447
|
def get_oid_type(oid, fmod, column_name, sql_type = "".freeze)
|
442
448
|
if !type_map.key?(oid)
|
443
|
-
load_additional_types(
|
449
|
+
load_additional_types([oid])
|
444
450
|
end
|
445
451
|
|
446
452
|
type_map.fetch(oid, fmod, sql_type) {
|
@@ -451,10 +457,10 @@ module ActiveRecord
|
|
451
457
|
}
|
452
458
|
end
|
453
459
|
|
454
|
-
def initialize_type_map(m)
|
455
|
-
|
456
|
-
|
457
|
-
|
460
|
+
def initialize_type_map(m = type_map)
|
461
|
+
m.register_type "int2", Type::Integer.new(limit: 2)
|
462
|
+
m.register_type "int4", Type::Integer.new(limit: 4)
|
463
|
+
m.register_type "int8", Type::Integer.new(limit: 8)
|
458
464
|
m.register_type "oid", OID::Oid.new
|
459
465
|
m.register_type "float4", Type::Float.new
|
460
466
|
m.alias_type "float8", "float4"
|
@@ -467,13 +473,13 @@ module ActiveRecord
|
|
467
473
|
register_class_with_limit m, "bit", OID::Bit
|
468
474
|
register_class_with_limit m, "varbit", OID::BitVarying
|
469
475
|
m.alias_type "timestamptz", "timestamp"
|
470
|
-
m.register_type "date",
|
476
|
+
m.register_type "date", OID::Date.new
|
471
477
|
|
472
478
|
m.register_type "money", OID::Money.new
|
473
479
|
m.register_type "bytea", OID::Bytea.new
|
474
480
|
m.register_type "point", OID::Point.new
|
475
481
|
m.register_type "hstore", OID::Hstore.new
|
476
|
-
m.register_type "json",
|
482
|
+
m.register_type "json", Type::Json.new
|
477
483
|
m.register_type "jsonb", OID::Jsonb.new
|
478
484
|
m.register_type "cidr", OID::Cidr.new
|
479
485
|
m.register_type "inet", OID::Inet.new
|
@@ -518,18 +524,7 @@ module ActiveRecord
|
|
518
524
|
end
|
519
525
|
end
|
520
526
|
|
521
|
-
load_additional_types
|
522
|
-
end
|
523
|
-
|
524
|
-
def extract_limit(sql_type)
|
525
|
-
case sql_type
|
526
|
-
when /^bigint/i, /^int8/i
|
527
|
-
8
|
528
|
-
when /^smallint/i
|
529
|
-
2
|
530
|
-
else
|
531
|
-
super
|
532
|
-
end
|
527
|
+
load_additional_types
|
533
528
|
end
|
534
529
|
|
535
530
|
# Extracts the value from a PostgreSQL column default definition.
|
@@ -567,7 +562,7 @@ module ActiveRecord
|
|
567
562
|
!default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
|
568
563
|
end
|
569
564
|
|
570
|
-
def load_additional_types(
|
565
|
+
def load_additional_types(oids = nil)
|
571
566
|
initializer = OID::TypeMapInitializer.new(type_map)
|
572
567
|
|
573
568
|
if supports_ranges?
|
@@ -586,7 +581,7 @@ module ActiveRecord
|
|
586
581
|
if oids
|
587
582
|
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
588
583
|
else
|
589
|
-
query += initializer.query_conditions_for_initial_load
|
584
|
+
query += initializer.query_conditions_for_initial_load
|
590
585
|
end
|
591
586
|
|
592
587
|
execute_and_clear(query, "SCHEMA", []) do |records|
|
@@ -613,7 +608,7 @@ module ActiveRecord
|
|
613
608
|
type_casted_binds = type_casted_binds(binds)
|
614
609
|
log(sql, name, binds, type_casted_binds) do
|
615
610
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
616
|
-
@connection.
|
611
|
+
@connection.exec_params(sql, type_casted_binds)
|
617
612
|
end
|
618
613
|
end
|
619
614
|
end
|
@@ -651,7 +646,7 @@ module ActiveRecord
|
|
651
646
|
# ActiveRecord::PreparedStatementCacheExpired
|
652
647
|
#
|
653
648
|
# Check here for more details:
|
654
|
-
#
|
649
|
+
# https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
|
655
650
|
CACHED_PLAN_HEURISTIC = "cached plan must not change result type".freeze
|
656
651
|
def is_cached_plan_failure?(e)
|
657
652
|
pgerror = e.cause
|
@@ -716,18 +711,20 @@ module ActiveRecord
|
|
716
711
|
# Use standard-conforming strings so we don't have to do the E'...' dance.
|
717
712
|
set_standard_conforming_strings
|
718
713
|
|
714
|
+
variables = @config.fetch(:variables, {}).stringify_keys
|
715
|
+
|
719
716
|
# If using Active Record's time zone support configure the connection to return
|
720
717
|
# TIMESTAMP WITH ZONE types in UTC.
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
718
|
+
unless variables["timezone"]
|
719
|
+
if ActiveRecord::Base.default_timezone == :utc
|
720
|
+
variables["timezone"] = "UTC"
|
721
|
+
elsif @local_tz
|
722
|
+
variables["timezone"] = @local_tz
|
723
|
+
end
|
726
724
|
end
|
727
725
|
|
728
726
|
# SET statements from :variables config hash
|
729
|
-
#
|
730
|
-
variables = @config[:variables] || {}
|
727
|
+
# https://www.postgresql.org/docs/current/static/sql-set.html
|
731
728
|
variables.map do |k, v|
|
732
729
|
if v == ":default" || v == :default
|
733
730
|
# Sets the value to the global or compile default
|
@@ -738,11 +735,6 @@ module ActiveRecord
|
|
738
735
|
end
|
739
736
|
end
|
740
737
|
|
741
|
-
# Returns the current ID of a table's sequence.
|
742
|
-
def last_insert_id_result(sequence_name)
|
743
|
-
exec_query("SELECT currval('#{sequence_name}')", "SQL")
|
744
|
-
end
|
745
|
-
|
746
738
|
# Returns the list of a table's column names, data types, and default values.
|
747
739
|
#
|
748
740
|
# The underlying query is roughly:
|
@@ -781,8 +773,8 @@ module ActiveRecord
|
|
781
773
|
$1.strip if $1
|
782
774
|
end
|
783
775
|
|
784
|
-
def
|
785
|
-
PostgreSQL
|
776
|
+
def arel_visitor
|
777
|
+
Arel::Visitors::PostgreSQL.new(self)
|
786
778
|
end
|
787
779
|
|
788
780
|
def can_perform_case_insensitive_comparison_for?(column)
|
@@ -853,12 +845,12 @@ module ActiveRecord
|
|
853
845
|
ActiveRecord::Type.register(:bit_varying, OID::BitVarying, adapter: :postgresql)
|
854
846
|
ActiveRecord::Type.register(:binary, OID::Bytea, adapter: :postgresql)
|
855
847
|
ActiveRecord::Type.register(:cidr, OID::Cidr, adapter: :postgresql)
|
848
|
+
ActiveRecord::Type.register(:date, OID::Date, adapter: :postgresql)
|
856
849
|
ActiveRecord::Type.register(:datetime, OID::DateTime, adapter: :postgresql)
|
857
850
|
ActiveRecord::Type.register(:decimal, OID::Decimal, adapter: :postgresql)
|
858
851
|
ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
|
859
852
|
ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
|
860
853
|
ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
|
861
|
-
ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
|
862
854
|
ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
|
863
855
|
ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
|
864
856
|
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
|
@@ -10,18 +12,39 @@ module ActiveRecord
|
|
10
12
|
quote_column_name(attr)
|
11
13
|
end
|
12
14
|
|
15
|
+
def quote_table_name(name)
|
16
|
+
@quoted_table_names[name] ||= super.gsub(".", "\".\"").freeze
|
17
|
+
end
|
18
|
+
|
13
19
|
def quote_column_name(name)
|
14
20
|
@quoted_column_names[name] ||= %Q("#{super.gsub('"', '""')}").freeze
|
15
21
|
end
|
16
22
|
|
17
23
|
def quoted_time(value)
|
18
|
-
|
24
|
+
value = value.change(year: 2000, month: 1, day: 1)
|
25
|
+
quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "2000-01-01 ")
|
19
26
|
end
|
20
27
|
|
21
28
|
def quoted_binary(value)
|
22
29
|
"x'#{value.hex}'"
|
23
30
|
end
|
24
31
|
|
32
|
+
def quoted_true
|
33
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? "1".freeze : "'t'".freeze
|
34
|
+
end
|
35
|
+
|
36
|
+
def unquoted_true
|
37
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? 1 : "t".freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
def quoted_false
|
41
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? "0".freeze : "'f'".freeze
|
42
|
+
end
|
43
|
+
|
44
|
+
def unquoted_false
|
45
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? 0 : "f".freeze
|
46
|
+
end
|
47
|
+
|
25
48
|
private
|
26
49
|
|
27
50
|
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,87 @@
|
|
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
|
+
# Indexes SQLite creates implicitly for internal use start with "sqlite_".
|
11
|
+
# See https://www.sqlite.org/fileformat2.html#intschema
|
12
|
+
next if row["name"].starts_with?("sqlite_")
|
13
|
+
|
14
|
+
index_sql = query_value(<<-SQL, "SCHEMA")
|
15
|
+
SELECT sql
|
16
|
+
FROM sqlite_master
|
17
|
+
WHERE name = #{quote(row['name'])} AND type = 'index'
|
18
|
+
UNION ALL
|
19
|
+
SELECT sql
|
20
|
+
FROM sqlite_temp_master
|
21
|
+
WHERE name = #{quote(row['name'])} AND type = 'index'
|
22
|
+
SQL
|
23
|
+
|
24
|
+
/\sWHERE\s+(?<where>.+)$/i =~ index_sql
|
25
|
+
|
26
|
+
columns = exec_query("PRAGMA index_info(#{quote(row['name'])})", "SCHEMA").map do |col|
|
27
|
+
col["name"]
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add info on sort order for columns (only desc order is explicitly specified, asc is
|
31
|
+
# the default)
|
32
|
+
orders = {}
|
33
|
+
if index_sql # index_sql can be null in case of primary key indexes
|
34
|
+
index_sql.scan(/"(\w+)" DESC/).flatten.each { |order_column|
|
35
|
+
orders[order_column] = :desc
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
IndexDefinition.new(
|
40
|
+
table_name,
|
41
|
+
row["name"],
|
42
|
+
row["unique"] != 0,
|
43
|
+
columns,
|
44
|
+
where: where,
|
45
|
+
orders: orders
|
46
|
+
)
|
47
|
+
end.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_schema_dumper(options)
|
51
|
+
SQLite3::SchemaDumper.create(self, options)
|
52
|
+
end
|
53
|
+
|
5
54
|
private
|
55
|
+
def schema_creation
|
56
|
+
SQLite3::SchemaCreation.new(self)
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_table_definition(*args)
|
60
|
+
SQLite3::TableDefinition.new(*args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def new_column_from_field(table_name, field)
|
64
|
+
default = \
|
65
|
+
case field["dflt_value"]
|
66
|
+
when /^null$/i
|
67
|
+
nil
|
68
|
+
when /^'(.*)'$/m
|
69
|
+
$1.gsub("''", "'")
|
70
|
+
when /^"(.*)"$/m
|
71
|
+
$1.gsub('""', '"')
|
72
|
+
else
|
73
|
+
field["dflt_value"]
|
74
|
+
end
|
75
|
+
|
76
|
+
type_metadata = fetch_type_metadata(field["type"])
|
77
|
+
Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, table_name, nil, field["collation"])
|
78
|
+
end
|
79
|
+
|
6
80
|
def data_source_sql(name = nil, type: nil)
|
7
81
|
scope = quoted_scope(name, type: type)
|
8
82
|
scope[:type] ||= "'table','view'"
|
9
83
|
|
10
|
-
sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'"
|
84
|
+
sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'".dup
|
11
85
|
sql << " AND name = #{scope[:name]}" if scope[:name]
|
12
86
|
sql << " AND type IN (#{scope[:type]})"
|
13
87
|
sql
|