activerecord 6.0.0.rc1 → 6.0.3.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +251 -3
- data/README.rdoc +1 -1
- data/lib/active_record.rb +1 -0
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +0 -1
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations.rb +2 -2
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +5 -1
- data/lib/active_record/associations/builder/collection_association.rb +2 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -3
- data/lib/active_record/associations/collection_association.rb +6 -2
- data/lib/active_record/associations/collection_proxy.rb +2 -3
- data/lib/active_record/associations/has_many_association.rb +0 -1
- data/lib/active_record/associations/join_dependency.rb +23 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +12 -3
- data/lib/active_record/associations/preloader.rb +2 -3
- data/lib/active_record/associations/preloader/association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +0 -1
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods.rb +0 -51
- data/lib/active_record/attribute_methods/before_type_cast.rb +0 -1
- data/lib/active_record/attribute_methods/dirty.rb +8 -3
- data/lib/active_record/attribute_methods/primary_key.rb +0 -2
- data/lib/active_record/attribute_methods/read.rb +0 -1
- data/lib/active_record/attribute_methods/serialization.rb +0 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +0 -2
- data/lib/active_record/attribute_methods/write.rb +0 -1
- data/lib/active_record/attributes.rb +0 -1
- data/lib/active_record/autosave_association.rb +11 -7
- data/lib/active_record/callbacks.rb +1 -2
- data/lib/active_record/coders/yaml_column.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +107 -13
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +21 -15
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +27 -27
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +55 -37
- data/lib/active_record/connection_adapters/abstract/transaction.rb +14 -7
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -25
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -32
- data/lib/active_record/connection_adapters/connection_specification.rb +3 -4
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +8 -12
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +3 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -8
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -4
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +9 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -29
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +17 -3
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +8 -7
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -3
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +23 -8
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +17 -22
- data/lib/active_record/core.rb +8 -6
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +60 -31
- data/lib/active_record/database_configurations/url_config.rb +0 -1
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +9 -0
- data/lib/active_record/explain.rb +0 -1
- data/lib/active_record/fixture_set/table_row.rb +0 -1
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +11 -9
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +0 -3
- data/lib/active_record/insert_all.rb +5 -6
- data/lib/active_record/internal_metadata.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +0 -1
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +3 -4
- data/lib/active_record/middleware/database_selector/resolver.rb +5 -8
- data/lib/active_record/migration.rb +43 -32
- data/lib/active_record/migration/command_recorder.rb +6 -18
- data/lib/active_record/migration/compatibility.rb +3 -3
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +3 -2
- data/lib/active_record/nested_attributes.rb +0 -2
- data/lib/active_record/no_touching.rb +2 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +4 -5
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +1 -2
- data/lib/active_record/railties/collection_cache_association_loading.rb +1 -1
- data/lib/active_record/railties/databases.rake +63 -23
- data/lib/active_record/reflection.rb +9 -9
- data/lib/active_record/relation.rb +13 -1
- data/lib/active_record/relation/batches.rb +0 -1
- data/lib/active_record/relation/calculations.rb +3 -5
- data/lib/active_record/relation/delegation.rb +7 -6
- data/lib/active_record/relation/finder_methods.rb +14 -4
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +6 -3
- data/lib/active_record/relation/predicate_builder.rb +1 -5
- data/lib/active_record/relation/query_methods.rb +94 -55
- data/lib/active_record/relation/spawn_methods.rb +0 -1
- data/lib/active_record/relation/where_clause.rb +0 -1
- data/lib/active_record/result.rb +0 -1
- data/lib/active_record/sanitization.rb +30 -2
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +5 -1
- data/lib/active_record/schema_migration.rb +1 -1
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +3 -3
- data/lib/active_record/store.rb +1 -1
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +21 -10
- data/lib/active_record/tasks/database_tasks.rb +76 -8
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -2
- data/lib/active_record/tasks/postgresql_database_tasks.rb +0 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +0 -1
- data/lib/active_record/test_databases.rb +1 -16
- data/lib/active_record/test_fixtures.rb +2 -1
- data/lib/active_record/timestamp.rb +26 -17
- data/lib/active_record/touch_later.rb +3 -2
- data/lib/active_record/transactions.rb +18 -19
- data/lib/active_record/type.rb +0 -1
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +0 -1
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +16 -10
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/arel.rb +17 -6
- data/lib/arel/predications.rb +5 -6
- data/lib/arel/visitors/depth_first.rb +1 -2
- data/lib/arel/visitors/dot.rb +0 -1
- data/lib/arel/visitors/mssql.rb +0 -1
- data/lib/arel/visitors/oracle.rb +1 -2
- data/lib/arel/visitors/oracle12.rb +0 -1
- data/lib/arel/visitors/postgresql.rb +0 -1
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +23 -27
- data/lib/arel/visitors/visitor.rb +9 -6
- data/lib/arel/visitors/where_sql.rb +0 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +0 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +0 -1
- metadata +13 -9
@@ -98,9 +98,13 @@ module ActiveRecord
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def rollback_records
|
101
|
-
ite = records.uniq
|
101
|
+
ite = records.uniq(&:__id__)
|
102
|
+
already_run_callbacks = {}
|
102
103
|
while record = ite.shift
|
103
|
-
record.
|
104
|
+
trigger_callbacks = record.trigger_transactional_callbacks?
|
105
|
+
should_run_callbacks = !already_run_callbacks[record] && trigger_callbacks
|
106
|
+
already_run_callbacks[record] ||= trigger_callbacks
|
107
|
+
record.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: should_run_callbacks)
|
104
108
|
end
|
105
109
|
ensure
|
106
110
|
ite.each do |i|
|
@@ -113,10 +117,14 @@ module ActiveRecord
|
|
113
117
|
end
|
114
118
|
|
115
119
|
def commit_records
|
116
|
-
ite = records.uniq
|
120
|
+
ite = records.uniq(&:__id__)
|
121
|
+
already_run_callbacks = {}
|
117
122
|
while record = ite.shift
|
118
123
|
if @run_commit_callbacks
|
119
|
-
record.
|
124
|
+
trigger_callbacks = record.trigger_transactional_callbacks?
|
125
|
+
should_run_callbacks = !already_run_callbacks[record] && trigger_callbacks
|
126
|
+
already_run_callbacks[record] ||= trigger_callbacks
|
127
|
+
record.committed!(should_run_callbacks: should_run_callbacks)
|
120
128
|
else
|
121
129
|
# if not running callbacks, only adds the record to the parent transaction
|
122
130
|
connection.add_transaction_record(record)
|
@@ -133,8 +141,8 @@ module ActiveRecord
|
|
133
141
|
end
|
134
142
|
|
135
143
|
class SavepointTransaction < Transaction
|
136
|
-
def initialize(connection, savepoint_name, parent_transaction, *args)
|
137
|
-
super(connection, *args)
|
144
|
+
def initialize(connection, savepoint_name, parent_transaction, *args, **options)
|
145
|
+
super(connection, *args, **options)
|
138
146
|
|
139
147
|
parent_transaction.state.add_child(@state)
|
140
148
|
|
@@ -301,7 +309,6 @@ module ActiveRecord
|
|
301
309
|
end
|
302
310
|
|
303
311
|
private
|
304
|
-
|
305
312
|
NULL_TRANSACTION = NullTransaction.new
|
306
313
|
|
307
314
|
# Deallocate invalidated prepared statements outside of the transaction
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "set"
|
3
4
|
require "active_record/connection_adapters/determine_if_preparable_visitor"
|
4
5
|
require "active_record/connection_adapters/schema_cache"
|
5
6
|
require "active_record/connection_adapters/sql_type_metadata"
|
@@ -76,9 +77,10 @@ module ActiveRecord
|
|
76
77
|
include Savepoints
|
77
78
|
|
78
79
|
SIMPLE_INT = /\A\d+\z/
|
80
|
+
COMMENT_REGEX = %r{/\*(?:[^\*]|\*[^/])*\*/}m
|
79
81
|
|
80
82
|
attr_accessor :pool
|
81
|
-
attr_reader :
|
83
|
+
attr_reader :visitor, :owner, :logger, :lock
|
82
84
|
alias :in_use? :owner
|
83
85
|
|
84
86
|
set_callback :checkin, :after, :enable_lazy_transactions!
|
@@ -102,8 +104,16 @@ module ActiveRecord
|
|
102
104
|
end
|
103
105
|
|
104
106
|
def self.build_read_query_regexp(*parts) # :nodoc:
|
105
|
-
parts = parts.map { |part|
|
106
|
-
Regexp.union(*parts)
|
107
|
+
parts = parts.map { |part| /#{part}/i }
|
108
|
+
/\A(?:[\(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.quoted_column_names # :nodoc:
|
112
|
+
@quoted_column_names ||= {}
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.quoted_table_names # :nodoc:
|
116
|
+
@quoted_table_names ||= {}
|
107
117
|
end
|
108
118
|
|
109
119
|
def initialize(connection, logger = nil, config = {}) # :nodoc:
|
@@ -114,11 +124,8 @@ module ActiveRecord
|
|
114
124
|
@instrumenter = ActiveSupport::Notifications.instrumenter
|
115
125
|
@logger = logger
|
116
126
|
@config = config
|
117
|
-
@pool =
|
127
|
+
@pool = ActiveRecord::ConnectionAdapters::NullPool.new
|
118
128
|
@idle_since = Concurrent.monotonic_time
|
119
|
-
@schema_cache = SchemaCache.new self
|
120
|
-
@quoted_column_names, @quoted_table_names = {}, {}
|
121
|
-
@prevent_writes = false
|
122
129
|
@visitor = arel_visitor
|
123
130
|
@statements = build_statement_pool
|
124
131
|
@lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
@@ -144,19 +151,7 @@ module ActiveRecord
|
|
144
151
|
# Returns true if the connection is a replica, or if +prevent_writes+
|
145
152
|
# is set to true.
|
146
153
|
def preventing_writes?
|
147
|
-
replica? || prevent_writes
|
148
|
-
end
|
149
|
-
|
150
|
-
# Prevent writing to the database regardless of role.
|
151
|
-
#
|
152
|
-
# In some cases you may want to prevent writes to the database
|
153
|
-
# even if you are on a database that can write. `while_preventing_writes`
|
154
|
-
# will prevent writes to the database for the duration of the block.
|
155
|
-
def while_preventing_writes
|
156
|
-
original, @prevent_writes = @prevent_writes, true
|
157
|
-
yield
|
158
|
-
ensure
|
159
|
-
@prevent_writes = original
|
154
|
+
replica? || ActiveRecord::Base.connection_handler.prevent_writes
|
160
155
|
end
|
161
156
|
|
162
157
|
def migrations_paths # :nodoc:
|
@@ -164,7 +159,30 @@ module ActiveRecord
|
|
164
159
|
end
|
165
160
|
|
166
161
|
def migration_context # :nodoc:
|
167
|
-
MigrationContext.new(migrations_paths)
|
162
|
+
MigrationContext.new(migrations_paths, schema_migration)
|
163
|
+
end
|
164
|
+
|
165
|
+
def schema_migration # :nodoc:
|
166
|
+
@schema_migration ||= begin
|
167
|
+
conn = self
|
168
|
+
spec_name = conn.pool.spec.name
|
169
|
+
name = "#{spec_name}::SchemaMigration"
|
170
|
+
|
171
|
+
Class.new(ActiveRecord::SchemaMigration) do
|
172
|
+
define_singleton_method(:name) { name }
|
173
|
+
define_singleton_method(:to_s) { name }
|
174
|
+
|
175
|
+
self.connection_specification_name = spec_name
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def prepared_statements
|
181
|
+
@prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
|
182
|
+
end
|
183
|
+
|
184
|
+
def prepared_statements_disabled_cache # :nodoc:
|
185
|
+
Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
|
168
186
|
end
|
169
187
|
|
170
188
|
class Version
|
@@ -206,9 +224,13 @@ module ActiveRecord
|
|
206
224
|
@owner = Thread.current
|
207
225
|
end
|
208
226
|
|
227
|
+
def schema_cache
|
228
|
+
@pool.get_schema_cache(self)
|
229
|
+
end
|
230
|
+
|
209
231
|
def schema_cache=(cache)
|
210
232
|
cache.connection = self
|
211
|
-
@
|
233
|
+
@pool.set_schema_cache(cache)
|
212
234
|
end
|
213
235
|
|
214
236
|
# this method must only be called while holding connection pool's mutex
|
@@ -247,10 +269,10 @@ module ActiveRecord
|
|
247
269
|
end
|
248
270
|
|
249
271
|
def unprepared_statement
|
250
|
-
|
272
|
+
cache = prepared_statements_disabled_cache.add(object_id) if @prepared_statements
|
251
273
|
yield
|
252
274
|
ensure
|
253
|
-
|
275
|
+
cache&.delete(object_id)
|
254
276
|
end
|
255
277
|
|
256
278
|
# Returns the human-readable name of the adapter. Use mixed case - one
|
@@ -259,6 +281,11 @@ module ActiveRecord
|
|
259
281
|
self.class::ADAPTER_NAME
|
260
282
|
end
|
261
283
|
|
284
|
+
# Does the database for this adapter exist?
|
285
|
+
def self.database_exists?(config)
|
286
|
+
raise NotImplementedError
|
287
|
+
end
|
288
|
+
|
262
289
|
# Does this adapter support DDL rollbacks in transactions? That is, would
|
263
290
|
# CREATE TABLE or ALTER TABLE get rolled back by a transaction?
|
264
291
|
def supports_ddl_transactions?
|
@@ -286,6 +313,10 @@ module ActiveRecord
|
|
286
313
|
false
|
287
314
|
end
|
288
315
|
|
316
|
+
def supports_partitioned_indexes?
|
317
|
+
false
|
318
|
+
end
|
319
|
+
|
289
320
|
# Does this adapter support index sort order?
|
290
321
|
def supports_index_sort_order?
|
291
322
|
false
|
@@ -390,6 +421,10 @@ module ActiveRecord
|
|
390
421
|
false
|
391
422
|
end
|
392
423
|
|
424
|
+
def supports_common_table_expressions?
|
425
|
+
false
|
426
|
+
end
|
427
|
+
|
393
428
|
def supports_lazy_transactions?
|
394
429
|
false
|
395
430
|
end
|
@@ -487,6 +522,9 @@ module ActiveRecord
|
|
487
522
|
#
|
488
523
|
# Prevent @connection's finalizer from touching the socket, or
|
489
524
|
# otherwise communicating with its server, when it is collected.
|
525
|
+
if schema_cache.connection == self
|
526
|
+
schema_cache.connection = nil
|
527
|
+
end
|
490
528
|
end
|
491
529
|
|
492
530
|
# Reset the state of this connection, directing the DBMS to clear
|
@@ -587,7 +625,6 @@ module ActiveRecord
|
|
587
625
|
end
|
588
626
|
|
589
627
|
private
|
590
|
-
|
591
628
|
def type_map
|
592
629
|
@type_map ||= Type::TypeMap.new.tap do |mapping|
|
593
630
|
initialize_type_map(mapping)
|
@@ -45,7 +45,6 @@ module ActiveRecord
|
|
45
45
|
|
46
46
|
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
47
47
|
private
|
48
|
-
|
49
48
|
def dealloc(stmt)
|
50
49
|
stmt.close
|
51
50
|
end
|
@@ -110,6 +109,14 @@ module ActiveRecord
|
|
110
109
|
!mariadb? && database_version >= "5.7.7"
|
111
110
|
end
|
112
111
|
|
112
|
+
def supports_common_table_expressions?
|
113
|
+
if mariadb?
|
114
|
+
database_version >= "10.2.1"
|
115
|
+
else
|
116
|
+
database_version >= "8.0.1"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
113
120
|
def supports_advisory_locks?
|
114
121
|
true
|
115
122
|
end
|
@@ -359,7 +366,7 @@ module ActiveRecord
|
|
359
366
|
end
|
360
367
|
|
361
368
|
def add_index(table_name, column_name, options = {}) #:nodoc:
|
362
|
-
index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, options)
|
369
|
+
index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, **options)
|
363
370
|
sql = +"CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}"
|
364
371
|
execute add_sql_comment!(sql, comment)
|
365
372
|
end
|
@@ -411,12 +418,13 @@ module ActiveRecord
|
|
411
418
|
create_table_info = create_table_info(table_name)
|
412
419
|
|
413
420
|
# strip create_definitions and partition_options
|
414
|
-
|
421
|
+
# Be aware that `create_table_info` might not include any table options due to `NO_TABLE_OPTIONS` sql mode.
|
422
|
+
raw_table_options = create_table_info.sub(/\A.*\n\) ?/m, "").sub(/\n\/\*!.*\*\/\n\z/m, "").strip
|
415
423
|
|
416
424
|
# strip AUTO_INCREMENT
|
417
425
|
raw_table_options.sub!(/(ENGINE=\w+)(?: AUTO_INCREMENT=\d+)/, '\1')
|
418
426
|
|
419
|
-
table_options[:options] = raw_table_options
|
427
|
+
table_options[:options] = raw_table_options unless raw_table_options.blank?
|
420
428
|
|
421
429
|
# strip COMMENT
|
422
430
|
if raw_table_options.sub!(/ COMMENT='.+'/, "")
|
@@ -440,11 +448,11 @@ module ActiveRecord
|
|
440
448
|
|
441
449
|
query_values(<<~SQL, "SCHEMA")
|
442
450
|
SELECT column_name
|
443
|
-
FROM information_schema.
|
444
|
-
WHERE
|
451
|
+
FROM information_schema.statistics
|
452
|
+
WHERE index_name = 'PRIMARY'
|
445
453
|
AND table_schema = #{scope[:schema]}
|
446
454
|
AND table_name = #{scope[:name]}
|
447
|
-
ORDER BY
|
455
|
+
ORDER BY seq_in_index
|
448
456
|
SQL
|
449
457
|
end
|
450
458
|
|
@@ -485,7 +493,7 @@ module ActiveRecord
|
|
485
493
|
def columns_for_distinct(columns, orders) # :nodoc:
|
486
494
|
order_columns = orders.reject(&:blank?).map { |s|
|
487
495
|
# Convert Arel node to string
|
488
|
-
s = s
|
496
|
+
s = visitor.compile(s) unless s.is_a?(String)
|
489
497
|
# Remove any ASC/DESC modifiers
|
490
498
|
s.gsub(/\s+(?:ASC|DESC)\b/i, "")
|
491
499
|
}.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" }
|
@@ -522,7 +530,6 @@ module ActiveRecord
|
|
522
530
|
end
|
523
531
|
|
524
532
|
private
|
525
|
-
|
526
533
|
def initialize_type_map(m = type_map)
|
527
534
|
super
|
528
535
|
|
@@ -562,12 +569,12 @@ module ActiveRecord
|
|
562
569
|
end
|
563
570
|
end
|
564
571
|
|
565
|
-
def register_integer_type(mapping, key, options)
|
572
|
+
def register_integer_type(mapping, key, **options)
|
566
573
|
mapping.register_type(key) do |sql_type|
|
567
574
|
if /\bunsigned\b/.match?(sql_type)
|
568
|
-
Type::UnsignedInteger.new(options)
|
575
|
+
Type::UnsignedInteger.new(**options)
|
569
576
|
else
|
570
|
-
Type::Integer.new(options)
|
577
|
+
Type::Integer.new(**options)
|
571
578
|
end
|
572
579
|
end
|
573
580
|
end
|
@@ -581,6 +588,7 @@ module ActiveRecord
|
|
581
588
|
end
|
582
589
|
|
583
590
|
# See https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
|
591
|
+
ER_FILSORT_ABORT = 1028
|
584
592
|
ER_DUP_ENTRY = 1062
|
585
593
|
ER_NOT_NULL_VIOLATION = 1048
|
586
594
|
ER_NO_REFERENCED_ROW = 1216
|
@@ -622,7 +630,7 @@ module ActiveRecord
|
|
622
630
|
Deadlocked.new(message, sql: sql, binds: binds)
|
623
631
|
when ER_LOCK_WAIT_TIMEOUT
|
624
632
|
LockWaitTimeout.new(message, sql: sql, binds: binds)
|
625
|
-
when ER_QUERY_TIMEOUT
|
633
|
+
when ER_QUERY_TIMEOUT, ER_FILSORT_ABORT
|
626
634
|
StatementTimeout.new(message, sql: sql, binds: binds)
|
627
635
|
when ER_QUERY_INTERRUPTED
|
628
636
|
QueryCanceled.new(message, sql: sql, binds: binds)
|
@@ -648,7 +656,7 @@ module ActiveRecord
|
|
648
656
|
end
|
649
657
|
|
650
658
|
td = create_table_definition(table_name)
|
651
|
-
cd = td.new_column_definition(column.name, type, options)
|
659
|
+
cd = td.new_column_definition(column.name, type, **options)
|
652
660
|
schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
|
653
661
|
end
|
654
662
|
|
@@ -662,12 +670,12 @@ module ActiveRecord
|
|
662
670
|
|
663
671
|
current_type = exec_query("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE #{quote(column_name)}", "SCHEMA").first["Type"]
|
664
672
|
td = create_table_definition(table_name)
|
665
|
-
cd = td.new_column_definition(new_column_name, current_type, options)
|
673
|
+
cd = td.new_column_definition(new_column_name, current_type, **options)
|
666
674
|
schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
|
667
675
|
end
|
668
676
|
|
669
677
|
def add_index_for_alter(table_name, column_name, options = {})
|
670
|
-
index_name, index_type, index_columns, _, index_algorithm, index_using = add_index_options(table_name, column_name, options)
|
678
|
+
index_name, index_type, index_columns, _, index_algorithm, index_using = add_index_options(table_name, column_name, **options)
|
671
679
|
index_algorithm[0, 0] = ", " if index_algorithm.present?
|
672
680
|
"ADD #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_algorithm}"
|
673
681
|
end
|
@@ -677,20 +685,6 @@ module ActiveRecord
|
|
677
685
|
"DROP INDEX #{quote_column_name(index_name)}"
|
678
686
|
end
|
679
687
|
|
680
|
-
def add_timestamps_for_alter(table_name, options = {})
|
681
|
-
options[:null] = false if options[:null].nil?
|
682
|
-
|
683
|
-
if !options.key?(:precision) && supports_datetime_with_precision?
|
684
|
-
options[:precision] = 6
|
685
|
-
end
|
686
|
-
|
687
|
-
[add_column_for_alter(table_name, :created_at, :datetime, options), add_column_for_alter(table_name, :updated_at, :datetime, options)]
|
688
|
-
end
|
689
|
-
|
690
|
-
def remove_timestamps_for_alter(table_name, options = {})
|
691
|
-
[remove_column_for_alter(table_name, :updated_at), remove_column_for_alter(table_name, :created_at)]
|
692
|
-
end
|
693
|
-
|
694
688
|
def supports_rename_index?
|
695
689
|
mariadb? ? false : database_version >= "5.7.6"
|
696
690
|
end
|
@@ -787,7 +781,7 @@ module ActiveRecord
|
|
787
781
|
options[:primary_key_column] = column_for(match[:target_table], match[:primary_key])
|
788
782
|
end
|
789
783
|
|
790
|
-
MismatchedForeignKey.new(options)
|
784
|
+
MismatchedForeignKey.new(**options)
|
791
785
|
end
|
792
786
|
|
793
787
|
def version_string(full_version_string)
|
@@ -804,7 +798,6 @@ module ActiveRecord
|
|
804
798
|
end
|
805
799
|
|
806
800
|
private
|
807
|
-
|
808
801
|
def cast_value(value)
|
809
802
|
case value
|
810
803
|
when true then "1"
|
@@ -56,7 +56,6 @@ module ActiveRecord
|
|
56
56
|
end
|
57
57
|
|
58
58
|
private
|
59
|
-
|
60
59
|
attr_reader :uri
|
61
60
|
|
62
61
|
def uri_parser
|
@@ -73,7 +72,7 @@ module ActiveRecord
|
|
73
72
|
# "localhost"
|
74
73
|
# # => {}
|
75
74
|
def query_hash
|
76
|
-
Hash[(@query || "").split("&").map { |pair| pair.split("=") }]
|
75
|
+
Hash[(@query || "").split("&").map { |pair| pair.split("=", 2) }]
|
77
76
|
end
|
78
77
|
|
79
78
|
def raw_config
|
@@ -186,7 +185,7 @@ module ActiveRecord
|
|
186
185
|
adapter_method = "#{spec[:adapter]}_connection"
|
187
186
|
|
188
187
|
unless ActiveRecord::Base.respond_to?(adapter_method)
|
189
|
-
raise AdapterNotFound, "database configuration specifies nonexistent #{spec
|
188
|
+
raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter"
|
190
189
|
end
|
191
190
|
|
192
191
|
ConnectionSpecification.new(spec.delete(:name) || "primary", spec, adapter_method)
|
@@ -222,7 +221,7 @@ module ActiveRecord
|
|
222
221
|
when Hash
|
223
222
|
resolve_hash_connection config_or_env
|
224
223
|
else
|
225
|
-
|
224
|
+
raise TypeError, "Invalid type for configuration. Expected Symbol, String, or Hash. Got #{config_or_env.inspect}"
|
226
225
|
end
|
227
226
|
end
|
228
227
|
|
@@ -5,7 +5,7 @@ module ActiveRecord
|
|
5
5
|
module DetermineIfPreparableVisitor
|
6
6
|
attr_accessor :preparable
|
7
7
|
|
8
|
-
def accept(
|
8
|
+
def accept(object, collector)
|
9
9
|
@preparable = true
|
10
10
|
super
|
11
11
|
end
|
@@ -20,7 +20,7 @@ module ActiveRecord
|
|
20
20
|
super
|
21
21
|
end
|
22
22
|
|
23
|
-
def visit_Arel_Nodes_SqlLiteral(
|
23
|
+
def visit_Arel_Nodes_SqlLiteral(o, collector)
|
24
24
|
@preparable = false
|
25
25
|
super
|
26
26
|
end
|