mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
rm Type#text?
This predicate was only to figure out if it's safe to do case insensitive comparison, which is only a problem on PG. Turns out, PG can just tell us whether we are able to do it or not. If the query turns out to be a problem, let's just replace that method with checking the SQL type for `text` or `character`. I'd rather not burden the type objects with adapter specific knowledge. The *real* solution, is to deprecate this behavior entirely. The only reason we need it is because the `:case_sensitive` option for `validates_uniqueness_of` is documented as "this option is ignored for non-strings". It makes no sense for us to do that. If the type can't be compared in a case insensitive way, the user shouldn't tell us to do case insensitive comparison.
This commit is contained in:
parent
c4ef73affd
commit
16629c099c
6 changed files with 29 additions and 14 deletions
|
@ -367,9 +367,18 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def case_insensitive_comparison(table, attribute, column, value)
|
||||
table[attribute].lower.eq(table.lower(value))
|
||||
if can_perform_case_insensitive_comparison_for?(column)
|
||||
table[attribute].lower.eq(table.lower(value))
|
||||
else
|
||||
case_sensitive_comparison(table, attribute, column, value)
|
||||
end
|
||||
end
|
||||
|
||||
def can_perform_case_insensitive_comparison_for?(column)
|
||||
true
|
||||
end
|
||||
private :can_perform_case_insensitive_comparison_for?
|
||||
|
||||
def current_savepoint_name
|
||||
current_transaction.savepoint_name
|
||||
end
|
||||
|
|
|
@ -8,10 +8,6 @@ module ActiveRecord
|
|||
def initialize(type)
|
||||
@type = type
|
||||
end
|
||||
|
||||
def text?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -762,6 +762,24 @@ module ActiveRecord
|
|||
def create_table_definition(name, temporary = false, options = nil, as = nil) # :nodoc:
|
||||
PostgreSQL::TableDefinition.new native_database_types, name, temporary, options, as
|
||||
end
|
||||
|
||||
def can_perform_case_insensitive_comparison_for?(column)
|
||||
@case_insensitive_cache ||= {}
|
||||
@case_insensitive_cache[column.sql_type] ||= begin
|
||||
sql = <<-end_sql
|
||||
SELECT exists(
|
||||
SELECT * FROM pg_proc
|
||||
INNER JOIN pg_cast
|
||||
ON casttarget::text::oidvector = proargtypes
|
||||
WHERE proname = 'lower'
|
||||
AND castsource = '#{column.sql_type}'::regtype::oid
|
||||
)
|
||||
end_sql
|
||||
execute_and_clear(sql, "SCHEMA", []) do |result|
|
||||
result.getvalue(0, 0) == 't'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,10 +21,6 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def text?
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cast_value(value)
|
||||
|
|
|
@ -52,10 +52,6 @@ module ActiveRecord
|
|||
|
||||
# These predicates are not documented, as I need to look further into
|
||||
# their use, and see if they can be removed entirely.
|
||||
def text? # :nodoc:
|
||||
false
|
||||
end
|
||||
|
||||
def number? # :nodoc:
|
||||
false
|
||||
end
|
||||
|
|
|
@ -69,7 +69,7 @@ module ActiveRecord
|
|||
|
||||
value = Arel::Nodes::Quoted.new(value)
|
||||
|
||||
comparison = if !options[:case_sensitive] && value && cast_type.text?
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue