mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Only use BINARY for mysql case sensitive uniqueness check when column has a case insensitive collation.
This commit is contained in:
parent
a6900a2073
commit
501ae92a32
6 changed files with 62 additions and 6 deletions
|
@ -1,3 +1,7 @@
|
|||
* Only use BINARY for mysql case sensitive uniqueness check when column has a case insensitive collation.
|
||||
|
||||
*Ryuta Kamizono*
|
||||
|
||||
* Fix validation on uniqueness of empty association.
|
||||
|
||||
*Evgeny Li*
|
||||
|
|
|
@ -334,6 +334,11 @@ module ActiveRecord
|
|||
node
|
||||
end
|
||||
|
||||
def case_sensitive_comparison(table, attribute, column, value)
|
||||
value = case_sensitive_modifier(value) unless value.nil?
|
||||
table[attribute].eq(value)
|
||||
end
|
||||
|
||||
def case_insensitive_comparison(table, attribute, column, value)
|
||||
table[attribute].lower.eq(table.lower(value))
|
||||
end
|
||||
|
|
|
@ -585,6 +585,14 @@ module ActiveRecord
|
|||
Arel::Nodes::Bin.new(node)
|
||||
end
|
||||
|
||||
def case_sensitive_comparison(table, attribute, column, value)
|
||||
if column.case_sensitive?
|
||||
table[attribute].eq(value)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def case_insensitive_comparison(table, attribute, column, value)
|
||||
if column.case_sensitive?
|
||||
super
|
||||
|
|
|
@ -59,8 +59,7 @@ module ActiveRecord
|
|||
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
|
||||
klass.connection.case_insensitive_comparison(table, attribute, column, value)
|
||||
else
|
||||
value = klass.connection.case_sensitive_modifier(value) unless value.nil?
|
||||
table[attribute].eq(value)
|
||||
klass.connection.case_sensitive_comparison(table, attribute, column, value)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ require 'models/person'
|
|||
|
||||
class MysqlCaseSensitivityTest < ActiveRecord::TestCase
|
||||
class CollationTest < ActiveRecord::Base
|
||||
validates_uniqueness_of :string_cs_column, :case_sensitive => false
|
||||
validates_uniqueness_of :string_ci_column, :case_sensitive => false
|
||||
end
|
||||
|
||||
repair_validations(CollationTest)
|
||||
|
||||
def test_columns_include_collation_different_from_table
|
||||
assert_equal 'utf8_bin', CollationTest.columns_hash['string_cs_column'].collation
|
||||
assert_equal 'utf8_general_ci', CollationTest.columns_hash['string_ci_column'].collation
|
||||
|
@ -18,6 +18,7 @@ class MysqlCaseSensitivityTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_case_insensitive_comparison_for_ci_column
|
||||
CollationTest.validates_uniqueness_of(:string_ci_column, :case_sensitive => false)
|
||||
CollationTest.create!(:string_ci_column => 'A')
|
||||
invalid = CollationTest.new(:string_ci_column => 'a')
|
||||
queries = assert_sql { invalid.save }
|
||||
|
@ -26,10 +27,29 @@ class MysqlCaseSensitivityTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_case_insensitive_comparison_for_cs_column
|
||||
CollationTest.validates_uniqueness_of(:string_cs_column, :case_sensitive => false)
|
||||
CollationTest.create!(:string_cs_column => 'A')
|
||||
invalid = CollationTest.new(:string_cs_column => 'a')
|
||||
queries = assert_sql { invalid.save }
|
||||
cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) }
|
||||
assert_match(/lower/i, cs_uniqueness_query)
|
||||
end
|
||||
|
||||
def test_case_sensitive_comparison_for_ci_column
|
||||
CollationTest.validates_uniqueness_of(:string_ci_column, :case_sensitive => true)
|
||||
CollationTest.create!(:string_ci_column => 'A')
|
||||
invalid = CollationTest.new(:string_ci_column => 'A')
|
||||
queries = assert_sql { invalid.save }
|
||||
ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) }
|
||||
assert_match(/binary/i, ci_uniqueness_query)
|
||||
end
|
||||
|
||||
def test_case_sensitive_comparison_for_cs_column
|
||||
CollationTest.validates_uniqueness_of(:string_cs_column, :case_sensitive => true)
|
||||
CollationTest.create!(:string_cs_column => 'A')
|
||||
invalid = CollationTest.new(:string_cs_column => 'A')
|
||||
queries = assert_sql { invalid.save }
|
||||
cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) }
|
||||
assert_no_match(/binary/i, cs_uniqueness_query)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,10 +3,10 @@ require 'models/person'
|
|||
|
||||
class Mysql2CaseSensitivityTest < ActiveRecord::TestCase
|
||||
class CollationTest < ActiveRecord::Base
|
||||
validates_uniqueness_of :string_cs_column, :case_sensitive => false
|
||||
validates_uniqueness_of :string_ci_column, :case_sensitive => false
|
||||
end
|
||||
|
||||
repair_validations(CollationTest)
|
||||
|
||||
def test_columns_include_collation_different_from_table
|
||||
assert_equal 'utf8_bin', CollationTest.columns_hash['string_cs_column'].collation
|
||||
assert_equal 'utf8_general_ci', CollationTest.columns_hash['string_ci_column'].collation
|
||||
|
@ -18,6 +18,7 @@ class Mysql2CaseSensitivityTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_case_insensitive_comparison_for_ci_column
|
||||
CollationTest.validates_uniqueness_of(:string_ci_column, :case_sensitive => false)
|
||||
CollationTest.create!(:string_ci_column => 'A')
|
||||
invalid = CollationTest.new(:string_ci_column => 'a')
|
||||
queries = assert_sql { invalid.save }
|
||||
|
@ -26,10 +27,29 @@ class Mysql2CaseSensitivityTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_case_insensitive_comparison_for_cs_column
|
||||
CollationTest.validates_uniqueness_of(:string_cs_column, :case_sensitive => false)
|
||||
CollationTest.create!(:string_cs_column => 'A')
|
||||
invalid = CollationTest.new(:string_cs_column => 'a')
|
||||
queries = assert_sql { invalid.save }
|
||||
cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/)}
|
||||
assert_match(/lower/i, cs_uniqueness_query)
|
||||
end
|
||||
|
||||
def test_case_sensitive_comparison_for_ci_column
|
||||
CollationTest.validates_uniqueness_of(:string_ci_column, :case_sensitive => true)
|
||||
CollationTest.create!(:string_ci_column => 'A')
|
||||
invalid = CollationTest.new(:string_ci_column => 'A')
|
||||
queries = assert_sql { invalid.save }
|
||||
ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) }
|
||||
assert_match(/binary/i, ci_uniqueness_query)
|
||||
end
|
||||
|
||||
def test_case_sensitive_comparison_for_cs_column
|
||||
CollationTest.validates_uniqueness_of(:string_cs_column, :case_sensitive => true)
|
||||
CollationTest.create!(:string_cs_column => 'A')
|
||||
invalid = CollationTest.new(:string_cs_column => 'A')
|
||||
queries = assert_sql { invalid.save }
|
||||
cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) }
|
||||
assert_no_match(/binary/i, cs_uniqueness_query)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue