Skip to content

Commit b85ee91

Browse files
committed
Fix virtual datetime default precision
Prior to this change t.virtual :column_name, type: :datetime would erroneously produce the same result as t.virtual :column_name, type: :datetime, precision: nil This is because the code path for `virtual` skipped the default lookup: - `t.datetime` is delegated to the `column` method - `column` sees `type == :datetime` and sets a default `precision` is none was given - `column` calls `new_column_definition` to add the result to `@columns_hash` - `t.virtual` is delegated to the `column` method - `column` sees `type == :virtual`, not `:datetime`, so skips the default lookup - `column` calls `new_column_definition` to add the result to `@columns_hash` - `new_column_definition` sees `type == :virtual`, so sets `type = options[:type]` By moving the default lookup, we get consistent code paths: - `t.datetime` is delegated to the `column` method - `column` calls `new_column_definition` to add the result to `@columns_hash` - `new_column_definition` sees `type == :datetime` and sets a default `precision` is none was given - `t.virtual` is delegated to the `column` method - `column` calls `new_column_definition` to add the result to `@columns_hash` - `new_column_definition` sees `type == :virtual`, so sets `type = options[:type]` - `new_column_definition` sees `type == :datetime` and sets a default `precision` is none was given
1 parent 919dd4a commit b85ee91

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

activerecord/CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
* Fix erroneous nil default precision on virtual datetime columns.
2+
3+
Prior to this change, virtual datetime columns did not have the same
4+
default precision as regular datetime columns, resulting in the following
5+
being erroneously equivalent:
6+
7+
t.virtual :name, type: datetime, as: "expression"
8+
t.virtual :name, type: datetime, precision: nil, as: "expression"
9+
10+
This change fixes the default precision lookup, so virtual and regular
11+
datetime column default precisions match.
12+
13+
*Sam Bostock*
14+
115
* Use connection from `#with_raw_connection` in `#quote_string`.
216

317
This ensures that the string quoting is wrapped in the reconnect and retry logic

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -475,12 +475,6 @@ def column(name, type, index: nil, **options)
475475
end
476476
end
477477

478-
if @conn.supports_datetime_with_precision?
479-
if type == :datetime && !options.key?(:precision)
480-
options[:precision] = 6
481-
end
482-
end
483-
484478
@columns_hash[name] = new_column_definition(name, type, **options)
485479

486480
if index
@@ -547,6 +541,13 @@ def new_column_definition(name, type, **options) # :nodoc:
547541
type = integer_like_primary_key_type(type, options)
548542
end
549543
type = aliased_types(type.to_s, type)
544+
545+
if @conn.supports_datetime_with_precision?
546+
if type == :datetime && !options.key?(:precision)
547+
options[:precision] = 6
548+
end
549+
end
550+
550551
options[:primary_key] ||= type == :primary_key
551552
options[:null] = false if options[:primary_key]
552553
create_column_definition(name, type, options)

activerecord/test/cases/adapters/mysql2/virtual_column_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def test_schema_dumping
6363
assert_match(/t\.virtual\s+"name_length",\s+type: :integer,\s+as: "(?:octet_length|length)\(`name`\)",\s+stored: true$/i, output)
6464
assert_match(/t\.virtual\s+"name_octet_length",\s+type: :integer,\s+as: "(?:octet_length|length)\(`name`\)",\s+stored: true$/i, output)
6565
assert_match(/t\.virtual\s+"profile_email",\s+type: :string,\s+as: "json_extract\(`profile`,\w*?'\$\.email'\)", stored: true$/i, output)
66-
assert_match(/t\.virtual\s+"time_mirror",\s+type: :datetime,\s+precision: nil,\s+as: "`time`"$/i, output[/^.*time_mirror.*$/])
66+
assert_match(/t\.virtual\s+"time_mirror",\s+type: :datetime,\s+as: "`time`"$/i, output[/^.*time_mirror.*$/])
6767
end
6868
end
6969
end

activerecord/test/cases/migration/change_schema_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def test_add_column_with_timestamp_type
286286
elsif current_adapter?(:OracleAdapter)
287287
assert_equal "TIMESTAMP(6)", column.sql_type
288288
else
289-
assert_equal connection.type_to_sql("datetime"), column.sql_type
289+
assert_equal connection.type_to_sql("datetime(6)"), column.sql_type
290290
end
291291
end
292292

0 commit comments

Comments
 (0)