Skip to content

Commit fc906ea

Browse files
authored
Merge pull request rails#54348 from rails/rm-schema-dump-support
Make the schema cache forward compatible with the changes in Column
2 parents b8b00ef + 5179851 commit fc906ea

File tree

13 files changed

+211
-32
lines changed

13 files changed

+211
-32
lines changed

activerecord/lib/active_record/attributes.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,11 @@ def define_attribute(
241241

242242
def _default_attributes # :nodoc:
243243
@default_attributes ||= begin
244-
attributes_hash = columns_hash.transform_values do |column|
245-
ActiveModel::Attribute.from_database(column.name, column.default, type_for_column(column))
244+
# TODO: Remove the need for a connection after we release 8.1.
245+
attributes_hash = with_connection do |connection|
246+
columns_hash.transform_values do |column|
247+
ActiveModel::Attribute.from_database(column.name, column.default, type_for_column(connection, column))
248+
end
246249
end
247250

248251
attribute_set = ActiveModel::AttributeSet.new(attributes_hash)
@@ -297,7 +300,8 @@ def resolve_type_name(name, **options)
297300
Type.lookup(name, **options, adapter: Type.adapter_name_from(self))
298301
end
299302

300-
def type_for_column(column)
303+
def type_for_column(connection, column)
304+
# TODO: Remove the need for a connection after we release 8.1.
301305
hook_attribute_type(column.name, super)
302306
end
303307
end

activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,8 @@ def build_fixture_sql(fixtures, table_name)
624624

625625
columns.map do |name, column|
626626
if fixture.key?(name)
627-
with_yaml_fallback(column.cast_type.serialize(fixture[name]))
627+
# TODO: Remove fetch_cast_type and the need for connection after we release 8.1.
628+
with_yaml_fallback(column.fetch_cast_type(self).serialize(fixture[name]))
628629
else
629630
default_insert_value(column)
630631
end

activerecord/lib/active_record/connection_adapters/abstract/quoting.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ def quote_default_expression(value, column) # :nodoc:
146146
if value.is_a?(Proc)
147147
value.call
148148
else
149-
cast_type = column.respond_to?(:cast_type) ? column.cast_type : lookup_cast_type(column.sql_type)
149+
# TODO: Remove fetch_cast_type and the need for connection after we release 8.1.
150+
cast_type = column.respond_to?(:fetch_cast_type) ? column.fetch_cast_type(self) : lookup_cast_type(column.sql_type)
150151
value = cast_type.serialize(value)
151152
quote(value)
152153
end
@@ -209,6 +210,11 @@ def sanitize_as_sql_comment(value) # :nodoc:
209210
comment
210211
end
211212

213+
def lookup_cast_type(sql_type) # :nodoc:
214+
# TODO: Make this method private after we release 8.1.
215+
type_map.lookup(sql_type)
216+
end
217+
212218
private
213219
def type_casted_binds(binds)
214220
binds&.map do |value|
@@ -219,12 +225,6 @@ def type_casted_binds(binds)
219225
end
220226
end
221227
end
222-
223-
# In some adapters this executes queries; it should not be used in any
224-
# hot paths. Instead prefer using `column.cast_type`.
225-
def lookup_cast_type(sql_type)
226-
type_map.lookup(sql_type)
227-
end
228228
end
229229
end
230230
end

activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ def schema_scale(column)
8585

8686
def schema_default(column)
8787
return unless column.has_default?
88-
type = column.cast_type
88+
# TODO: Remove fetch_cast_type and the need for connection after we release 8.1.
89+
type = column.fetch_cast_type(@connection)
8990
default = type.deserialize(column.default)
9091
if default.nil?
9192
schema_expression(column)

activerecord/lib/active_record/connection_adapters/column.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module ConnectionAdapters
77
class Column
88
include Deduplicable
99

10-
attr_reader :name, :cast_type, :default, :sql_type_metadata, :null, :default_function, :collation, :comment
10+
attr_reader :name, :default, :sql_type_metadata, :null, :default_function, :collation, :comment
1111

1212
delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
1313

@@ -28,6 +28,11 @@ def initialize(name, cast_type, default, sql_type_metadata = nil, null = true, d
2828
@comment = comment
2929
end
3030

31+
def fetch_cast_type(connection) # :nodoc:
32+
# TODO: Remove fetch_cast_type and the need for connection after we release 8.1.
33+
@cast_type || connection.lookup_cast_type(sql_type)
34+
end
35+
3136
def has_default?
3237
!default.nil? || default_function
3338
end
@@ -105,6 +110,9 @@ def virtual?
105110
false
106111
end
107112

113+
protected
114+
attr_reader :cast_type
115+
108116
private
109117
def deduplicated
110118
@name = -name

activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ def quote_default_expression(value, column) # :nodoc:
160160
elsif column.type == :uuid && value.is_a?(String) && value.include?("()")
161161
value # Does not quote function default values for UUID columns
162162
elsif column.respond_to?(:array?)
163-
quote(column.cast_type.serialize(value))
163+
# TODO: Remove fetch_cast_type and the need for connection after we release 8.1.
164+
quote(column.fetch_cast_type(self).serialize(value))
164165
else
165166
super
166167
end
@@ -186,11 +187,12 @@ def type_cast(value) # :nodoc:
186187
end
187188
end
188189

189-
private
190-
def lookup_cast_type(sql_type)
191-
super(query_value("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").to_i)
192-
end
190+
# TODO: Make this method private after we release 8.1.
191+
def lookup_cast_type(sql_type) # :nodoc:
192+
super(query_value("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").to_i)
193+
end
193194

195+
private
194196
def encode_array(array_data)
195197
encoder = array_data.encoder
196198
values = type_cast_array(array_data.values)

activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,8 @@ def copy_table(from, to, options = {})
654654
column_options[:stored] = column.virtual_stored?
655655
column_options[:type] = column.type
656656
elsif column.has_default?
657-
default = column.cast_type.deserialize(column.default)
657+
# TODO: Remove fetch_cast_type and the need for connection after we release 8.1.
658+
default = column.fetch_cast_type(self).deserialize(column.default)
658659
default = -> { column.default_function } if default.nil?
659660

660661
unless column.auto_increment?

activerecord/lib/active_record/model_schema.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,9 @@ def compute_table_name
619619
end
620620
end
621621

622-
def type_for_column(column)
623-
type = column.cast_type
622+
def type_for_column(connection, column)
623+
# TODO: Remove the need for a connection after we release 8.1.
624+
type = column.fetch_cast_type(connection)
624625

625626
if immutable_strings_by_default && type.respond_to?(:to_immutable_string)
626627
type = type.to_immutable_string

activerecord/lib/active_record/type_caster/connection.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ def type_for_attribute(attr_name)
1919
if schema_cache.data_source_exists?(table_name)
2020
column = schema_cache.columns_hash(table_name)[attr_name.to_s]
2121
if column
22-
type = column.cast_type
22+
# TODO: Remove fetch_cast_type and the need for connection after we release 8.1.
23+
type = column.fetch_cast_type(@klass.lease_connection)
2324
end
2425
end
2526

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
--- !ruby/object:ActiveRecord::ConnectionAdapters::SchemaCache
2+
columns:
3+
colleges:
4+
- &1 !ruby/object:ActiveRecord::ConnectionAdapters::Column
5+
auto_increment: true
6+
name: id
7+
sql_type_metadata: &4 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
8+
sql_type: INTEGER
9+
type: :integer
10+
limit:
11+
precision:
12+
scale:
13+
'null': false
14+
default:
15+
default_function:
16+
collation:
17+
comment:
18+
- &2 !ruby/object:ActiveRecord::ConnectionAdapters::Column
19+
auto_increment:
20+
name: name
21+
sql_type_metadata: !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
22+
sql_type: varchar
23+
type: :string
24+
limit:
25+
precision:
26+
scale:
27+
'null': false
28+
default:
29+
default_function:
30+
collation:
31+
comment:
32+
courses:
33+
- *1
34+
- *2
35+
- !ruby/object:ActiveRecord::ConnectionAdapters::Column
36+
auto_increment:
37+
name: college_id
38+
sql_type_metadata: *4
39+
'null': true
40+
default:
41+
default_function:
42+
collation:
43+
comment:
44+
courses_professors:
45+
- !ruby/object:ActiveRecord::ConnectionAdapters::Column
46+
auto_increment:
47+
name: course_id
48+
sql_type_metadata: *4
49+
'null': true
50+
default:
51+
default_function:
52+
collation:
53+
comment:
54+
- !ruby/object:ActiveRecord::ConnectionAdapters::Column
55+
auto_increment:
56+
name: professor_id
57+
sql_type_metadata: *4
58+
'null': true
59+
default:
60+
default_function:
61+
collation:
62+
comment:
63+
dogs:
64+
- *1
65+
professors:
66+
- *1
67+
- *2
68+
primary_keys:
69+
colleges: id
70+
courses: id
71+
courses_professors:
72+
dogs: id
73+
professors: id
74+
data_sources:
75+
colleges: true
76+
courses: true
77+
courses_professors: true
78+
dogs: true
79+
professors: true
80+
indexes:
81+
colleges: []
82+
courses:
83+
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
84+
table: courses
85+
name: index_courses_on_college_id
86+
unique: false
87+
columns:
88+
- college_id
89+
lengths: {}
90+
orders: {}
91+
opclasses: {}
92+
where:
93+
type:
94+
using:
95+
include:
96+
nulls_not_distinct:
97+
comment:
98+
valid: true
99+
courses_professors:
100+
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
101+
table: courses_professors
102+
name: index_courses_professors_on_professor_id
103+
unique: false
104+
columns:
105+
- professor_id
106+
lengths: {}
107+
orders: {}
108+
opclasses: {}
109+
where:
110+
type:
111+
using:
112+
include:
113+
nulls_not_distinct:
114+
comment:
115+
valid: true
116+
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
117+
table: courses_professors
118+
name: index_courses_professors_on_course_id
119+
unique: false
120+
columns:
121+
- course_id
122+
lengths: {}
123+
orders: {}
124+
opclasses: {}
125+
where:
126+
type:
127+
using:
128+
include:
129+
nulls_not_distinct:
130+
comment:
131+
valid: true
132+
dogs: []
133+
professors: []
134+
version: 0

0 commit comments

Comments
 (0)