Skip to content
Browse files

Pass column to quote when copying a sqlite table.

To make quote escape binary data correctly it needs the column passed in.
  • Loading branch information...
1 parent f278deb commit d3e5118e7d42a9425b843190380d12ed3ce1e5f9 @mmb mmb committed Mar 8, 2013
View
9 activerecord/CHANGELOG.md
@@ -1,5 +1,14 @@
## Rails 4.0.0 (unreleased) ##
+* Fix quoting for sqlite migrations using copy_table_contents() with binary
+ columns.
+
+ These would fail with "SQLite3::SQLException: unrecognized token" because
+ the column was not being passed to quote() so the data was not quoted
+ correctly.
+
+ *Matthew M. Boedicker*
+
* Promotes `change_column_null` to the migrations API. This macro sets/removes
`NOT NULL` constraints, and accepts an optional argument to replace existing
`NULL`s if needed. The adapters for SQLite, MySQL, PostgreSQL, and (at least)
View
10 activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -583,9 +583,17 @@ def copy_table_contents(from, to, columns, rename = {}) #:nodoc:
quoted_columns = columns.map { |col| quote_column_name(col) } * ','
quoted_to = quote_table_name(to)
+
+ raw_column_mappings = Hash[columns(from).map { |c| [c.name, c] }]
+
exec_query("SELECT * FROM #{quote_table_name(from)}").each do |row|
sql = "INSERT INTO #{quoted_to} (#{quoted_columns}) VALUES ("
- sql << columns.map {|col| quote row[column_mappings[col]]} * ', '
+
+ column_values = columns.map do |col|
+ quote(row[column_mappings[col]], raw_column_mappings[col])
+ end
+
+ sql << column_values * ', '
sql << ')'
exec_query sql
end
View
6 activerecord/test/cases/adapters/sqlite3/copy_table_test.rb
@@ -1,7 +1,7 @@
require "cases/helper"
class CopyTableTest < ActiveRecord::TestCase
- fixtures :customers, :companies, :comments
+ fixtures :customers, :companies, :comments, :binaries
def setup
@connection = ActiveRecord::Base.connection
@@ -72,6 +72,10 @@ def test_copy_table_with_unconventional_primary_key
end
end
+ def test_copy_table_with_binary_column
+ test_copy_table 'binaries', 'binaries2'
+ end
+
protected
def copy_table(from, to, options = {})
@connection.copy_table(from, to, {:temporary => true}.merge(options))

0 comments on commit d3e5118

Please sign in to comment.
Something went wrong with that request. Please try again.