activerecord 5.1.0 → 5.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +410 -530
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- 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 +23 -32
- data/lib/active_record/associations/association.rb +20 -21
- data/lib/active_record/associations/association_scope.rb +49 -49
- data/lib/active_record/associations/belongs_to_association.rb +12 -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 +10 -6
- 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 +50 -41
- data/lib/active_record/associations/collection_proxy.rb +22 -39
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +4 -2
- data/lib/active_record/associations/has_many_through_association.rb +12 -18
- data/lib/active_record/associations/has_one_association.rb +5 -1
- data/lib/active_record/associations/has_one_through_association.rb +8 -7
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -64
- 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 +27 -44
- data/lib/active_record/associations/preloader/association.rb +53 -92
- data/lib/active_record/associations/preloader/through_association.rb +72 -73
- 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 +26 -11
- data/lib/active_record/associations.rb +68 -76
- data/lib/active_record/attribute_assignment.rb +2 -0
- 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 +24 -214
- data/lib/active_record/attribute_methods/primary_key.rb +10 -13
- 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 +22 -19
- data/lib/active_record/attribute_methods.rb +48 -12
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +8 -11
- 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 +14 -10
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +175 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -24
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +58 -3
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +165 -85
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +118 -180
- data/lib/active_record/connection_adapters/column.rb +4 -2
- 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 -17
- 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 -23
- 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 +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
- 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_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 -11
- 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 -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 +2 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
- 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 +269 -126
- 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 +64 -85
- 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 -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 +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +92 -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 +39 -60
- data/lib/active_record/counter_cache.rb +3 -2
- 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 +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 +9 -9
- 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 +8 -6
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +46 -4
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +74 -22
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +181 -137
- data/lib/active_record/model_schema.rb +73 -58
- 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 +153 -18
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +4 -2
- 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 +47 -37
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +131 -204
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +32 -17
- data/lib/active_record/relation/calculations.rb +58 -20
- data/lib/active_record/relation/delegation.rb +10 -29
- data/lib/active_record/relation/finder_methods.rb +74 -85
- 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 +54 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
- 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 +9 -2
- data/lib/active_record/relation/query_methods.rb +101 -95
- 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 -67
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +99 -202
- 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 +10 -7
- data/lib/active_record/scoping/named.rb +38 -12
- data/lib/active_record/scoping.rb +12 -10
- 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 +37 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
- data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -5
- 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 -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 +25 -37
- 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 -113
- 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 -33
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Make sure we're using pg high enough for type casts and Ruby 2.2+ compatibility
|
2
|
-
gem "pg", "
|
4
|
+
gem "pg", ">= 0.18", "< 2.0"
|
3
5
|
require "pg"
|
4
6
|
|
5
7
|
require "active_record/connection_adapters/abstract_adapter"
|
@@ -62,11 +64,11 @@ module ActiveRecord
|
|
62
64
|
# defaults to true.
|
63
65
|
#
|
64
66
|
# Any further options are used as connection parameters to libpq. See
|
65
|
-
#
|
67
|
+
# https://www.postgresql.org/docs/current/static/libpq-connect.html for the
|
66
68
|
# list of parameters.
|
67
69
|
#
|
68
70
|
# In addition, default connection parameters of libpq can be set per environment variables.
|
69
|
-
# See
|
71
|
+
# See https://www.postgresql.org/docs/current/static/libpq-envars.html .
|
70
72
|
class PostgreSQLAdapter < AbstractAdapter
|
71
73
|
ADAPTER_NAME = "PostgreSQL".freeze
|
72
74
|
|
@@ -74,7 +76,7 @@ module ActiveRecord
|
|
74
76
|
primary_key: "bigserial primary key",
|
75
77
|
string: { name: "character varying" },
|
76
78
|
text: { name: "text" },
|
77
|
-
integer: { name: "integer" },
|
79
|
+
integer: { name: "integer", limit: 4 },
|
78
80
|
float: { name: "float" },
|
79
81
|
decimal: { name: "decimal" },
|
80
82
|
datetime: { name: "timestamp" },
|
@@ -119,19 +121,8 @@ module ActiveRecord
|
|
119
121
|
include PostgreSQL::ReferentialIntegrity
|
120
122
|
include PostgreSQL::SchemaStatements
|
121
123
|
include PostgreSQL::DatabaseStatements
|
122
|
-
include PostgreSQL::ColumnDumper
|
123
|
-
|
124
|
-
def schema_creation # :nodoc:
|
125
|
-
PostgreSQL::SchemaCreation.new self
|
126
|
-
end
|
127
|
-
|
128
|
-
def arel_visitor # :nodoc:
|
129
|
-
Arel::Visitors::PostgreSQL.new(self)
|
130
|
-
end
|
131
124
|
|
132
|
-
|
133
|
-
# caching.
|
134
|
-
def supports_statement_cache?
|
125
|
+
def supports_bulk_alter?
|
135
126
|
true
|
136
127
|
end
|
137
128
|
|
@@ -155,6 +146,10 @@ module ActiveRecord
|
|
155
146
|
true
|
156
147
|
end
|
157
148
|
|
149
|
+
def supports_validate_constraints?
|
150
|
+
true
|
151
|
+
end
|
152
|
+
|
158
153
|
def supports_views?
|
159
154
|
true
|
160
155
|
end
|
@@ -179,7 +174,7 @@ module ActiveRecord
|
|
179
174
|
{ concurrently: "CONCURRENTLY" }
|
180
175
|
end
|
181
176
|
|
182
|
-
class StatementPool < ConnectionAdapters::StatementPool
|
177
|
+
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
183
178
|
def initialize(connection, max)
|
184
179
|
super(max)
|
185
180
|
@connection = connection
|
@@ -195,9 +190,9 @@ module ActiveRecord
|
|
195
190
|
end
|
196
191
|
|
197
192
|
private
|
198
|
-
|
199
193
|
def dealloc(key)
|
200
194
|
@connection.query "DEALLOCATE #{key}" if connection_active?
|
195
|
+
rescue PG::Error
|
201
196
|
end
|
202
197
|
|
203
198
|
def connection_active?
|
@@ -229,7 +224,7 @@ module ActiveRecord
|
|
229
224
|
add_pg_decoders
|
230
225
|
|
231
226
|
@type_map = Type::HashLookupTypeMap.new
|
232
|
-
initialize_type_map
|
227
|
+
initialize_type_map
|
233
228
|
@local_tz = execute("SHOW TIME ZONE", "SCHEMA").first["TimeZone"]
|
234
229
|
@use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
|
235
230
|
end
|
@@ -285,6 +280,11 @@ module ActiveRecord
|
|
285
280
|
end
|
286
281
|
end
|
287
282
|
|
283
|
+
def discard! # :nodoc:
|
284
|
+
@connection.socket_io.reopen(IO::NULL) rescue nil
|
285
|
+
@connection = nil
|
286
|
+
end
|
287
|
+
|
288
288
|
def native_database_types #:nodoc:
|
289
289
|
NATIVE_DATABASE_TYPES
|
290
290
|
end
|
@@ -309,8 +309,8 @@ module ActiveRecord
|
|
309
309
|
true
|
310
310
|
end
|
311
311
|
|
312
|
-
# Range datatypes weren't introduced until PostgreSQL 9.2
|
313
312
|
def supports_ranges?
|
313
|
+
# Range datatypes weren't introduced until PostgreSQL 9.2
|
314
314
|
postgresql_version >= 90200
|
315
315
|
end
|
316
316
|
|
@@ -318,22 +318,26 @@ module ActiveRecord
|
|
318
318
|
postgresql_version >= 90300
|
319
319
|
end
|
320
320
|
|
321
|
+
def supports_foreign_tables?
|
322
|
+
postgresql_version >= 90300
|
323
|
+
end
|
324
|
+
|
321
325
|
def supports_pgcrypto_uuid?
|
322
326
|
postgresql_version >= 90400
|
323
327
|
end
|
324
328
|
|
325
329
|
def get_advisory_lock(lock_id) # :nodoc:
|
326
330
|
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
327
|
-
raise(ArgumentError, "
|
331
|
+
raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
|
328
332
|
end
|
329
|
-
|
333
|
+
query_value("SELECT pg_try_advisory_lock(#{lock_id})")
|
330
334
|
end
|
331
335
|
|
332
336
|
def release_advisory_lock(lock_id) # :nodoc:
|
333
337
|
unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
|
334
|
-
raise(ArgumentError, "
|
338
|
+
raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
|
335
339
|
end
|
336
|
-
|
340
|
+
query_value("SELECT pg_advisory_unlock(#{lock_id})")
|
337
341
|
end
|
338
342
|
|
339
343
|
def enable_extension(name)
|
@@ -349,46 +353,31 @@ module ActiveRecord
|
|
349
353
|
end
|
350
354
|
|
351
355
|
def extension_enabled?(name)
|
352
|
-
|
353
|
-
|
354
|
-
"SCHEMA"
|
355
|
-
res.cast_values.first
|
356
|
-
end
|
356
|
+
res = exec_query("SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled", "SCHEMA")
|
357
|
+
res.cast_values.first
|
357
358
|
end
|
358
359
|
|
359
360
|
def extensions
|
360
|
-
|
361
|
-
exec_query("SELECT extname from pg_extension", "SCHEMA").cast_values
|
362
|
-
else
|
363
|
-
super
|
364
|
-
end
|
361
|
+
exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
|
365
362
|
end
|
366
363
|
|
367
364
|
# Returns the configured supported identifier length supported by PostgreSQL
|
368
|
-
def
|
369
|
-
@max_identifier_length ||=
|
365
|
+
def max_identifier_length
|
366
|
+
@max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
|
370
367
|
end
|
371
|
-
alias
|
368
|
+
alias table_alias_length max_identifier_length
|
369
|
+
alias index_name_length max_identifier_length
|
372
370
|
|
373
371
|
# Set the authorized user for this session
|
374
372
|
def session_auth=(user)
|
375
373
|
clear_cache!
|
376
|
-
|
374
|
+
execute("SET SESSION AUTHORIZATION #{user}")
|
377
375
|
end
|
378
376
|
|
379
377
|
def use_insert_returning?
|
380
378
|
@use_insert_returning
|
381
379
|
end
|
382
380
|
|
383
|
-
def update_table_definition(table_name, base) #:nodoc:
|
384
|
-
PostgreSQL::Table.new(table_name, base)
|
385
|
-
end
|
386
|
-
|
387
|
-
def lookup_cast_type(sql_type) # :nodoc:
|
388
|
-
oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").first["oid"].to_i
|
389
|
-
super(oid)
|
390
|
-
end
|
391
|
-
|
392
381
|
def column_name_for_operation(operation, node) # :nodoc:
|
393
382
|
OPERATION_ALIASES.fetch(operation) { operation.downcase }
|
394
383
|
end
|
@@ -409,8 +398,7 @@ module ActiveRecord
|
|
409
398
|
end
|
410
399
|
|
411
400
|
private
|
412
|
-
|
413
|
-
# See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
401
|
+
# See https://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
414
402
|
VALUE_LIMIT_VIOLATION = "22001"
|
415
403
|
NUMERIC_VALUE_OUT_OF_RANGE = "22003"
|
416
404
|
NOT_NULL_VIOLATION = "23502"
|
@@ -418,6 +406,8 @@ module ActiveRecord
|
|
418
406
|
UNIQUE_VIOLATION = "23505"
|
419
407
|
SERIALIZATION_FAILURE = "40001"
|
420
408
|
DEADLOCK_DETECTED = "40P01"
|
409
|
+
LOCK_NOT_AVAILABLE = "55P03"
|
410
|
+
QUERY_CANCELED = "57014"
|
421
411
|
|
422
412
|
def translate_exception(exception, message)
|
423
413
|
return exception unless exception.respond_to?(:result)
|
@@ -437,6 +427,10 @@ module ActiveRecord
|
|
437
427
|
SerializationFailure.new(message)
|
438
428
|
when DEADLOCK_DETECTED
|
439
429
|
Deadlocked.new(message)
|
430
|
+
when LOCK_NOT_AVAILABLE
|
431
|
+
LockWaitTimeout.new(message)
|
432
|
+
when QUERY_CANCELED
|
433
|
+
QueryCanceled.new(message)
|
440
434
|
else
|
441
435
|
super
|
442
436
|
end
|
@@ -444,7 +438,7 @@ module ActiveRecord
|
|
444
438
|
|
445
439
|
def get_oid_type(oid, fmod, column_name, sql_type = "".freeze)
|
446
440
|
if !type_map.key?(oid)
|
447
|
-
load_additional_types(
|
441
|
+
load_additional_types([oid])
|
448
442
|
end
|
449
443
|
|
450
444
|
type_map.fetch(oid, fmod, sql_type) {
|
@@ -455,10 +449,10 @@ module ActiveRecord
|
|
455
449
|
}
|
456
450
|
end
|
457
451
|
|
458
|
-
def initialize_type_map(m)
|
459
|
-
|
460
|
-
|
461
|
-
|
452
|
+
def initialize_type_map(m = type_map)
|
453
|
+
m.register_type "int2", Type::Integer.new(limit: 2)
|
454
|
+
m.register_type "int4", Type::Integer.new(limit: 4)
|
455
|
+
m.register_type "int8", Type::Integer.new(limit: 8)
|
462
456
|
m.register_type "oid", OID::Oid.new
|
463
457
|
m.register_type "float4", Type::Float.new
|
464
458
|
m.alias_type "float8", "float4"
|
@@ -477,7 +471,7 @@ module ActiveRecord
|
|
477
471
|
m.register_type "bytea", OID::Bytea.new
|
478
472
|
m.register_type "point", OID::Point.new
|
479
473
|
m.register_type "hstore", OID::Hstore.new
|
480
|
-
m.register_type "json",
|
474
|
+
m.register_type "json", Type::Json.new
|
481
475
|
m.register_type "jsonb", OID::Jsonb.new
|
482
476
|
m.register_type "cidr", OID::Cidr.new
|
483
477
|
m.register_type "inet", OID::Inet.new
|
@@ -522,18 +516,7 @@ module ActiveRecord
|
|
522
516
|
end
|
523
517
|
end
|
524
518
|
|
525
|
-
load_additional_types
|
526
|
-
end
|
527
|
-
|
528
|
-
def extract_limit(sql_type)
|
529
|
-
case sql_type
|
530
|
-
when /^bigint/i, /^int8/i
|
531
|
-
8
|
532
|
-
when /^smallint/i
|
533
|
-
2
|
534
|
-
else
|
535
|
-
super
|
536
|
-
end
|
519
|
+
load_additional_types
|
537
520
|
end
|
538
521
|
|
539
522
|
# Extracts the value from a PostgreSQL column default definition.
|
@@ -571,7 +554,7 @@ module ActiveRecord
|
|
571
554
|
!default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
|
572
555
|
end
|
573
556
|
|
574
|
-
def load_additional_types(
|
557
|
+
def load_additional_types(oids = nil)
|
575
558
|
initializer = OID::TypeMapInitializer.new(type_map)
|
576
559
|
|
577
560
|
if supports_ranges?
|
@@ -590,7 +573,7 @@ module ActiveRecord
|
|
590
573
|
if oids
|
591
574
|
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
592
575
|
else
|
593
|
-
query += initializer.query_conditions_for_initial_load
|
576
|
+
query += initializer.query_conditions_for_initial_load
|
594
577
|
end
|
595
578
|
|
596
579
|
execute_and_clear(query, "SCHEMA", []) do |records|
|
@@ -655,7 +638,7 @@ module ActiveRecord
|
|
655
638
|
# ActiveRecord::PreparedStatementCacheExpired
|
656
639
|
#
|
657
640
|
# Check here for more details:
|
658
|
-
#
|
641
|
+
# https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
|
659
642
|
CACHED_PLAN_HEURISTIC = "cached plan must not change result type".freeze
|
660
643
|
def is_cached_plan_failure?(e)
|
661
644
|
pgerror = e.cause
|
@@ -720,18 +703,20 @@ module ActiveRecord
|
|
720
703
|
# Use standard-conforming strings so we don't have to do the E'...' dance.
|
721
704
|
set_standard_conforming_strings
|
722
705
|
|
706
|
+
variables = @config.fetch(:variables, {}).stringify_keys
|
707
|
+
|
723
708
|
# If using Active Record's time zone support configure the connection to return
|
724
709
|
# TIMESTAMP WITH ZONE types in UTC.
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
710
|
+
unless variables["timezone"]
|
711
|
+
if ActiveRecord::Base.default_timezone == :utc
|
712
|
+
variables["timezone"] = "UTC"
|
713
|
+
elsif @local_tz
|
714
|
+
variables["timezone"] = @local_tz
|
715
|
+
end
|
730
716
|
end
|
731
717
|
|
732
718
|
# SET statements from :variables config hash
|
733
|
-
#
|
734
|
-
variables = @config[:variables] || {}
|
719
|
+
# https://www.postgresql.org/docs/current/static/sql-set.html
|
735
720
|
variables.map do |k, v|
|
736
721
|
if v == ":default" || v == :default
|
737
722
|
# Sets the value to the global or compile default
|
@@ -742,11 +727,6 @@ module ActiveRecord
|
|
742
727
|
end
|
743
728
|
end
|
744
729
|
|
745
|
-
# Returns the current ID of a table's sequence.
|
746
|
-
def last_insert_id_result(sequence_name)
|
747
|
-
exec_query("SELECT currval('#{sequence_name}')", "SQL")
|
748
|
-
end
|
749
|
-
|
750
730
|
# Returns the list of a table's column names, data types, and default values.
|
751
731
|
#
|
752
732
|
# The underlying query is roughly:
|
@@ -785,8 +765,8 @@ module ActiveRecord
|
|
785
765
|
$1.strip if $1
|
786
766
|
end
|
787
767
|
|
788
|
-
def
|
789
|
-
PostgreSQL
|
768
|
+
def arel_visitor
|
769
|
+
Arel::Visitors::PostgreSQL.new(self)
|
790
770
|
end
|
791
771
|
|
792
772
|
def can_perform_case_insensitive_comparison_for?(column)
|
@@ -862,7 +842,6 @@ module ActiveRecord
|
|
862
842
|
ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
|
863
843
|
ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
|
864
844
|
ActiveRecord::Type.register(:inet, OID::Inet, adapter: :postgresql)
|
865
|
-
ActiveRecord::Type.register(:json, OID::Json, adapter: :postgresql)
|
866
845
|
ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
|
867
846
|
ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
|
868
847
|
ActiveRecord::Type.register(:point, OID::Point, adapter: :postgresql)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
class SchemaCache
|
@@ -26,7 +28,7 @@ module ActiveRecord
|
|
26
28
|
coder["columns_hash"] = @columns_hash
|
27
29
|
coder["primary_keys"] = @primary_keys
|
28
30
|
coder["data_sources"] = @data_sources
|
29
|
-
coder["version"] =
|
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
|
@@ -22,6 +24,22 @@ module ActiveRecord
|
|
22
24
|
"x'#{value.hex}'"
|
23
25
|
end
|
24
26
|
|
27
|
+
def quoted_true
|
28
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? "1".freeze : "'t'".freeze
|
29
|
+
end
|
30
|
+
|
31
|
+
def unquoted_true
|
32
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? 1 : "t".freeze
|
33
|
+
end
|
34
|
+
|
35
|
+
def quoted_false
|
36
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? "0".freeze : "'f'".freeze
|
37
|
+
end
|
38
|
+
|
39
|
+
def unquoted_false
|
40
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer ? 0 : "f".freeze
|
41
|
+
end
|
42
|
+
|
25
43
|
private
|
26
44
|
|
27
45
|
def _type_cast(value)
|
@@ -1,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
|