Allow changing text and blob size without giving the limit
option
In MySQL, the text column size is 65,535 bytes by default (1 GiB in PostgreSQL). It is sometimes too short when people want to use a text column, so they sometimes change the text size to mediumtext (16 MiB) or longtext (4 GiB) by giving the `limit` option. Unlike MySQL, PostgreSQL doesn't allow the `limit` option for a text column (raises ERROR: type modifier is not allowed for type "text"). So `limit: 4294967295` (longtext) couldn't be used in Action Text. I've allowed changing text and blob size without giving the `limit` option, it prevents that migration failure on PostgreSQL.
This commit is contained in:
parent
b8baa15adb
commit
1745e905a3
@ -5,11 +5,7 @@ def change
|
||||
t.string :message_id, null: false
|
||||
t.string :message_checksum, null: false
|
||||
|
||||
if supports_datetime_with_precision?
|
||||
t.timestamps precision: 6
|
||||
else
|
||||
t.timestamps
|
||||
end
|
||||
t.timestamps
|
||||
|
||||
t.index [ :message_id, :message_checksum ], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true
|
||||
end
|
||||
|
@ -2,7 +2,7 @@ class CreateActionTextTables < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :action_text_rich_texts do |t|
|
||||
t.string :name, null: false
|
||||
t.text :body, limit: 16777215
|
||||
t.text :body, size: :long
|
||||
t.references :record, null: false, polymorphic: true, index: false
|
||||
|
||||
t.timestamps
|
@ -2,11 +2,10 @@ class CreateActionTextTables < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :action_text_rich_texts do |t|
|
||||
t.string :name, null: false
|
||||
t.text :body, limit: 16777215
|
||||
t.text :body, size: :long
|
||||
t.references :record, null: false, polymorphic: true, index: false
|
||||
|
||||
t.datetime :created_at, null: false
|
||||
t.datetime :updated_at, null: false
|
||||
t.timestamps
|
||||
|
||||
t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
|
||||
end
|
@ -14,7 +14,7 @@
|
||||
|
||||
create_table "action_text_rich_texts", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.text "body", limit: 16777215
|
||||
t.text "body"
|
||||
t.string "record_type", null: false
|
||||
t.integer "record_id", null: false
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
|
@ -1,3 +1,7 @@
|
||||
* MySQL: Support `:size` option to change text and blob size.
|
||||
|
||||
*Ryuta Kamizono*
|
||||
|
||||
* Make `t.timestamps` with precision by default.
|
||||
|
||||
*Ryuta Kamizono*
|
||||
|
@ -29,7 +29,7 @@ class AbstractMysqlAdapter < AbstractAdapter
|
||||
NATIVE_DATABASE_TYPES = {
|
||||
primary_key: "bigint auto_increment PRIMARY KEY",
|
||||
string: { name: "varchar", limit: 255 },
|
||||
text: { name: "text", limit: 65535 },
|
||||
text: { name: "text" },
|
||||
integer: { name: "int", limit: 4 },
|
||||
float: { name: "float", limit: 24 },
|
||||
decimal: { name: "decimal" },
|
||||
@ -37,7 +37,8 @@ class AbstractMysqlAdapter < AbstractAdapter
|
||||
timestamp: { name: "timestamp" },
|
||||
time: { name: "time" },
|
||||
date: { name: "date" },
|
||||
binary: { name: "blob", limit: 65535 },
|
||||
binary: { name: "blob" },
|
||||
blob: { name: "blob" },
|
||||
boolean: { name: "tinyint", limit: 1 },
|
||||
json: { name: "json" },
|
||||
}
|
||||
|
@ -56,6 +56,16 @@ def new_column_definition(name, type, **options) # :nodoc:
|
||||
case type
|
||||
when :virtual
|
||||
type = options[:type]
|
||||
when :text, :blob, :binary
|
||||
case (size = options[:size])&.to_s
|
||||
when "tiny", "medium", "long"
|
||||
sql_type = @conn.native_database_types[type][:name]
|
||||
type = "#{size}#{sql_type}"
|
||||
else
|
||||
raise ArgumentError, <<~MSG unless size.nil?
|
||||
#{size.inspect} is invalid :size value. Only :tiny, :medium, and :long are allowed.
|
||||
MSG
|
||||
end
|
||||
when :primary_key
|
||||
type = :integer
|
||||
options[:limit] ||= 8
|
||||
|
@ -10,6 +10,10 @@ def prepare_column_options(column)
|
||||
spec[:unsigned] = "true" if column.unsigned?
|
||||
spec[:auto_increment] = "true" if column.auto_increment?
|
||||
|
||||
if /\A(?<size>tiny|medium|long)(?:text|blob)/ =~ column.sql_type
|
||||
spec = { size: size.to_sym.inspect }.merge!(spec)
|
||||
end
|
||||
|
||||
if @connection.supports_virtual_columns? && column.virtual?
|
||||
spec[:as] = extract_expression_for_virtual_column(column)
|
||||
spec[:stored] = "true" if /\b(?:STORED|PERSISTENT)\b/.match?(column.extra)
|
||||
@ -37,13 +41,15 @@ def schema_type(column)
|
||||
case column.sql_type
|
||||
when /\Atimestamp\b/
|
||||
:timestamp
|
||||
when "tinyblob"
|
||||
:blob
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def schema_limit(column)
|
||||
super unless /\A(?:tiny|medium|long)?(?:text|blob)/.match?(column.sql_type)
|
||||
end
|
||||
|
||||
def schema_precision(column)
|
||||
super unless /\A(?:date)?time(?:stamp)?\b/.match?(column.sql_type) && column.precision == 0
|
||||
end
|
||||
|
@ -626,6 +626,18 @@ def test_out_of_range_text_limit_should_raise
|
||||
ensure
|
||||
Person.connection.drop_table :test_text_limits, if_exists: true
|
||||
end
|
||||
|
||||
def test_invalid_text_size_should_raise
|
||||
e = assert_raise(ArgumentError) do
|
||||
Person.connection.create_table :test_text_sizes, force: true do |t|
|
||||
t.text :bigtext, size: 0xfffffffff
|
||||
end
|
||||
end
|
||||
|
||||
assert_match(/#{0xfffffffff} is invalid :size value\. Only :tiny, :medium, and :long are allowed\./, e.message)
|
||||
ensure
|
||||
Person.connection.drop_table :test_text_sizes, if_exists: true
|
||||
end
|
||||
end
|
||||
|
||||
if ActiveRecord::Base.connection.supports_advisory_locks?
|
||||
|
@ -245,25 +245,31 @@ def test_schema_dump_expression_indices
|
||||
|
||||
if current_adapter?(:Mysql2Adapter)
|
||||
def test_schema_dump_includes_length_for_mysql_binary_fields
|
||||
output = standard_dump
|
||||
output = dump_table_schema "binary_fields"
|
||||
assert_match %r{t\.binary\s+"var_binary",\s+limit: 255$}, output
|
||||
assert_match %r{t\.binary\s+"var_binary_large",\s+limit: 4095$}, output
|
||||
end
|
||||
|
||||
def test_schema_dump_includes_length_for_mysql_blob_and_text_fields
|
||||
output = standard_dump
|
||||
assert_match %r{t\.blob\s+"tiny_blob",\s+limit: 255$}, output
|
||||
output = dump_table_schema "binary_fields"
|
||||
assert_match %r{t\.binary\s+"tiny_blob",\s+size: :tiny$}, output
|
||||
assert_match %r{t\.binary\s+"normal_blob"$}, output
|
||||
assert_match %r{t\.binary\s+"medium_blob",\s+limit: 16777215$}, output
|
||||
assert_match %r{t\.binary\s+"long_blob",\s+limit: 4294967295$}, output
|
||||
assert_match %r{t\.text\s+"tiny_text",\s+limit: 255$}, output
|
||||
assert_match %r{t\.binary\s+"medium_blob",\s+size: :medium$}, output
|
||||
assert_match %r{t\.binary\s+"long_blob",\s+size: :long$}, output
|
||||
assert_match %r{t\.text\s+"tiny_text",\s+size: :tiny$}, output
|
||||
assert_match %r{t\.text\s+"normal_text"$}, output
|
||||
assert_match %r{t\.text\s+"medium_text",\s+limit: 16777215$}, output
|
||||
assert_match %r{t\.text\s+"long_text",\s+limit: 4294967295$}, output
|
||||
assert_match %r{t\.text\s+"medium_text",\s+size: :medium$}, output
|
||||
assert_match %r{t\.text\s+"long_text",\s+size: :long$}, output
|
||||
assert_match %r{t\.binary\s+"tiny_blob_2",\s+size: :tiny$}, output
|
||||
assert_match %r{t\.binary\s+"medium_blob_2",\s+size: :medium$}, output
|
||||
assert_match %r{t\.binary\s+"long_blob_2",\s+size: :long$}, output
|
||||
assert_match %r{t\.text\s+"tiny_text_2",\s+size: :tiny$}, output
|
||||
assert_match %r{t\.text\s+"medium_text_2",\s+size: :medium$}, output
|
||||
assert_match %r{t\.text\s+"long_text_2",\s+size: :long$}, output
|
||||
end
|
||||
|
||||
def test_schema_does_not_include_limit_for_emulated_mysql_boolean_fields
|
||||
output = standard_dump
|
||||
output = dump_table_schema "booleans"
|
||||
assert_no_match %r{t\.boolean\s+"has_fun",.+limit: 1}, output
|
||||
end
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
create_table :binary_fields, force: true do |t|
|
||||
t.binary :var_binary, limit: 255
|
||||
t.binary :var_binary_large, limit: 4095
|
||||
|
||||
t.tinyblob :tiny_blob
|
||||
t.blob :normal_blob
|
||||
t.mediumblob :medium_blob
|
||||
@ -36,6 +37,13 @@
|
||||
t.mediumtext :medium_text
|
||||
t.longtext :long_text
|
||||
|
||||
t.binary :tiny_blob_2, size: :tiny
|
||||
t.binary :medium_blob_2, size: :medium
|
||||
t.binary :long_blob_2, size: :long
|
||||
t.text :tiny_text_2, size: :tiny
|
||||
t.text :medium_text_2, size: :medium
|
||||
t.text :long_text_2, size: :long
|
||||
|
||||
t.index :var_binary
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user