activerecord 8.0.0.beta1 → 8.0.0.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.
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(", ")}.