activerecord 8.0.0.beta1 → 8.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -0
  3. data/lib/active_record/associations/has_many_through_association.rb +7 -1
  4. data/lib/active_record/attribute_methods/primary_key.rb +2 -7
  5. data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -12
  6. data/lib/active_record/callbacks.rb +1 -1
  7. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +26 -8
  8. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
  9. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +6 -1
  10. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -2
  11. data/lib/active_record/connection_adapters/abstract_adapter.rb +0 -1
  12. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +8 -4
  13. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  14. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
  15. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +0 -10
  16. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -11
  17. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +1 -1
  18. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +4 -8
  19. data/lib/active_record/connection_adapters/postgresql_adapter.rb +8 -8
  20. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +1 -1
  21. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +0 -2
  22. data/lib/active_record/connection_adapters.rb +0 -56
  23. data/lib/active_record/core.rb +14 -11
  24. data/lib/active_record/enum.rb +54 -72
  25. data/lib/active_record/fixtures.rb +0 -1
  26. data/lib/active_record/gem_version.rb +1 -1
  27. data/lib/active_record/locking/optimistic.rb +1 -1
  28. data/lib/active_record/log_subscriber.rb +5 -11
  29. data/lib/active_record/marshalling.rb +4 -1
  30. data/lib/active_record/migration.rb +0 -5
  31. data/lib/active_record/model_schema.rb +2 -3
  32. data/lib/active_record/query_cache.rb +0 -4
  33. data/lib/active_record/query_logs.rb +5 -11
  34. data/lib/active_record/querying.rb +2 -2
  35. data/lib/active_record/railtie.rb +1 -24
  36. data/lib/active_record/railties/databases.rake +1 -1
  37. data/lib/active_record/reflection.rb +14 -19
  38. data/lib/active_record/relation/calculations.rb +24 -28
  39. data/lib/active_record/relation/predicate_builder.rb +8 -0
  40. data/lib/active_record/relation/query_methods.rb +66 -36
  41. data/lib/active_record/relation.rb +8 -1
  42. data/lib/active_record/result.rb +10 -9
  43. data/lib/active_record/table_metadata.rb +1 -3
  44. data/lib/active_record/tasks/database_tasks.rb +4 -31
  45. data/lib/active_record/testing/query_assertions.rb +2 -2
  46. data/lib/active_record.rb +0 -45
  47. data/lib/arel/table.rb +3 -7
  48. data/lib/arel/visitors/sqlite.rb +25 -0
  49. metadata +9 -10
  50. 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: 1e4bbfe90a91599557f1804b34ccb34ca5db162d8ffb8c61a7bf87c3db518b16
4
- data.tar.gz: a84a3f17fe43e75642b2d293df3916062ef9fcc77cc6485f4b8e9183bb90f234
3
+ metadata.gz: c87db8720964fea39e42e8eb013edb1fc3fd47e5964e5d6d6fdbe46295766f02
4
+ data.tar.gz: c4bf7718e51c5accaad971f57faae94312d5cf81f5cfc4e58e8d4fe138027964
5
5
  SHA512:
6
- metadata.gz: 8e0c9d489c0baade86104d8f1f2be0595c1eb3b2a9f1f02328cc3de9d941c8d46302daf74547b2a2c508bd03f418312b0557e1274b14ada1d6bb2f2ae3fc17d5
7
- data.tar.gz: '04599d4f24baede9df806c5b0abc1627bb468f365581acd71ee30ef058faeadd3de22074f4752727633df01b8578258cffdab7e709a7e849e332af2de08b3f2d'
6
+ metadata.gz: 81389502abf74508e9eb58bcf7c91088bf4c44b858bd121128e801fee6a3a58309e0f455444bbe43faea18f7fe458610ab04ad8286d8e9faebf06ba5198bcba9
7
+ data.tar.gz: 85de6837aff3ae8a24f177c53e2f3912c6660493bbb4138f75223a2dcb813c7f796444bd4d0196f606d16ce1bde6d3352d30d54279c72bb99910eee7f4183924
data/CHANGELOG.md CHANGED
@@ -1,3 +1,70 @@
1
+ ## Rails 8.0.0.rc1 (October 19, 2024) ##
2
+
3
+ * Remove deprecated support to setting `ENV["SCHEMA_CACHE"]`.
4
+
5
+ *Rafael Mendonça França*
6
+
7
+ * Remove deprecated support to passing a database name to `cache_dump_filename`.
8
+
9
+ *Rafael Mendonça França*
10
+
11
+ * Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection`.
12
+
13
+ *Rafael Mendonça França*
14
+
15
+ * Remove deprecated `config.active_record.sqlite3_deprecated_warning`.
16
+
17
+ *Rafael Mendonça França*
18
+
19
+ * Remove deprecated `config.active_record.warn_on_records_fetched_greater_than`.
20
+
21
+ *Rafael Mendonça França*
22
+
23
+ * Remove deprecated support for defining `enum` with keyword arguments.
24
+
25
+ *Rafael Mendonça França*
26
+
27
+ * Remove deprecated support to finding database adapters that aren't registered to Active Record.
28
+
29
+ *Rafael Mendonça França*
30
+
31
+ * Remove deprecated `config.active_record.allow_deprecated_singular_associations_name`.
32
+
33
+ *Rafael Mendonça França*
34
+
35
+ * Remove deprecated `config.active_record.commit_transaction_on_non_local_return`.
36
+
37
+ *Rafael Mendonça França*
38
+
39
+ * Fix incorrect SQL query when passing an empty hash to `ActiveRecord::Base.insert`.
40
+
41
+ *David Stosik*
42
+
43
+ * Allow to save records with polymorphic join tables that have `inverse_of`
44
+ specified.
45
+
46
+ *Markus Doits*
47
+
48
+ * Fix association scopes applying on the incorrect join when using a polymorphic `has_many through:`.
49
+
50
+ *Joshua Young*
51
+
52
+ * Allow `ActiveRecord::Base#pluck` to accept hash arguments with symbol and string values.
53
+
54
+ ```ruby
55
+ Post.joins(:comments).pluck(:id, comments: :id)
56
+ Post.joins(:comments).pluck("id", "comments" => "id")
57
+ ```
58
+
59
+ *Joshua Young*
60
+
61
+ * Make Float distinguish between `float4` and `float8` in PostgreSQL.
62
+
63
+ Fixes #52742
64
+
65
+ *Ryota Kitazawa*, *Takayuki Nagatomi*
66
+
67
+
1
68
  ## Rails 8.0.0.beta1 (September 26, 2024) ##
2
69
 
3
70
  * Allow `drop_table` to accept an array of table names.
@@ -93,7 +93,13 @@ module ActiveRecord
93
93
  @through_scope = scope
94
94
  record = super
95
95
 
96
- inverse = source_reflection.inverse_of
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)
@@ -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, used to construct
93
- # SQL statements.
90
+ # Returns a quoted version of the primary key name.
94
91
  def quoted_primary_key
95
- @quoted_primary_key ||= adapter_class.quote_column_name(primary_key)
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
- map_avoiding_infinite_recursion(super) { |v| cast(v) }
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
- map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
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 visit_DropForeignKey(name)
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 used.
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?
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
4
3
  require "active_record/connection_adapters/sql_type_metadata"
5
4
  require "active_record/connection_adapters/abstract/schema_dumper"
6
5
  require "active_record/connection_adapters/abstract/schema_creation"
@@ -98,7 +98,7 @@ module ActiveRecord
98
98
  end
99
99
 
100
100
  def supports_index_sort_order?
101
- !mariadb? && database_version >= "8.0.1"
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
- sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{values_alias}.#{no_op_column}"
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
- sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
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?
@@ -65,7 +65,7 @@ module ActiveRecord
65
65
  end
66
66
 
67
67
  def map(value, &block)
68
- value.map { |v| subtype.map(v, &block) }
68
+ value.is_a?(::Array) ? value.map(&block) : subtype.map(value, &block)
69
69
  end
70
70
 
71
71
  def changed_in_place?(raw_old_value, new_value)
@@ -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
- table_schema,
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)
@@ -72,18 +70,10 @@ module ActiveRecord
72
70
  "ADD #{accept(o)}"
73
71
  end
74
72
 
75
- def visit_DropExclusionConstraint(name)
76
- "DROP CONSTRAINT #{quote_column_name(name)}"
77
- end
78
-
79
73
  def visit_AddUniqueConstraint(o)
80
74
  "ADD #{accept(o)}"
81
75
  end
82
76
 
83
- def visit_DropUniqueConstraint(name)
84
- "DROP CONSTRAINT #{quote_column_name(name)}"
85
- end
86
-
87
77
  def visit_ChangeColumnDefinition(o)
88
78
  column = o.column
89
79
  column.sql_type = type_to_sql(column.type, **column.options)
@@ -356,15 +356,13 @@ module ActiveRecord
356
356
 
357
357
  # = Active Record PostgreSQL Adapter Alter \Table
358
358
  class AlterTable < ActiveRecord::ConnectionAdapters::AlterTable
359
- attr_reader :constraint_validations, :exclusion_constraint_adds, :exclusion_constraint_drops, :unique_constraint_adds, :unique_constraint_drops
359
+ attr_reader :constraint_validations, :exclusion_constraint_adds, :unique_constraint_adds
360
360
 
361
361
  def initialize(td)
362
362
  super
363
363
  @constraint_validations = []
364
364
  @exclusion_constraint_adds = []
365
- @exclusion_constraint_drops = []
366
365
  @unique_constraint_adds = []
