mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fixed MariaDB default function
Dont test default function on MySQL where it is unsupported and default expect default function instead of default value Simplified test - dont repeat last test Removed cache of create table SQL - it messes up when tables change, and it should only be called when a default is set and the other cases arent true anyway Test if string first (starts with single quote) because default_type does a SQL lookup and is more expensive Fixed tests: Postgres uses a different named method for generating UUID's Skip check if column default is a function when it starts with a number to reduce the number of queries done Added note in CHANGELOG.md
This commit is contained in:
parent
2c21a39493
commit
4ccd79cdd6
4 changed files with 75 additions and 2 deletions
|
@ -1,3 +1,11 @@
|
|||
* Fixed MariaDB default function support.
|
||||
|
||||
Defaults would be written wrong in "db/schema.rb" and not work correctly
|
||||
if using `db:schema:load`. Further more the function name would be
|
||||
added as string content when saving new records.
|
||||
|
||||
*kaspernj*
|
||||
|
||||
* Add `active_record.destroy_association_async_batch_size` configuration
|
||||
|
||||
This allows applications to specify the maximum number of records that will
|
||||
|
|
|
@ -158,7 +158,27 @@ module ActiveRecord
|
|||
MySQL::TableDefinition.new(self, name, **options)
|
||||
end
|
||||
|
||||
def default_type(table_name, field_name)
|
||||
match = create_table_sql(table_name).match(/`#{field_name}` (.+) DEFAULT ('|\d+|[A-z]+)/)
|
||||
default_pre = match[2] if match
|
||||
|
||||
if default_pre == "'"
|
||||
:string
|
||||
elsif default_pre&.match?(/^\d+$/)
|
||||
:integer
|
||||
elsif default_pre&.match?(/^[A-z]+$/)
|
||||
:function
|
||||
end
|
||||
end
|
||||
|
||||
def create_table_sql(table_name)
|
||||
execute_and_free("SHOW CREATE TABLE #{quote_table_name(table_name)}") do |result|
|
||||
result.first[1]
|
||||
end
|
||||
end
|
||||
|
||||
def new_column_from_field(table_name, field)
|
||||
field_name = field.fetch(:Field)
|
||||
type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
|
||||
default, default_function = field[:Default], nil
|
||||
|
||||
|
@ -168,9 +188,13 @@ module ActiveRecord
|
|||
elsif type_metadata.extra == "DEFAULT_GENERATED"
|
||||
default = +"(#{default})" unless default.start_with?("(")
|
||||
default, default_function = nil, default
|
||||
elsif type_metadata.type == :text && default
|
||||
elsif type_metadata.type == :text && default&.start_with?("'")
|
||||
# strip and unescape quotes
|
||||
default = default[1...-1].gsub("\\'", "'")
|
||||
elsif default&.match?(/\A\d/)
|
||||
# Its a number so we can skip the query to check if it is a function
|
||||
elsif default && default_type(table_name, field_name) == :function
|
||||
default, default_function = nil, default
|
||||
end
|
||||
|
||||
MySQL::Column.new(
|
||||
|
|
|
@ -1347,6 +1347,32 @@ if ActiveRecord::Base.connection.supports_bulk_alter?
|
|||
assert_equal "This is a comment", column(:birthdate).comment
|
||||
end
|
||||
|
||||
if supports_text_column_with_default?
|
||||
def test_default_functions_on_columns
|
||||
with_bulk_change_table do |t|
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
t.string :name, default: -> { "gen_random_uuid()" }
|
||||
else
|
||||
t.string :name, default: -> { "UUID()" }
|
||||
end
|
||||
end
|
||||
|
||||
assert_nil column(:name).default
|
||||
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
assert_equal "gen_random_uuid()", column(:name).default_function
|
||||
Person.connection.execute("INSERT INTO delete_me DEFAULT VALUES")
|
||||
person_data = Person.connection.execute("SELECT * FROM delete_me ORDER BY id DESC").to_a.first
|
||||
else
|
||||
assert_equal "uuid()", column(:name).default_function
|
||||
Person.connection.execute("INSERT INTO delete_me () VALUES ()")
|
||||
person_data = Person.connection.execute("SELECT * FROM delete_me ORDER BY id DESC").to_a(as: :hash).first
|
||||
end
|
||||
|
||||
assert_match(/\A(.+)-(.+)-(.+)-(.+)\Z/, person_data.fetch("name"))
|
||||
end
|
||||
end
|
||||
|
||||
if current_adapter?(:Mysql2Adapter)
|
||||
def test_updating_auto_increment
|
||||
with_bulk_change_table do |t|
|
||||
|
|
|
@ -825,7 +825,16 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
|
|||
t.datetime :datetime_with_default, default: "2014-06-05 07:17:04"
|
||||
t.time :time_with_default, default: "07:17:04"
|
||||
t.decimal :decimal_with_default, default: "1234567890.0123456789", precision: 20, scale: 10
|
||||
t.text :text_with_default, default: "John' Doe" if supports_text_column_with_default?
|
||||
|
||||
if supports_text_column_with_default?
|
||||
t.text :text_with_default, default: "John' Doe"
|
||||
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
t.text :uuid, default: -> { "gen_random_uuid()" }
|
||||
else
|
||||
t.text :uuid, default: -> { "uuid()" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
|
@ -864,6 +873,12 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
|
|||
output = dump_table_schema("dump_defaults")
|
||||
|
||||
assert_match %r{t\.text\s+"text_with_default",.*?default: "John' Doe"}, output
|
||||
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
assert_match %r{t\.text\s+"uuid",.*?default: -> \{ "gen_random_uuid\(\)" \}}, output
|
||||
else
|
||||
assert_match %r{t\.text\s+"uuid",.*?default: -> \{ "uuid\(\)" \}}, output
|
||||
end
|
||||
end if supports_text_column_with_default?
|
||||
|
||||
def test_schema_dump_with_column_infinity_default
|
||||
|
|
Loading…
Reference in a new issue