1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Refactor case_{sensitive|insensitive}_comparison

Before:

    ```
    SELECT  1 AS one FROM "topics" WHERE "topics"."title" = 'abc' LIMIT $1  [["LIMIT", 1]]
    ```

After:

    ```
    SELECT  1 AS one FROM "topics" WHERE "topics"."title" = $1 LIMIT $2 [["title", "abc"], ["LIMIT", 1]]
    ```
This commit is contained in:
Ryuta Kamizono 2016-01-01 06:18:03 +09:00
parent 8167fa4562
commit b80d304f11
4 changed files with 17 additions and 20 deletions

View file

@ -391,19 +391,17 @@ module ActiveRecord
def release_savepoint(name = nil)
end
def case_sensitive_modifier(node, table_attribute)
node
end
def case_sensitive_comparison(table, attribute, column, value)
table_attr = table[attribute]
value = case_sensitive_modifier(value, table_attr) unless value.nil?
table_attr.eq(value)
if value.nil?
table[attribute].eq(value)
else
table[attribute].eq(Arel::Nodes::BindParam.new)
end
end
def case_insensitive_comparison(table, attribute, column, value)
if can_perform_case_insensitive_comparison_for?(column)
table[attribute].lower.eq(table.lower(value))
table[attribute].lower.eq(table.lower(Arel::Nodes::BindParam.new))
else
case_sensitive_comparison(table, attribute, column, value)
end

View file

@ -752,16 +752,11 @@ module ActiveRecord
SQL
end
def case_sensitive_modifier(node, table_attribute)
node = Arel::Nodes.build_quoted node, table_attribute
Arel::Nodes::Bin.new(node)
end
def case_sensitive_comparison(table, attribute, column, value)
if column.case_sensitive?
table[attribute].eq(value)
else
if value.nil? || column.case_sensitive?
super
else
table[attribute].eq(Arel::Nodes::Bin.new(Arel::Nodes::BindParam.new))
end
end
@ -769,7 +764,7 @@ module ActiveRecord
if column.case_sensitive?
super
else
table[attribute].eq(value)
table[attribute].eq(Arel::Nodes::BindParam.new)
end
end

View file

@ -22,6 +22,7 @@ module ActiveRecord
parts = predicate_builder.build_from_hash(attributes)
when Arel::Nodes::Node
parts = [opts]
binds = other
else
raise ArgumentError, "Unsupported argument type: #{opts} (#{opts.class})"
end

View file

@ -73,15 +73,18 @@ module ActiveRecord
value = value.to_s[0, column.limit]
end
value = Arel::Nodes::Quoted.new(value)
comparison = if !options[:case_sensitive] && !value.nil?
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
klass.connection.case_insensitive_comparison(table, attribute, column, value)
else
klass.connection.case_sensitive_comparison(table, attribute, column, value)
end
if value.nil?
klass.unscoped.where(comparison)
else
bind = Relation::QueryAttribute.new(attribute.to_s, value, Type::Value.new)
klass.unscoped.where(comparison, bind)
end
rescue RangeError
klass.none
end