367
- @unique_constraint_drops = []
368
366
  end
369
367
 
370
368
  def validate_constraint(name)
@@ -375,17 +373,9 @@ module ActiveRecord
375
373
  @exclusion_constraint_adds << @td.new_exclusion_constraint_definition(expression, options)
376
374
  end
377
375
 
378
- def drop_exclusion_constraint(constraint_name)
379
- @exclusion_constraint_drops << constraint_name
380
- end
381
-
382
376
  def add_unique_constraint(column_name, options)
383
377
  @unique_constraint_adds << @td.new_unique_constraint_definition(column_name, options)
384
378
  end
385
-
386
- def drop_unique_constraint(unique_constraint_name)
387
- @unique_constraint_drops << unique_constraint_name
388
- end
389
379
  end
390
380
  end
391
381
  end
@@ -91,7 +91,7 @@ module ActiveRecord
91
91
  spec = { type: schema_type(column).inspect }.merge!(spec)
92
92
  end
93
93
 
94
- spec[:enum_type] = "\"#{column.sql_type}\"" if column.enum?
94
+ spec[:enum_type] = column.sql_type.inspect if column.enum?
95
95
 
96
96
  spec
97
97
  end
@@ -299,6 +299,8 @@ module ActiveRecord
299
299
 
300
300
  # Returns the sequence name for a table's primary key or some other specified key.
301
301
  def default_sequence_name(table_name, pk = "id") # :nodoc:
302
+ return nil if pk.is_a?(Array)
303
+
302
304
  result = serial_sequence(table_name, pk)
303
305
  return nil unless result
304
306
  Utils.extract_schema_qualified_name(result).to_s
@@ -764,10 +766,7 @@ module ActiveRecord
764
766
  def remove_exclusion_constraint(table_name, expression = nil, **options)
765
767
  excl_name_to_delete = exclusion_constraint_for!(table_name, expression: expression, **options).name
766
768
 
767
- at = create_alter_table(table_name)
768
- at.drop_exclusion_constraint(excl_name_to_delete)
769
-
770
- execute schema_creation.accept(at)
769
+ remove_constraint(table_name, excl_name_to_delete)
771
770
  end
772
771
 
773
772
  # Adds a new unique constraint to the table.
@@ -819,10 +818,7 @@ module ActiveRecord
819
818
  def remove_unique_constraint(table_name, column_name = nil, **options)
820
819
  unique_name_to_delete = unique_constraint_for!(table_name, column: column_name, **options).name
821
820
 
822
- at = create_alter_table(table_name)
823
- at.drop_unique_constraint(unique_name_to_delete)
824
-
825
- execute schema_creation.accept(at)
821
+ remove_constraint(table_name, unique_name_to_delete)
826
822
  end
827
823
 
828
824
  # Maps logical Rails types to PostgreSQL-specific data types.
@@ -576,9 +576,9 @@ module ActiveRecord
576
576
 
577
577
  # Rename an existing enum type to something else.
578
578
  def rename_enum(name, **options)
579
- to = options.fetch(:to) { raise ArgumentError, ":to is required" }
579
+ new_name = options.fetch(:to) { raise ArgumentError, ":to is required" }
580
580
 
581
- exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{to}").tap { reload_type_map }
581
+ exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}").tap { reload_type_map }
582
582
  end
583
583
 
584
584
  # Add enum value to an existing enum type.
@@ -586,14 +586,14 @@ module ActiveRecord
586
586
  before, after = options.values_at(:before, :after)
587
587
  sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE"
588
588
  sql << " IF NOT EXISTS" if options[:if_not_exists]
589
- sql << " '#{value}'"
589
+ sql << " #{quote(value)}"
590
590
 
591
591
  if before && after
592
592
  raise ArgumentError, "Cannot have both :before and :after at the same time"
593
593
  elsif before
594
- sql << " BEFORE '#{before}'"
594
+ sql << " BEFORE #{quote(before)}"
595
595
  elsif after
596
- sql << " AFTER '#{after}'"
596
+ sql << " AFTER #{quote(after)}"
597
597
  end
598
598
 
599
599
  execute(sql).tap { reload_type_map }
@@ -608,7 +608,7 @@ module ActiveRecord
608
608
  from = options.fetch(:from) { raise ArgumentError, ":from is required" }
609
609
  to = options.fetch(:to) { raise ArgumentError, ":to is required" }
610
610
 
611
- execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE '#{from}' TO '#{to}'").tap {
611
+ execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE #{quote(from)} TO #{quote(to)}").tap {
612
612
  reload_type_map
613
613
  }
614
614
  end
@@ -671,8 +671,8 @@ module ActiveRecord
671
671
  m.register_type "int4", Type::Integer.new(limit: 4)
672
672
  m.register_type "int8", Type::Integer.new(limit: 8)
