activerecord 8.0.0.beta1 → 8.0.0.rc2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +102 -2
- data/lib/active_record/association_relation.rb +1 -0
- data/lib/active_record/associations/association.rb +9 -5
- data/lib/active_record/associations/has_many_through_association.rb +7 -1
- data/lib/active_record/associations.rb +28 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -12
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +6 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +0 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +8 -4
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +1 -10
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +6 -12
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +11 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +12 -10
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +0 -2
- data/lib/active_record/connection_adapters.rb +0 -56
- data/lib/active_record/core.rb +43 -14
- data/lib/active_record/database_configurations/database_config.rb +4 -0
- data/lib/active_record/database_configurations/hash_config.rb +8 -0
- data/lib/active_record/enum.rb +9 -22
- data/lib/active_record/fixtures.rb +0 -1
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +5 -11
- data/lib/active_record/marshalling.rb +4 -1
- data/lib/active_record/migration/command_recorder.rb +5 -5
- data/lib/active_record/migration.rb +0 -5
- data/lib/active_record/model_schema.rb +2 -3
- data/lib/active_record/query_cache.rb +0 -4
- data/lib/active_record/query_logs.rb +5 -11
- data/lib/active_record/querying.rb +2 -2
- data/lib/active_record/railtie.rb +2 -25
- data/lib/active_record/railties/databases.rake +2 -17
- data/lib/active_record/reflection.rb +14 -19
- data/lib/active_record/relation/calculations.rb +24 -28
- data/lib/active_record/relation/predicate_builder.rb +8 -0
- data/lib/active_record/relation/query_methods.rb +76 -38
- data/lib/active_record/relation.rb +8 -1
- data/lib/active_record/result.rb +10 -9
- data/lib/active_record/table_metadata.rb +1 -3
- data/lib/active_record/tasks/database_tasks.rb +26 -34
- data/lib/active_record/testing/query_assertions.rb +2 -2
- data/lib/active_record.rb +0 -45
- data/lib/arel/table.rb +3 -7
- data/lib/arel/visitors/sqlite.rb +25 -0
- metadata +9 -10
- data/lib/active_record/relation/record_fetch_warning.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b6b5ce7951d63889da24f22f9635d27371d6fc733e400d1510cd0ffe27f669e
|
4
|
+
data.tar.gz: 68f851f76e82b3969bc3a7125b3700ce3623ed7cf1717064f26202b4a5c062cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef1e91d706ec3c79e71b2e59780a831a63fe82ab45a8e123748c5d073bc120c3d9506d3e8b43b68aa77dc90a5f564b8ef45cb1d5abc19e008127757966bf32dc
|
7
|
+
data.tar.gz: 35e7644e3037334b724042c5f26539c2489c579fede36d461e3661cf04ca79b5c8ca0b3e3c29d8edfc9eab3de15af0b8dcee33a7d88f2f4985c46acfce26a324
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,103 @@
|
|
1
|
+
## Rails 8.0.0.rc2 (October 30, 2024) ##
|
2
|
+
|
3
|
+
* NULLS NOT DISTINCT works with UNIQUE CONSTRAINT as well as UNIQUE INDEX.
|
4
|
+
|
5
|
+
*Ryuta Kamizono*
|
6
|
+
|
7
|
+
* The `db:prepare` task no longer loads seeds when a non-primary database is created.
|
8
|
+
|
9
|
+
Previously, the `db:prepare` task would load seeds whenever a new database
|
10
|
+
is created, leading to potential loss of data if a database is added to an
|
11
|
+
existing environment.
|
12
|
+
|
13
|
+
Introduces a new database config property `seeds` to control whether seeds
|
14
|
+
are loaded during `db:prepare` which defaults to `true` for primary database
|
15
|
+
configs and `false` otherwise.
|
16
|
+
|
17
|
+
Fixes #53348.
|
18
|
+
|
19
|
+
*Mike Dalessio*
|
20
|
+
|
21
|
+
* `PG::UnableToSend: no connection to the server` is now retryable as a connection-related exception
|
22
|
+
|
23
|
+
*Kazuma Watanabe*
|
24
|
+
|
25
|
+
* Fix strict loading propagation even if statement cache is not used.
|
26
|
+
|
27
|
+
*Ryuta Kamizono*
|
28
|
+
|
29
|
+
* Allow `rename_enum` accepts two from/to name arguments as `rename_table` does so.
|
30
|
+
|
31
|
+
*Ryuta Kamizono*
|
32
|
+
|
33
|
+
|
34
|
+
## Rails 8.0.0.rc1 (October 19, 2024) ##
|
35
|
+
|
36
|
+
* Remove deprecated support to setting `ENV["SCHEMA_CACHE"]`.
|
37
|
+
|
38
|
+
*Rafael Mendonça França*
|
39
|
+
|
40
|
+
* Remove deprecated support to passing a database name to `cache_dump_filename`.
|
41
|
+
|
42
|
+
*Rafael Mendonça França*
|
43
|
+
|
44
|
+
* Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
|
45
|
+
|
46
|
+
*Rafael Mendonça França*
|
47
|
+
|
48
|
+
* Remove deprecated `config.active_record.sqlite3_deprecated_warning`.
|
49
|
+
|
50
|
+
*Rafael Mendonça França*
|
51
|
+
|
52
|
+
* Remove deprecated `config.active_record.warn_on_records_fetched_greater_than`.
|
53
|
+
|
54
|
+
*Rafael Mendonça França*
|
55
|
+
|
56
|
+
* Remove deprecated support for defining `enum` with keyword arguments.
|
57
|
+
|
58
|
+
*Rafael Mendonça França*
|
59
|
+
|
60
|
+
* Remove deprecated support to finding database adapters that aren't registered to Active Record.
|
61
|
+
|
62
|
+
*Rafael Mendonça França*
|
63
|
+
|
64
|
+
* Remove deprecated `config.active_record.allow_deprecated_singular_associations_name`.
|
65
|
+
|
66
|
+
*Rafael Mendonça França*
|
67
|
+
|
68
|
+
* Remove deprecated `config.active_record.commit_transaction_on_non_local_return`.
|
69
|
+
|
70
|
+
*Rafael Mendonça França*
|
71
|
+
|
72
|
+
* Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
|
73
|
+
|
74
|
+
*David Stosik*
|
75
|
+
|
76
|
+
* Allow to save records with polymorphic join tables that have `inverse_of`
|
77
|
+
specified.
|
78
|
+
|
79
|
+
*Markus Doits*
|
80
|
+
|
81
|
+
* Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
|
82
|
+
|
83
|
+
*Joshua Young*
|
84
|
+
|
85
|
+
* Allow `ActiveRecord::Base#pluck` to accept hash arguments with symbol and string values.
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
Post.joins(:comments).pluck(:id, comments: :id)
|
89
|
+
Post.joins(:comments).pluck("id", "comments" => "id")
|
90
|
+
```
|
91
|
+
|
92
|
+
*Joshua Young*
|
93
|
+
|
94
|
+
* Make Float distinguish between `float4` and `float8` in PostgreSQL.
|
95
|
+
|
96
|
+
Fixes #52742
|
97
|
+
|
98
|
+
*Ryota Kitazawa*, *Takayuki Nagatomi*
|
99
|
+
|
100
|
+
|
1
101
|
## Rails 8.0.0.beta1 (September 26, 2024) ##
|
2
102
|
|
3
103
|
* Allow `drop_table` to accept an array of table names.
|
@@ -15,9 +115,9 @@
|
|
15
115
|
|
16
116
|
*Ariel Rzezak*
|
17
117
|
|
18
|
-
* When running `db:migrate` on a fresh database, load the
|
118
|
+
* When running `db:migrate` on a fresh database, load the databases schemas before running migrations.
|
19
119
|
|
20
|
-
*Andrew Novoselac*
|
120
|
+
*Andrew Novoselac*, *Marek Kasztelnik*
|
21
121
|
|
22
122
|
* Fix an issue where `.left_outer_joins` used with multiple associations that have
|
23
123
|
the same child association but different parents does not join all parents.
|
@@ -120,6 +120,14 @@ module ActiveRecord
|
|
120
120
|
@association_scope = nil
|
121
121
|
end
|
122
122
|
|
123
|
+
def set_strict_loading(record)
|
124
|
+
if owner.strict_loading_n_plus_one_only? && reflection.macro == :has_many
|
125
|
+
record.strict_loading!
|
126
|
+
else
|
127
|
+
record.strict_loading!(false, mode: owner.strict_loading_mode)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
123
131
|
# Set the inverse association, if possible
|
124
132
|
def set_inverse_instance(record)
|
125
133
|
if inverse = inverse_association_for(record)
|
@@ -260,11 +268,7 @@ module ActiveRecord
|
|
260
268
|
klass.with_connection do |c|
|
261
269
|
sc.execute(binds, c, async: async) do |record|
|
262
270
|
set_inverse_instance(record)
|
263
|
-
|
264
|
-
record.strict_loading!
|
265
|
-
else
|
266
|
-
record.strict_loading!(false, mode: owner.strict_loading_mode)
|
267
|
-
end
|
271
|
+
set_strict_loading(record)
|
268
272
|
end
|
269
273
|
end
|
270
274
|
end
|
@@ -93,7 +93,13 @@ module ActiveRecord
|
|
93
93
|
@through_scope = scope
|
94
94
|
record = super
|
95
95
|
|
96
|
-
inverse =
|
96
|
+
inverse =
|
97
|
+
if source_reflection.polymorphic?
|
98
|
+
source_reflection.polymorphic_inverse_of(record.class)
|
99
|
+
else
|
100
|
+
source_reflection.inverse_of
|
101
|
+
end
|
102
|
+
|
97
103
|
if inverse
|
98
104
|
if inverse.collection?
|
99
105
|
record.send(inverse.name) << build_through_record(record)
|
@@ -559,7 +559,7 @@ module ActiveRecord
|
|
559
559
|
# @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around
|
560
560
|
# @group.avatars.delete(@group.avatars.last) # so would this
|
561
561
|
#
|
562
|
-
#
|
562
|
+
# === Setting Inverses
|
563
563
|
#
|
564
564
|
# If you are using a #belongs_to on the join model, it is a good idea to set the
|
565
565
|
# <tt>:inverse_of</tt> option on the #belongs_to, which will mean that the following example
|
@@ -1221,8 +1221,11 @@ module ActiveRecord
|
|
1221
1221
|
# If you are going to modify the association (rather than just read from it), then it is
|
1222
1222
|
# a good idea to set the <tt>:inverse_of</tt> option on the source association on the
|
1223
1223
|
# join model. This allows associated records to be built which will automatically create
|
1224
|
-
# the appropriate join model records when they are saved.
|
1225
|
-
#
|
1224
|
+
# the appropriate join model records when they are saved. See
|
1225
|
+
# {Association Join Models}[rdoc-ref:Associations::ClassMethods@Association+Join+Models]
|
1226
|
+
# and {Setting Inverses}[rdoc-ref:Associations::ClassMethods@Setting+Inverses] for
|
1227
|
+
# more detail.
|
1228
|
+
#
|
1226
1229
|
# [+:disable_joins+]
|
1227
1230
|
# Specifies whether joins should be skipped for an association. If set to true, two or more queries
|
1228
1231
|
# will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
|
@@ -1251,7 +1254,8 @@ module ActiveRecord
|
|
1251
1254
|
# [+:inverse_of+]
|
1252
1255
|
# Specifies the name of the #belongs_to association on the associated object
|
1253
1256
|
# that is the inverse of this #has_many association.
|
1254
|
-
# See
|
1257
|
+
# See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
|
1258
|
+
# for more detail.
|
1255
1259
|
# [+:extend+]
|
1256
1260
|
# Specifies a module or array of modules that will be extended into the association object returned.
|
1257
1261
|
# Useful for defining methods on associations, especially when they should be shared between multiple
|
@@ -1300,10 +1304,12 @@ module ActiveRecord
|
|
1300
1304
|
Reflection.add_reflection self, name, reflection
|
1301
1305
|
end
|
1302
1306
|
|
1303
|
-
# Specifies a one-to-one association with another class. This method
|
1304
|
-
# if the other class contains the foreign key. If
|
1305
|
-
#
|
1306
|
-
#
|
1307
|
+
# Specifies a one-to-one association with another class. This method
|
1308
|
+
# should only be used if the other class contains the foreign key. If
|
1309
|
+
# the current class contains the foreign key, then you should use
|
1310
|
+
# #belongs_to instead. See {Is it a belongs_to or has_one
|
1311
|
+
# association?}[rdoc-ref:Associations::ClassMethods@Is+it+a+-23belongs_to+or+-23has_one+association-3F]
|
1312
|
+
# for more detail on when to use #has_one and when to use #belongs_to.
|
1307
1313
|
#
|
1308
1314
|
# The following methods for retrieval and query of a single associated object will be added:
|
1309
1315
|
#
|
@@ -1418,8 +1424,10 @@ module ActiveRecord
|
|
1418
1424
|
# If you are going to modify the association (rather than just read from it), then it is
|
1419
1425
|
# a good idea to set the <tt>:inverse_of</tt> option on the source association on the
|
1420
1426
|
# join model. This allows associated records to be built which will automatically create
|
1421
|
-
# the appropriate join model records when they are saved.
|
1422
|
-
#
|
1427
|
+
# the appropriate join model records when they are saved. See
|
1428
|
+
# {Association Join Models}[rdoc-ref:Associations::ClassMethods@Association+Join+Models]
|
1429
|
+
# and {Setting Inverses}[rdoc-ref:Associations::ClassMethods@Setting+Inverses] for
|
1430
|
+
# more detail.
|
1423
1431
|
# [+:disable_joins+]
|
1424
1432
|
# Specifies whether joins should be skipped for an association. If set to true, two or more queries
|
1425
1433
|
# will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
|
@@ -1457,7 +1465,8 @@ module ActiveRecord
|
|
1457
1465
|
# [+:inverse_of+]
|
1458
1466
|
# Specifies the name of the #belongs_to association on the associated object
|
1459
1467
|
# that is the inverse of this #has_one association.
|
1460
|
-
# See
|
1468
|
+
# See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
|
1469
|
+
# for more detail.
|
1461
1470
|
# [+:required+]
|
1462
1471
|
# When set to +true+, the association will also have its presence validated.
|
1463
1472
|
# This will validate the association itself, not the id. You can use
|
@@ -1491,10 +1500,12 @@ module ActiveRecord
|
|
1491
1500
|
Reflection.add_reflection self, name, reflection
|
1492
1501
|
end
|
1493
1502
|
|
1494
|
-
# Specifies a one-to-one association with another class. This method
|
1495
|
-
# if this class contains the foreign key. If the
|
1496
|
-
# then you should use #has_one
|
1497
|
-
#
|
1503
|
+
# Specifies a one-to-one association with another class. This method
|
1504
|
+
# should only be used if this class contains the foreign key. If the
|
1505
|
+
# other class contains the foreign key, then you should use #has_one
|
1506
|
+
# instead. See {Is it a belongs_to or has_one
|
1507
|
+
# association?}[rdoc-ref:Associations::ClassMethods@Is+it+a+-23belongs_to+or+-23has_one+association-3F]
|
1508
|
+
# for more detail on when to use #has_one and when to use #belongs_to.
|
1498
1509
|
#
|
1499
1510
|
# Methods will be added for retrieval and query for a single associated object, for which
|
1500
1511
|
# this object holds an id:
|
@@ -1636,7 +1647,8 @@ module ActiveRecord
|
|
1636
1647
|
# [+:inverse_of+]
|
1637
1648
|
# Specifies the name of the #has_one or #has_many association on the associated
|
1638
1649
|
# object that is the inverse of this #belongs_to association.
|
1639
|
-
# See
|
1650
|
+
# See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
|
1651
|
+
# for more detail.
|
1640
1652
|
# [+:optional+]
|
1641
1653
|
# When set to +true+, the association will not have its presence validated.
|
1642
1654
|
# [+:required+]
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "set"
|
4
|
-
|
5
3
|
module ActiveRecord
|
6
4
|
module AttributeMethods
|
7
5
|
# = Active Record Attribute Methods Primary Key
|
@@ -89,10 +87,9 @@ module ActiveRecord
|
|
89
87
|
@composite_primary_key
|
90
88
|
end
|
91
89
|
|
92
|
-
# Returns a quoted version of the primary key name
|
93
|
-
# SQL statements.
|
90
|
+
# Returns a quoted version of the primary key name.
|
94
91
|
def quoted_primary_key
|
95
|
-
|
92
|
+
adapter_class.quote_column_name(primary_key)
|
96
93
|
end
|
97
94
|
|
98
95
|
def reset_primary_key # :nodoc:
|
@@ -138,7 +135,6 @@ module ActiveRecord
|
|
138
135
|
elsif value
|
139
136
|
-value.to_s
|
140
137
|
end
|
141
|
-
@quoted_primary_key = nil
|
142
138
|
@attributes_builder = nil
|
143
139
|
end
|
144
140
|
|
@@ -148,7 +144,6 @@ module ActiveRecord
|
|
148
144
|
base.class_eval do
|
149
145
|
@primary_key = PRIMARY_KEY_NOT_SET
|
150
146
|
@composite_primary_key = false
|
151
|
-
@quoted_primary_key = nil
|
152
147
|
@attributes_builder = nil
|
153
148
|
end
|
154
149
|
end
|
@@ -28,7 +28,7 @@ module ActiveRecord
|
|
28
28
|
elsif value.respond_to?(:infinite?) && value.infinite?
|
29
29
|
value
|
30
30
|
else
|
31
|
-
|
31
|
+
map(super) { |v| cast(v) }
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -45,23 +45,13 @@ module ActiveRecord
|
|
45
45
|
elsif value.respond_to?(:infinite?) && value.infinite?
|
46
46
|
value
|
47
47
|
else
|
48
|
-
|
48
|
+
map(value) { |v| convert_time_to_time_zone(v) }
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
def set_time_zone_without_conversion(value)
|
53
53
|
::Time.zone.local_to_utc(value).try(:in_time_zone) if value
|
54
54
|
end
|
55
|
-
|
56
|
-
def map_avoiding_infinite_recursion(value)
|
57
|
-
map(value) do |v|
|
58
|
-
if value.equal?(v)
|
59
|
-
nil
|
60
|
-
else
|
61
|
-
yield(v)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
55
|
end
|
66
56
|
|
67
57
|
extend ActiveSupport::Concern
|
@@ -418,7 +418,7 @@ module ActiveRecord
|
|
418
418
|
|
419
419
|
def destroy # :nodoc:
|
420
420
|
@_destroy_callback_already_called ||= false
|
421
|
-
return if @_destroy_callback_already_called
|
421
|
+
return true if @_destroy_callback_already_called
|
422
422
|
@_destroy_callback_already_called = true
|
423
423
|
_run_destroy_callbacks { super }
|
424
424
|
rescue RecordNotDestroyed => e
|
@@ -183,6 +183,31 @@ module ActiveRecord
|
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
|
+
module ExecutorHooks # :nodoc:
|
187
|
+
class << self
|
188
|
+
def run
|
189
|
+
# noop
|
190
|
+
end
|
191
|
+
|
192
|
+
def complete(_)
|
193
|
+
ActiveRecord::Base.connection_handler.each_connection_pool do |pool|
|
194
|
+
if (connection = pool.active_connection?)
|
195
|
+
transaction = connection.current_transaction
|
196
|
+
if transaction.closed? || !transaction.joinable?
|
197
|
+
pool.release_connection
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class << self
|
206
|
+
def install_executor_hooks(executor = ActiveSupport::Executor)
|
207
|
+
executor.register_hook(ExecutorHooks)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
186
211
|
include MonitorMixin
|
187
212
|
prepend QueryCache::ConnectionPoolConfiguration
|
188
213
|
include ConnectionAdapters::AbstractPool
|
@@ -291,14 +316,6 @@ module ActiveRecord
|
|
291
316
|
connection_lease.sticky.nil?
|
292
317
|
end
|
293
318
|
|
294
|
-
def connection
|
295
|
-
ActiveRecord.deprecator.warn(<<~MSG)
|
296
|
-
ActiveRecord::ConnectionAdapters::ConnectionPool#connection is deprecated
|
297
|
-
and will be removed in Rails 8.0. Use #lease_connection instead.
|
298
|
-
MSG
|
299
|
-
lease_connection
|
300
|
-
end
|
301
|
-
|
302
319
|
def pin_connection!(lock_thread) # :nodoc:
|
303
320
|
@pinned_connection ||= (connection_lease&.connection || checkout)
|
304
321
|
@pinned_connections_depth += 1
|
@@ -332,6 +349,7 @@ module ActiveRecord
|
|
332
349
|
end
|
333
350
|
|
334
351
|
if @pinned_connection.nil?
|
352
|
+
connection.steal!
|
335
353
|
connection.lock_thread = nil
|
336
354
|
checkin(connection)
|
337
355
|
end
|
@@ -28,6 +28,7 @@ module ActiveRecord
|
|
28
28
|
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
|
29
29
|
sql << o.check_constraint_adds.map { |con| visit_AddCheckConstraint con }.join(" ")
|
30
30
|
sql << o.check_constraint_drops.map { |con| visit_DropCheckConstraint con }.join(" ")
|
31
|
+
sql << o.constraint_drops.map { |con| visit_DropConstraint con }.join(" ")
|
31
32
|
end
|
32
33
|
|
33
34
|
def visit_ColumnDefinition(o)
|
@@ -96,9 +97,11 @@ module ActiveRecord
|
|
96
97
|
"ADD #{accept(o)}"
|
97
98
|
end
|
98
99
|
|
99
|
-
def
|
100
|
+
def visit_DropConstraint(name)
|
100
101
|
"DROP CONSTRAINT #{quote_column_name(name)}"
|
101
102
|
end
|
103
|
+
alias :visit_DropForeignKey :visit_DropConstraint
|
104
|
+
alias :visit_DropCheckConstraint :visit_DropConstraint
|
102
105
|
|
103
106
|
def visit_CreateIndexDefinition(o)
|
104
107
|
index = o.index
|
@@ -127,10 +130,6 @@ module ActiveRecord
|
|
127
130
|
"ADD #{accept(o)}"
|
128
131
|
end
|
129
132
|
|
130
|
-
def visit_DropCheckConstraint(name)
|
131
|
-
"DROP CONSTRAINT #{quote_column_name(name)}"
|
132
|
-
end
|
133
|
-
|
134
133
|
def quoted_columns(o)
|
135
134
|
String === o.columns ? o.columns : quoted_columns_for_index(o.columns, o.column_options)
|
136
135
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
3
|
module ActiveRecord
|
5
4
|
module ConnectionAdapters # :nodoc:
|
6
5
|
# Abstract representation of an index definition on a table. Instances of
|
@@ -622,6 +621,7 @@ module ActiveRecord
|
|
622
621
|
attr_reader :adds
|
623
622
|
attr_reader :foreign_key_adds, :foreign_key_drops
|
624
623
|
attr_reader :check_constraint_adds, :check_constraint_drops
|
624
|
+
attr_reader :constraint_drops
|
625
625
|
|
626
626
|
def initialize(td)
|
627
627
|
@td = td
|
@@ -630,6 +630,7 @@ module ActiveRecord
|
|
630
630
|
@foreign_key_drops = []
|
631
631
|
@check_constraint_adds = []
|
632
632
|
@check_constraint_drops = []
|
633
|
+
@constraint_drops = []
|
633
634
|
end
|
634
635
|
|
635
636
|
def name; @td.name; end
|
@@ -650,6 +651,10 @@ module ActiveRecord
|
|
650
651
|
@check_constraint_drops << constraint_name
|
651
652
|
end
|
652
653
|
|
654
|
+
def drop_constraint(constraint_name)
|
655
|
+
@constraint_drops << constraint_name
|
656
|
+
end
|
657
|
+
|
653
658
|
def add_column(name, type, **options)
|
654
659
|
name = name.to_s
|
655
660
|
type = type.to_sym
|
@@ -693,7 +693,7 @@ module ActiveRecord
|
|
693
693
|
#
|
694
694
|
# If the options provided include an +if_exists+ key, it will be used to check if the
|
695
695
|
# column does not exist. This will silently ignore the migration rather than raising
|
696
|
-
# if the column was already
|
696
|
+
# if the column was already removed.
|
697
697
|
#
|
698
698
|
# remove_column(:suppliers, :qualification, if_exists: true)
|
699
699
|
def remove_column(table_name, column_name, type = nil, **options)
|
@@ -1334,7 +1334,6 @@ module ActiveRecord
|
|
1334
1334
|
execute schema_creation.accept(at)
|
1335
1335
|
end
|
1336
1336
|
|
1337
|
-
|
1338
1337
|
# Checks to see if a check constraint exists on a table for a given check constraint definition.
|
1339
1338
|
#
|
1340
1339
|
# check_constraint_exists?(:products, name: "price_check")
|
@@ -1346,6 +1345,13 @@ module ActiveRecord
|
|
1346
1345
|
check_constraint_for(table_name, **options).present?
|
1347
1346
|
end
|
1348
1347
|
|
1348
|
+
def remove_constraint(table_name, constraint_name) # :nodoc:
|
1349
|
+
at = create_alter_table(table_name)
|
1350
|
+
at.drop_constraint(constraint_name)
|
1351
|
+
|
1352
|
+
execute schema_creation.accept(at)
|
1353
|
+
end
|
1354
|
+
|
1349
1355
|
def dump_schema_information # :nodoc:
|
1350
1356
|
versions = pool.schema_migration.versions
|
1351
1357
|
insert_versions_sql(versions) if versions.any?
|
@@ -98,7 +98,7 @@ module ActiveRecord
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def supports_index_sort_order?
|
101
|
-
|
101
|
+
mariadb? ? database_version >= "10.8.1" : database_version >= "8.0.1"
|
102
102
|
end
|
103
103
|
|
104
104
|
def supports_expression_index?
|
@@ -628,7 +628,7 @@ module ActiveRecord
|
|
628
628
|
end
|
629
629
|
|
630
630
|
def build_insert_sql(insert) # :nodoc:
|
631
|
-
no_op_column = quote_column_name(insert.keys.first)
|
631
|
+
no_op_column = quote_column_name(insert.keys.first) if insert.keys.first
|
632
632
|
|
633
633
|
# MySQL 8.0.19 replaces `VALUES(<expression>)` clauses with row and column alias names, see https://dev.mysql.com/worklog/task/?id=6312 .
|
634
634
|
# then MySQL 8.0.20 deprecates the `VALUES(<expression>)` see https://dev.mysql.com/worklog/task/?id=13325 .
|
@@ -637,7 +637,9 @@ module ActiveRecord
|
|
637
637
|
sql = +"INSERT #{insert.into} #{insert.values_list} AS #{values_alias}"
|
638
638
|
|
639
639
|
if insert.skip_duplicates?
|
640
|
-
|
640
|
+
if no_op_column
|
641
|
+
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{values_alias}.#{no_op_column}"
|
642
|
+
end
|
641
643
|
elsif insert.update_duplicates?
|
642
644
|
if insert.raw_update_sql?
|
643
645
|
sql = +"INSERT #{insert.into} #{insert.values_list} ON DUPLICATE KEY UPDATE #{insert.raw_update_sql}"
|
@@ -651,7 +653,9 @@ module ActiveRecord
|
|
651
653
|
sql = +"INSERT #{insert.into} #{insert.values_list}"
|
652
654
|
|
653
655
|
if insert.skip_duplicates?
|
654
|
-
|
656
|
+
if no_op_column
|
657
|
+
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
|
658
|
+
end
|
655
659
|
elsif insert.update_duplicates?
|
656
660
|
sql << " ON DUPLICATE KEY UPDATE "
|
657
661
|
if insert.raw_update_sql?
|
@@ -45,12 +45,10 @@ Rails needs superuser privileges to disable referential integrity.
|
|
45
45
|
BEGIN
|
46
46
|
FOR r IN (
|
47
47
|
SELECT FORMAT(
|
48
|
-
'UPDATE pg_constraint SET convalidated=false WHERE conname = ''%I'' AND connamespace::regnamespace = ''%I''::regnamespace; ALTER TABLE %I.%I VALIDATE CONSTRAINT %I;',
|
48
|
+
'UPDATE pg_catalog.pg_constraint SET convalidated=false WHERE conname = ''%1$I'' AND connamespace::regnamespace = ''%2$I''::regnamespace; ALTER TABLE %2$I.%3$I VALIDATE CONSTRAINT %1$I;',
|
49
49
|
constraint_name,
|
50
50
|
table_schema,
|
51
|
-
|
52
|
-
table_name,
|
53
|
-
constraint_name
|
51
|
+
table_name
|
54
52
|
) AS constraint_check
|
55
53
|
FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY'
|
56
54
|
)
|
@@ -11,9 +11,7 @@ module ActiveRecord
|
|
11
11
|
sql = super
|
12
12
|
sql << o.constraint_validations.map { |fk| visit_ValidateConstraint fk }.join(" ")
|
13
13
|
sql << o.exclusion_constraint_adds.map { |con| visit_AddExclusionConstraint con }.join(" ")
|
14
|
-
sql << o.exclusion_constraint_drops.map { |con| visit_DropExclusionConstraint con }.join(" ")
|
15
14
|
sql << o.unique_constraint_adds.map { |con| visit_AddUniqueConstraint con }.join(" ")
|
16
|
-
sql << o.unique_constraint_drops.map { |con| visit_DropUniqueConstraint con }.join(" ")
|
17
15
|
end
|
18
16
|
|
19
17
|
def visit_AddForeignKey(o)
|
@@ -54,6 +52,7 @@ module ActiveRecord
|
|
54
52
|
sql = ["CONSTRAINT"]
|
55
53
|
sql << quote_column_name(o.name)
|
56
54
|
sql << "UNIQUE"
|
55
|
+
sql << "NULLS NOT DISTINCT" if supports_nulls_not_distinct? && o.nulls_not_distinct
|
57
56
|
|
58
57
|
if o.using_index
|
59
58
|
sql << "USING INDEX #{quote_column_name(o.using_index)}"
|
@@ -72,18 +71,10 @@ module ActiveRecord
|
|
72
71
|
"ADD #{accept(o)}"
|
73
72
|
end
|
74
73
|
|
75
|
-
def visit_DropExclusionConstraint(name)
|
76
|
-
"DROP CONSTRAINT #{quote_column_name(name)}"
|
77
|
-
end
|
78
|
-
|
79
74
|
def visit_AddUniqueConstraint(o)
|
80
75
|
"ADD #{accept(o)}"
|
81
76
|
end
|
82
77
|
|
83
|
-
def visit_DropUniqueConstraint(name)
|
84
|
-
"DROP CONSTRAINT #{quote_column_name(name)}"
|
85
|
-
end
|
86
|
-
|
87
78
|
def visit_ChangeColumnDefinition(o)
|
88
79
|
column = o.column
|
89
80
|
column.sql_type = type_to_sql(column.type, **column.options)
|