activerecord 5.1.7 → 5.2.6
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 +583 -673
- 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 +27 -8
- 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 +12 -4
- 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 +30 -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 +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 +6 -5
- data/lib/active_record/autosave_association.rb +35 -19
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -6
- 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 +12 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +139 -41
- 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 +13 -31
- 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 +92 -165
- 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 +2 -0
- 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 +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 +4 -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 +233 -111
- 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 +57 -73
- 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 +22 -0
- 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 +81 -94
- 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 +41 -61
- data/lib/active_record/counter_cache.rb +10 -3
- 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 +42 -3
- 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 +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 +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 +167 -16
- data/lib/active_record/query_cache.rb +6 -8
- data/lib/active_record/querying.rb +4 -2
- data/lib/active_record/railtie.rb +62 -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 +45 -19
- data/lib/active_record/relation/delegation.rb +45 -27
- data/lib/active_record/relation/finder_methods.rb +75 -76
- 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 +128 -99
- 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 +25 -14
- 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 +6 -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 +2 -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 +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 +23 -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,3 +1,5 @@
|
|
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"
|
@@ -70,11 +72,11 @@ module ActiveRecord
|
|
70
72
|
# defaults to true.
|
71
73
|
#
|
72
74
|
# Any further options are used as connection parameters to libpq. See
|
73
|
-
#
|
75
|
+
# https://www.postgresql.org/docs/current/static/libpq-connect.html for the
|
74
76
|
# list of parameters.
|
75
77
|
#
|
76
78
|
# In addition, default connection parameters of libpq can be set per environment variables.
|
77
|
-
# See
|
79
|
+
# See https://www.postgresql.org/docs/current/static/libpq-envars.html .
|
78
80
|
class PostgreSQLAdapter < AbstractAdapter
|
79
81
|
ADAPTER_NAME = "PostgreSQL".freeze
|
80
82
|
|
@@ -82,7 +84,7 @@ module ActiveRecord
|
|
82
84
|
primary_key: "bigserial primary key",
|
83
85
|
string: { name: "character varying" },
|
84
86
|
text: { name: "text" },
|
85
|
-
integer: { name: "integer" },
|
87
|
+
integer: { name: "integer", limit: 4 },
|
86
88
|
float: { name: "float" },
|
87
89
|
decimal: { name: "decimal" },
|
88
90
|
datetime: { name: "timestamp" },
|
@@ -127,19 +129,8 @@ module ActiveRecord
|
|
127
129
|
include PostgreSQL::ReferentialIntegrity
|
128
130
|
include PostgreSQL::SchemaStatements
|
129
131
|
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
132
|
|
140
|
-
|
141
|
-
# caching.
|
142
|
-
def supports_statement_cache?
|
133
|
+
def supports_bulk_alter?
|
143
134
|
true
|
144
135
|
end
|
145
136
|
|
@@ -163,6 +154,10 @@ module ActiveRecord
|
|
163
154
|
true
|
164
155
|
end
|
165
156
|
|
157
|
+
def supports_validate_constraints?
|
158
|
+
true
|
159
|
+
end
|
160
|
+
|
166
161
|
def supports_views?
|
167
162
|
true
|
168
163
|
end
|
@@ -187,7 +182,7 @@ module ActiveRecord
|
|
187
182
|
{ concurrently: "CONCURRENTLY" }
|
188
183
|
end
|
189
184
|
|
190
|
-
class StatementPool < ConnectionAdapters::StatementPool
|
185
|
+
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
191
186
|
def initialize(connection, max)
|
192
187
|
super(max)
|
193
188
|
@connection = connection
|
@@ -203,7 +198,6 @@ module ActiveRecord
|
|
203
198
|
end
|
204
199
|
|
205
200
|
private
|
206
|
-
|
207
201
|
def dealloc(key)
|
208
202
|
@connection.query "DEALLOCATE #{key}" if connection_active?
|
209
203
|
rescue PG::Error
|
@@ -238,7 +232,7 @@ module ActiveRecord
|
|
238
232
|
add_pg_decoders
|
239
233
|
|
240
234
|
@type_map = Type::HashLookupTypeMap.new
|
241
|
-
initialize_type_map
|
235
|
+
initialize_type_map
|
242
236
|
@local_tz = execute("SHOW TIME ZONE", "SCHEMA").first["TimeZone"]
|
243
237
|
@use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
|
244
238
|
end
|
@@ -294,6 +288,11 @@ module ActiveRecord
|
|
294
288
|
end
|
295
289
|
end
|
296
290
|
|
291
|
+
def discard! # :nodoc:
|
292
|
+
@connection.socket_io.reopen(IO::NULL) rescue nil
|
293
|
+
@connection = nil
|
294
|
+
end
|
295
|
+
|
297
296
|
def native_database_types #:nodoc:
|
298
297
|
NATIVE_DATABASE_TYPES
|
299
298
|
end
|
@@ -318,8 +317,8 @@ module ActiveRecord
|
|
318
317
|
true
|
319
318
|
end
|
320
319
|
|
321
|
-
# Range datatypes weren't introduced until PostgreSQL 9.2
|
322
320
|
def supports_ranges?
|
321
|
+
# Range datatypes weren't introduced until PostgreSQL 9.2
|
323
322
|
postgresql_version >= 90200
|
324
323
|
end
|
325
324
|
|
@@ -327,20 +326,24 @@ module ActiveRecord
|
|
327
326
|
postgresql_version >= 90300
|
328
327
|
end
|
329
328
|
|
329
|
+
def supports_foreign_tables?
|
330
|
+
postgresql_version >= 90300
|
331
|
+
end
|
332
|
+
|
330
333
|
def supports_pgcrypto_uuid?
|
331
334
|
postgresql_version >= 90400
|
332
335
|
end
|
333
336
|
|
334
337
|
def get_advisory_lock(lock_id) # :nodoc:
|
335
338
|
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
336
|
-
raise(ArgumentError, "
|
339
|
+
raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
|
337
340
|
end
|
338
341
|
query_value("SELECT pg_try_advisory_lock(#{lock_id})")
|
339
342
|
end
|
340
343
|
|
341
344
|
def release_advisory_lock(lock_id) # :nodoc:
|
342
345
|
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
343
|
-
raise(ArgumentError, "
|
346
|
+
raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
|
344
347
|
end
|
345
348
|
query_value("SELECT pg_advisory_unlock(#{lock_id})")
|
346
349
|
end
|
@@ -358,18 +361,12 @@ module ActiveRecord
|
|
358
361
|
end
|
359
362
|
|
360
363
|
def extension_enabled?(name)
|
361
|
-
|
362
|
-
|
363
|
-
res.cast_values.first
|
364
|
-
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
|
365
366
|
end
|
366
367
|
|
367
368
|
def extensions
|
368
|
-
|
369
|
-
exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
|
370
|
-
else
|
371
|
-
super
|
372
|
-
end
|
369
|
+
exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
|
373
370
|
end
|
374
371
|
|
375
372
|
# Returns the configured supported identifier length supported by PostgreSQL
|
@@ -389,10 +386,6 @@ module ActiveRecord
|
|
389
386
|
@use_insert_returning
|
390
387
|
end
|
391
388
|
|
392
|
-
def update_table_definition(table_name, base) #:nodoc:
|
393
|
-
PostgreSQL::Table.new(table_name, base)
|
394
|
-
end
|
395
|
-
|
396
389
|
def column_name_for_operation(operation, node) # :nodoc:
|
397
390
|
OPERATION_ALIASES.fetch(operation) { operation.downcase }
|
398
391
|
end
|
@@ -413,8 +406,7 @@ module ActiveRecord
|
|
413
406
|
end
|
414
407
|
|
415
408
|
private
|
416
|
-
|
417
|
-
# See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
409
|
+
# See https://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
418
410
|
VALUE_LIMIT_VIOLATION = "22001"
|
419
411
|
NUMERIC_VALUE_OUT_OF_RANGE = "22003"
|
420
412
|
NOT_NULL_VIOLATION = "23502"
|
@@ -422,6 +414,8 @@ module ActiveRecord
|
|
422
414
|
UNIQUE_VIOLATION = "23505"
|
423
415
|
SERIALIZATION_FAILURE = "40001"
|
424
416
|
DEADLOCK_DETECTED = "40P01"
|
417
|
+
LOCK_NOT_AVAILABLE = "55P03"
|
418
|
+
QUERY_CANCELED = "57014"
|
425
419
|
|
426
420
|
def translate_exception(exception, message)
|
427
421
|
return exception unless exception.respond_to?(:result)
|
@@ -441,6 +435,10 @@ module ActiveRecord
|
|
441
435
|
SerializationFailure.new(message)
|
442
436
|
when DEADLOCK_DETECTED
|
443
437
|
Deadlocked.new(message)
|
438
|
+
when LOCK_NOT_AVAILABLE
|
439
|
+
LockWaitTimeout.new(message)
|
440
|
+
when QUERY_CANCELED
|
441
|
+
QueryCanceled.new(message)
|
444
442
|
else
|
445
443
|
super
|
446
444
|
end
|
@@ -448,7 +446,7 @@ module ActiveRecord
|
|
448
446
|
|
449
447
|
def get_oid_type(oid, fmod, column_name, sql_type = "".freeze)
|
450
448
|
if !type_map.key?(oid)
|
451
|
-
load_additional_types(
|
449
|
+
load_additional_types([oid])
|
452
450
|
end
|
453
451
|
|
454
452
|
type_map.fetch(oid, fmod, sql_type) {
|
@@ -459,10 +457,10 @@ module ActiveRecord
|
|
459
457
|
}
|
460
458
|
end
|
461
459
|
|
462
|
-
def initialize_type_map(m)
|
463
|
-
|
464
|
-
|
465
|
-
|
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)
|
466
464
|
m.register_type "oid", OID::Oid.new
|
467
465
|
m.register_type "float4", Type::Float.new
|
468
466
|
m.alias_type "float8", "float4"
|
@@ -475,13 +473,13 @@ module ActiveRecord
|
|
475
473
|
register_class_with_limit m, "bit", OID::Bit
|
476
474
|
register_class_with_limit m, "varbit", OID::BitVarying
|
477
475
|
m.alias_type "timestamptz", "timestamp"
|
478
|
-
m.register_type "date",
|
476
|
+
m.register_type "date", OID::Date.new
|
479
477
|
|
480
478
|
m.register_type "money", OID::Money.new
|
481
479
|
m.register_type "bytea", OID::Bytea.new
|
482
480
|
m.register_type "point", OID::Point.new
|
483
481
|
m.register_type "hstore", OID::Hstore.new
|
484
|
-
m.register_type "json",
|
482
|
+
m.register_type "json", Type::Json.new
|
485
483
|
m.register_type "jsonb", OID::Jsonb.new
|
486
484
|
m.register_type "cidr", OID::Cidr.new
|
487
485
|
m.register_type "inet", OID::Inet.new
|
@@ -526,18 +524,7 @@ module ActiveRecord
|
|
526
524
|
end
|
527
525
|
end
|
528
526
|
|
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
|
527
|
+
load_additional_types
|
541
528
|
end
|
542
529
|
|
543
530
|
# Extracts the value from a PostgreSQL column default definition.
|
@@ -575,7 +562,7 @@ module ActiveRecord
|
|
575
562
|
!default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
|
576
563
|
end
|
577
564
|
|
578
|
-
def load_additional_types(
|
565
|
+
def load_additional_types(oids = nil)
|
579
566
|
initializer = OID::TypeMapInitializer.new(type_map)
|
580
567
|
|
581
568
|
if supports_ranges?
|
@@ -594,7 +581,7 @@ module ActiveRecord
|
|
594
581
|
if oids
|
595
582
|
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
596
583
|
else
|
597
|
-
query += initializer.query_conditions_for_initial_load
|
584
|
+
query += initializer.query_conditions_for_initial_load
|
598
585
|
end
|
599
586
|
|
600
587
|
execute_and_clear(query, "SCHEMA", []) do |records|
|
@@ -659,7 +646,7 @@ module ActiveRecord
|
|
659
646
|
# ActiveRecord::PreparedStatementCacheExpired
|
660
647
|
#
|
661
648
|
# Check here for more details:
|
662
|
-
#
|
649
|
+
# https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
|
663
650
|
CACHED_PLAN_HEURISTIC = "cached plan must not change result type".freeze
|
664
651
|
def is_cached_plan_failure?(e)
|
665
652
|
pgerror = e.cause
|
@@ -724,18 +711,20 @@ module ActiveRecord
|
|
724
711
|
# Use standard-conforming strings so we don't have to do the E'...' dance.
|
725
712
|
set_standard_conforming_strings
|
726
713
|
|
714
|
+
variables = @config.fetch(:variables, {}).stringify_keys
|
715
|
+
|
727
716
|
# If using Active Record's time zone support configure the connection to return
|
728
717
|
# TIMESTAMP WITH ZONE types in UTC.
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
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
|
734
724
|
end
|
735
725
|
|
736
726
|
# SET statements from :variables config hash
|
737
|
-
#
|
738
|
-
variables = @config[:variables] || {}
|
727
|
+
# https://www.postgresql.org/docs/current/static/sql-set.html
|
739
728
|
variables.map do |k, v|
|
740
729
|
if v == ":default" || v == :default
|
741
730
|
# Sets the value to the global or compile default
|
@@ -746,11 +735,6 @@ module ActiveRecord
|
|
746
735
|
end
|
747
736
|
end
|
748
737
|
|
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
738
|
# Returns the list of a table's column names, data types, and default values.
|
755
739
|
#
|
756
740
|
# The underlying query is roughly:
|
@@ -789,8 +773,8 @@ module ActiveRecord
|
|
789
773
|
$1.strip if $1
|
790
774
|
end
|
791
775
|
|
792
|
-
def
|
793
|
-
PostgreSQL
|
776
|
+
def arel_visitor
|
777
|
+
Arel::Visitors::PostgreSQL.new(self)
|
794
778
|
end
|
795
779
|
|
796
780
|
def can_perform_case_insensitive_comparison_for?(column)
|
@@ -861,12 +845,12 @@ module ActiveRecord
|
|
861
845
|
ActiveRecord::Type.register(:bit_varying, OID::BitVarying, adapter: :postgresql)
|
862
846
|
ActiveRecord::Type.register(:binary, OID::Bytea, adapter: :postgresql)
|
863
847
|
ActiveRecord::Type.register(:cidr, OID::Cidr, adapter: :postgresql)
|
848
|
+
ActiveRecord::Type.register(:date, OID::Date, adapter: :postgresql)
|
864
849
|
ActiveRecord::Type.register(:datetime, OID::DateTime, adapter: :postgresql)
|
865
850
|
ActiveRecord::Type.register(:decimal, OID::Decimal, adapter: :postgresql)
|
866
851
|
ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
|
867
852
|
ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
|
868
853
|
ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
|
869
|
-
ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
|
870
854
|
ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
|
871
855
|
ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
|
872
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,6 +12,10 @@ 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
|
@@ -23,6 +29,22 @@ module ActiveRecord
|
|
23
29
|
"x'#{value.hex}'"
|
24
30
|
end
|
25
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
|
+
|
26
48
|
private
|
27
49
|
|
28
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
|