1
0
Fork 0
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:
Sean Griffin 2015-02-07 17:23:30 -07:00
parent c4ef73affd
commit 16629c099c
6 changed files with 29 additions and 14 deletions

View file

@ -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

View file

@ -8,10 +8,6 @@ module ActiveRecord
def initialize(type)
@type = type
end
def text?
false
end
end
end
end

View file

@ -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

View file

@ -21,10 +21,6 @@ module ActiveRecord
end
end
def text?
true
end
private
def cast_value(value)

View file

@ -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

View file

@ -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