673
673
  m.register_type "oid", OID::Oid.new
674
- m.register_type "float4", Type::Float.new
675
- m.alias_type "float8", "float4"
674
+ m.register_type "float4", Type::Float.new(limit: 24)
675
+ m.register_type "float8", Type::Float.new
676
676
  m.register_type "text", Type::Text.new
677
677
  register_class_with_limit m, "varchar", Type::String
678
678
  m.alias_type "char", "varchar"
@@ -68,7 +68,7 @@ module ActiveRecord
68
68
  raise StandardError, "You need to enable the shared-cache mode in SQLite mode before attempting to change the transaction isolation level" unless shared_cache?
69
69
  end
70
70
 
71
- internal_execute("BEGIN #{mode} TRANSACTION", allow_retry: true, materialize_transactions: false)
71
+ internal_execute("BEGIN #{mode} TRANSACTION", "TRANSACTION", allow_retry: true, materialize_transactions: false)
72
72
  if isolation
73
73
  @previous_read_uncommitted = query_value("PRAGMA read_uncommitted")
74
74
  internal_execute("PRAGMA read_uncommitted=ON", "TRANSACTION", allow_retry: true, materialize_transactions: false)
@@ -725,8 +725,6 @@ module ActiveRecord
725
725
  end
726
726
 
727
727
  basic_structure.map do |column|
728
- column = column.to_h
729
-
730
728
  column_name = column["name"]
731
729
 
732
730
  if collation_hash.has_key? column_name
@@ -31,62 +31,6 @@ module ActiveRecord
31
31
  class_name, path_to_adapter = @adapters[adapter_name.to_s]
32
32
 
33
33
  unless class_name
34
- # To provide better error messages for adapters expecting the pre-7.2 adapter registration API, we attempt
35
- # to load the adapter file from the old location which was required by convention, and then raise an error
36
- # describing how to upgrade the adapter to the new API.
37
- legacy_adapter_path = "active_record/connection_adapters/#{adapter_name}_adapter"
38
- legacy_adapter_connection_method_name = "#{adapter_name}_connection".to_sym
39
-
40
- begin
41
- require legacy_adapter_path
42
- # If we reach here it means we found the found a file that may be the legacy adapter and should raise.
43
- if ActiveRecord::ConnectionHandling.method_defined?(legacy_adapter_connection_method_name)
44
- # If we find the connection method then we care certain it is a legacy adapter.
45
- deprecation_message = <<~MSG.squish
46
- Database configuration specifies '#{adapter_name}' adapter but that adapter has not been registered.
47
- Rails 7.2 has changed the way Active Record database adapters are loaded. The adapter needs to be
48
- updated to register itself rather than being loaded by convention.
49
- Ensure that the adapter in the Gemfile is at the latest version. If it is, then the adapter may need to
50
- be modified.
51
- See:
52
- https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html#method-c-register
53
- MSG
54
-
55
- exception_message = <<~MSG.squish
56
- Database configuration specifies '#{adapter_name}' adapter but that adapter has not been registered.
57
- Ensure that the adapter in the Gemfile is at the latest version. If it is, then the adapter may need to
58
- be modified.
59
- MSG
60
- else
61
- # If we do not find the connection method we are much less certain it is a legacy adapter. Even though the
62
- # file exists in the location defined by convenntion, it does not necessarily mean that file is supposed
63
- # to define the adapter the legacy way. So raise an error that explains both possibilities.
64
- deprecation_message = <<~MSG.squish
65
- Database configuration specifies nonexistent '#{adapter_name}' adapter.
66
- Available adapters are: #{@adapters.keys.sort.join(", ")}.
67
- Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary
68
- adapter gem to your Gemfile if it's not in the list of available adapters.
69
- Rails 7.2 has changed the way Active Record database adapters are loaded. Ensure that the adapter in
70
- the Gemfile is at the latest version. If it is up to date, the adapter may need to be modified.
71
- See:
72
- https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html#method-c-register
73
- MSG
74
-
75
- exception_message = <<~MSG.squish
76
- Database configuration specifies nonexistent '#{adapter_name}' adapter.
77
- Available adapters are: #{@adapters.keys.sort.join(", ")}.
78
- Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary
79
- adapter gem to your Gemfile and that it is at its latest version. If it is up to date, the adapter may
80
- need to be modified.
81
- MSG
82
- end
83
-
84
- ActiveRecord.deprecator.warn(deprecation_message)
85
- raise AdapterNotFound, exception_message
86
- rescue LoadError => error
87
- # The adapter was not found in the legacy location so fall through to the error handling for a missing adapter.
88
- end
89
-
90
34
  raise AdapterNotFound, <<~MSG.squish
91
35
  Database configuration specifies nonexistent '#{adapter_name}' adapter.
92
36
  Available adapters are: #{@adapters.keys.sort.join(", ")}.