提交 69e4cc6e 编写于 作者: J Jeremy Kemper

SQLite, MySQL, PostgreSQL, Oracle: quote column names in column migration SQL...

SQLite, MySQL, PostgreSQL, Oracle: quote column names in column migration SQL statements. Closes #8466.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6889 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 8139de28
*SVN*
* SQLite, MySQL, PostgreSQL, Oracle: quote column names in column migration SQL statements. #8466 [marclove, lorenjohnson]
* Allow nil serialized attributes with a set class constraint. #7293 [sandofsky]
* Oracle: support binary fixtures. #7987 [Michael Schoen]
......
......@@ -388,7 +388,7 @@ def rename_table(name, new_name)
def change_column_default(table_name, column_name, default) #:nodoc:
current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"]
execute("ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{current_type} DEFAULT #{quote(default)}")
execute("ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{current_type} DEFAULT #{quote(default)}")
end
def change_column(table_name, column_name, type, options = {}) #:nodoc:
......@@ -396,14 +396,14 @@ def change_column(table_name, column_name, type, options = {}) #:nodoc:
options[:default] = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Default"]
end
change_column_sql = "ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
change_column_sql = "ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
add_column_options!(change_column_sql, options)
execute(change_column_sql)
end
def rename_column(table_name, column_name, new_column_name) #:nodoc:
current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"]
execute "ALTER TABLE #{table_name} CHANGE #{column_name} #{new_column_name} #{current_type}"
execute "ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}"
end
......
......@@ -387,21 +387,21 @@ def remove_index(table_name, options = {}) #:nodoc:
end
def change_column_default(table_name, column_name, default) #:nodoc:
execute "ALTER TABLE #{table_name} MODIFY #{column_name} DEFAULT #{quote(default)}"
execute "ALTER TABLE #{table_name} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
end
def change_column(table_name, column_name, type, options = {}) #:nodoc:
change_column_sql = "ALTER TABLE #{table_name} MODIFY #{column_name} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
change_column_sql = "ALTER TABLE #{table_name} MODIFY #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
add_column_options!(change_column_sql, options)
execute(change_column_sql)
end
def rename_column(table_name, column_name, new_column_name) #:nodoc:
execute "ALTER TABLE #{table_name} RENAME COLUMN #{column_name} to #{new_column_name}"
execute "ALTER TABLE #{table_name} RENAME COLUMN #{quote_column_name(column_name)} to #{new_column_name}"
end
def remove_column(table_name, column_name) #:nodoc:
execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name}"
execute "ALTER TABLE #{table_name} DROP COLUMN #{quote_column_name(column_name)}"
end
# Find a table's primary key and sequence.
......
......@@ -325,32 +325,35 @@ def add_column(table_name, column_name, type, options = {})
default = options[:default]
notnull = options[:null] == false
quoted_column_name = quote_column_name(column_name)
# Add the column.
execute("ALTER TABLE #{table_name} ADD COLUMN #{column_name} #{type_to_sql(type, options[:limit])}")
execute("ALTER TABLE #{table_name} ADD COLUMN #{quoted_column_name} #{type_to_sql(type, options[:limit])}")
# Set optional default. If not null, update nulls to the new default.
if options_include_default?(options)
change_column_default(table_name, column_name, default)
if notnull
execute("UPDATE #{table_name} SET #{column_name}=#{quote(default, options[:column])} WHERE #{column_name} IS NULL")
execute("UPDATE #{table_name} SET #{quoted_column_name}=#{quote(default, options[:column])} WHERE #{quoted_column_name} IS NULL")
end
end
if notnull
execute("ALTER TABLE #{table_name} ALTER #{column_name} SET NOT NULL")
execute("ALTER TABLE #{table_name} ALTER #{quoted_column_name} SET NOT NULL")
end
end
def change_column(table_name, column_name, type, options = {}) #:nodoc:
begin
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
execute "ALTER TABLE #{table_name} ALTER COLUMN #{quoted_column_name} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
rescue ActiveRecord::StatementInvalid
# This is PG7, so we use a more arcane way of doing it.
begin_db_transaction
add_column(table_name, "#{column_name}_ar_tmp", type, options)
execute "UPDATE #{table_name} SET #{column_name}_ar_tmp = CAST(#{column_name} AS #{type_to_sql(type, options[:limit], options[:precision], options[:scale])})"
tmp_column_name = "#{column_name}_ar_tmp"
add_column(table_name, tmp_column_name, type, options)
execute "UPDATE #{table_name} SET #{quote_column_name(tmp_column_name)} = CAST(#{quote_column_name(column_name)} AS #{type_to_sql(type, options[:limit], options[:precision], options[:scale])})"
remove_column(table_name, column_name)
rename_column(table_name, "#{column_name}_ar_tmp", column_name)
rename_column(table_name, tmp_column_name, column_name)
commit_db_transaction
end
......
......@@ -327,8 +327,10 @@ def copy_table_contents(from, to, columns, rename = {}) #:nodoc:
rename.inject(column_mappings) {|map, a| map[a.last] = a.first; map}
from_columns = columns(from).collect {|col| col.name}
columns = columns.find_all{|col| from_columns.include?(column_mappings[col])}
quoted_columns = columns.map { |col| quote_column_name(col) } * ','
@connection.execute "SELECT * FROM #{from}" do |row|
sql = "INSERT INTO #{to} ("+columns*','+") VALUES ("
sql = "INSERT INTO #{to} (#{quoted_columns}) VALUES ("
sql << columns.map {|col| quote row[column_mappings[col]]} * ', '
sql << ')'
@connection.execute sql
......
......@@ -398,6 +398,17 @@ def test_rename_column
end
end
def test_rename_column_with_sql_reserved_word
begin
assert_nothing_raised { Person.connection.rename_column "people", "first_name", "group" }
Person.reset_column_information
assert Person.column_names.include?("group")
ensure
Person.connection.remove_column("people", "group") rescue nil
Person.connection.add_column("people", "first_name", :string) rescue nil
end
end
def test_rename_table
begin
ActiveRecord::Base.connection.create_table :octopuses do |t|
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册