rails: MySQL create_table loses ENGINE default info if options doesn't provide it.
Steps to reproduce
In ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
the default value "ENGINE=InnoDB"
for options
is provided. This value is propagated unless the create_table
method receives another options
String, in that case the ENGINE
reference is lost.
# frozen_string_literal: true
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails"
gem "arel", github: "rails/arel"
gem "mysql2"
end
require "active_record"
require "minitest/autorun"
require "logger"
LOG_FILE_PATH = "mysql_create_table_engine.log"
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "mysql2", database: "test", username: "root", password: "")
ActiveRecord::Base.logger = Logger.new(LOG_FILE_PATH)
class CreateUsers < ActiveRecord::Migration[5.2]
def change
create_table :users, options: "DEFAULT CHARSET=utf8" do |t|
t.string :name
t.string :email
end
end
end
class CreateProducts < ActiveRecord::Migration[5.2]
def change
create_table :products do |t|
t.string :name
t.integer :price
end
end
end
class BugTest < Minitest::Test
def test_create_table_loses_engine_info
create_users_migration = CreateUsers.new
create_users_migration.change
logged_info = File.read(LOG_FILE_PATH)
assert !logged_info.include?("ENGINE")
create_users_migration = CreateProducts.new
create_users_migration.change
logged_info = File.read(LOG_FILE_PATH)
assert logged_info.include?("ENGINE")
File.delete(LOG_FILE_PATH)
end
end
Expected behavior
Default ENGINE=InnoDB
is provided by default unless options string provides a different ENGINE, in which case this new engine will override the default one, as documented in Rails Guides. See last paragraph at point 3.1 in Rails Migrations Guides.
Actual behavior
The generated SQL does NOT contain default ENGINE=InnoDB
information if an options string is provided.
System configuration
Rails version: Edge
Ruby version: 2.4.1
I am preparing a fix which will satisfy the expected behavior. Please confirm the issue and I will submit a PR.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 18 (16 by maintainers)
Fixed by #31177.
Thanks @albertoalmagro !
In case anyone finds my comment above, here’s how I’m working around this issue:
https://gist.github.com/blimmer/1ef562ac5981dd8f65653075f16c1157
The reason for explicitly passing
ENGINE=InnoDB
is because the default storage engine was MyISAM in MySQL 5.1. This is not absolutely necessary in MySQL 5.5 unless you intentionally change the server’s default configuration. And MySQL 5.1 had already been EOL in Dec 2013. So I’m not excited to keep the passing default for a future version of Rails.https://dev.mysql.com/doc/refman/5.5/en/innodb-introduction.html