Skip to content

Commit 76448a0

Browse files
committed
Freeze database conversion types
I want to start moving Rails to be more Ractor friendly, and in support of that goal I want to start moving some of our long lived "global" objects to be frozen. `_default_attributes` keeps references to the database types, and it's my first target for Ractor shareability.
1 parent a091ea2 commit 76448a0

File tree

6 files changed

+27
-8
lines changed

6 files changed

+27
-8
lines changed

activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,12 +728,12 @@ def initialize_type_map(m)
728728
m.alias_type %r(bit)i, "binary"
729729
end
730730

731-
def register_integer_type(mapping, key, **options)
731+
def register_integer_type(mapping, key, limit:)
732732
mapping.register_type(key) do |sql_type|
733733
if /\bunsigned\b/.match?(sql_type)
734-
Type::UnsignedInteger.new(**options)
734+
Type::UnsignedInteger.new(limit: limit)
735735
else
736-
Type::Integer.new(**options)
736+
Type::Integer.new(limit: limit)
737737
end
738738
end
739739
end

activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ def initialize(subtype, delimiter = ",")
1616
@subtype = subtype
1717
@delimiter = delimiter
1818

19-
@pg_encoder = PG::TextEncoder::Array.new name: "#{type}[]", delimiter: delimiter
20-
@pg_decoder = PG::TextDecoder::Array.new name: "#{type}[]", delimiter: delimiter
19+
@pg_encoder = PG::TextEncoder::Array.new(name: "#{type}[]".freeze, delimiter: delimiter).freeze
20+
@pg_decoder = PG::TextDecoder::Array.new(name: "#{type}[]".freeze, delimiter: delimiter).freeze
2121
end
2222

2323
def deserialize(value)

activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def register_enum_type(row)
6868

6969
def register_array_type(row)
7070
register_with_subtype(row["oid"], row["typelem"].to_i) do |subtype|
71-
OID::Array.new(subtype, row["typdelim"])
71+
OID::Array.new(subtype, row["typdelim"].freeze)
7272
end
7373
end
7474

activerecord/lib/active_record/type/hash_lookup_type_map.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def register_type(key, value = nil, &block)
2626
if block
2727
@mapping[key] = block
2828
else
29+
value.freeze
2930
@mapping[key] = proc { value }
3031
end
3132
@cache.clear
@@ -50,7 +51,7 @@ def keys
5051

5152
private
5253
def perform_fetch(type, *args, &block)
53-
@mapping.fetch(type, block).call(type, *args)
54+
@mapping.fetch(type, block).call(type, *args).freeze
5455
end
5556
end
5657
end

activerecord/lib/active_record/type/type_map.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def perform_fetch(lookup_key, &block)
4646
end
4747

4848
if matching_pair
49-
matching_pair.last.call(lookup_key)
49+
matching_pair.last.call(lookup_key).freeze
5050
elsif @parent
5151
@parent.perform_fetch(lookup_key, &block)
5252
else

activerecord/test/cases/adapter_test.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ def setup
1414
@connection.materialize_transactions
1515
end
1616

17+
def test_type_map_is_ractor_shareable
18+
# This is testing internals. Please feel free to remove this test
19+
# or change it when internals change. The point is to make sure
20+
# the type map is Ractor shareable.
21+
@connection.tables.each do |table|
22+
@connection.columns(table).each do |column|
23+
assert_ractor_shareable @connection.lookup_cast_type_from_column(column)
24+
end
25+
end
26+
end
27+
1728
##
1829
# PostgreSQL does not support null bytes in strings
1930
unless current_adapter?(:PostgreSQLAdapter) ||
@@ -338,6 +349,13 @@ def test_select_methods_passing_a_relation
338349

339350
assert_match(/ActiveRecord::ConnectionAdapters::\w+:0x[\da-f]+ env_name="\w+" role=:writing>/, output)
340351
end
352+
353+
private
354+
def assert_ractor_shareable(obj)
355+
# rubocop:disable Minitest/AssertWithExpectedArgument
356+
assert(Ractor.shareable?(obj), -> { "Expected #{obj} to be shareable, but it wasn't" })
357+
# rubocop:enable Minitest/AssertWithExpectedArgument
358+
end
341359
end
342360

343361
class AdapterForeignKeyTest < ActiveRecord::TestCase

0 commit comments

Comments
 (0)