Skip to content

MySQL create_table loses ENGINE default info if options doesn't provide it. #30947

@albertoalmagro

Description

@albertoalmagro

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.

How to reproduce

# 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions