mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fixes bugs for using indexes in CREATE TABLE by adding checks for table existence
Also: - updates tests by stubbing table_exists? method - adds entry for creating indexes in CREATE TABLE to changelog
This commit is contained in:
parent
afa148a4f0
commit
63c94efccb
5 changed files with 25 additions and 6 deletions
|
@ -1,3 +1,18 @@
|
|||
* Create indexes inline in CREATE TABLE for MySQL
|
||||
|
||||
This is important, because adding an index on a temporary table after it has been created
|
||||
would commit the transaction.
|
||||
It also allows creating and dropping indexed tables with fewer queries and fewer permissions required.
|
||||
|
||||
Example:
|
||||
|
||||
create_table :temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query" do |t|
|
||||
t.index :zip
|
||||
end
|
||||
# => CREATE TEMPORARY TABLE temp (INDEX (zip)) AS SELECT id, name, zip FROM a_really_complicated_query
|
||||
|
||||
*Cody Cutrer*, *Steve Rice*
|
||||
|
||||
* Save `has_one` association even if the record doesn't changed.
|
||||
|
||||
Fixes #14407.
|
||||
|
|
|
@ -795,7 +795,7 @@ module ActiveRecord
|
|||
if index_name.length > max_index_length
|
||||
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
|
||||
end
|
||||
if index_name_exists?(table_name, index_name, false)
|
||||
if table_exists?(table_name) && index_name_exists?(table_name, index_name, false)
|
||||
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
|
||||
end
|
||||
index_columns = quoted_columns_for_index(column_names, options).join(", ")
|
||||
|
|
|
@ -12,7 +12,7 @@ module ActiveRecord
|
|||
statements = []
|
||||
statements.concat(o.columns.map { |c| accept c })
|
||||
statements.concat(o.indexes.map { |(column_name, options)| index_in_create(o.name, column_name, options) })
|
||||
create_sql << "(#{statements.join(', ')}) "
|
||||
create_sql << "(#{statements.join(', ')}) " if statements.present?
|
||||
create_sql << "#{o.options}"
|
||||
create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
|
||||
create_sql
|
||||
|
|
|
@ -17,7 +17,8 @@ class ActiveSchemaTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_add_index
|
||||
# add_index calls index_name_exists? which can't work since execute is stubbed
|
||||
# add_index calls table_exists? and index_name_exists? which can't work since execute is stubbed
|
||||
def (ActiveRecord::Base.connection).table_exists?(*); true; end
|
||||
def (ActiveRecord::Base.connection).index_name_exists?(*); false; end
|
||||
|
||||
expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`) "
|
||||
|
@ -118,7 +119,8 @@ class ActiveSchemaTest < ActiveRecord::TestCase
|
|||
|
||||
def test_indexes_in_create
|
||||
begin
|
||||
ActiveRecord::Base.connection.stubs(:index_name_exists?).returns(false)
|
||||
ActiveRecord::Base.connection.stubs(:table_exists?).with(:temp).returns(false)
|
||||
ActiveRecord::Base.connection.stubs(:index_name_exists?).with(:index_temp_on_zip).returns(false)
|
||||
expected = "CREATE TEMPORARY TABLE `temp` (INDEX `index_temp_on_zip` (`zip`)) ENGINE=InnoDB AS SELECT id, name, zip FROM a_really_complicated_query"
|
||||
actual = ActiveRecord::Base.connection.create_table(:temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query") do |t|
|
||||
t.index :zip
|
||||
|
|
|
@ -17,7 +17,8 @@ class ActiveSchemaTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_add_index
|
||||
# add_index calls index_name_exists? which can't work since execute is stubbed
|
||||
# add_index calls table_exists? and index_name_exists? which can't work since execute is stubbed
|
||||
def (ActiveRecord::Base.connection).table_exists?(*); true; end
|
||||
def (ActiveRecord::Base.connection).index_name_exists?(*); false; end
|
||||
|
||||
expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`) "
|
||||
|
@ -118,7 +119,8 @@ class ActiveSchemaTest < ActiveRecord::TestCase
|
|||
|
||||
def test_indexes_in_create
|
||||
begin
|
||||
ActiveRecord::Base.connection.stubs(:index_name_exists?).returns(false)
|
||||
ActiveRecord::Base.connection.stubs(:table_exists?).with(:temp).returns(false)
|
||||
ActiveRecord::Base.connection.stubs(:index_name_exists?).with(:index_temp_on_zip).returns(false)
|
||||
expected = "CREATE TEMPORARY TABLE `temp` (INDEX `index_temp_on_zip` (`zip`)) ENGINE=InnoDB AS SELECT id, name, zip FROM a_really_complicated_query"
|
||||
actual = ActiveRecord::Base.connection.create_table(:temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query") do |t|
|
||||
t.index :zip
|
||||
|
|
Loading…
Reference in a new issue