Fix timeouts in source:<url> searches and bookmarklet.

* Change the source index on posts from `(lower(source) gin_trgm_ops) WHERE source != ''`
  to just `(source gin_trgm_ops)`. The WHERE clause prevented the index
  from being used in source:<url> searches because we didn't specify
  the `source != ''` clause in the search itself. Excluding blank
  sources only saved a marginal amount of space anyway. This fixes
  timeouts in source:<url> searches and in the bookmarklet (since we do
  a source dupe check on the upload page too).

* Also switch from indexing `lower(name)` to `name` on pools and users.
  We don't need to lowercase the column because GIN indexes can be used
  with both LIKE and ILIKE queries.
This commit is contained in:
evazion
2019-09-02 18:53:27 -05:00
parent ffc693ef37
commit 5df3b01ca2
7 changed files with 44 additions and 11 deletions

View File

@@ -18,11 +18,11 @@ class ApplicationRecord < ActiveRecord::Base
end
def where_ilike(attr, value)
where("lower(#{qualified_column_for(attr)}) LIKE ? ESCAPE E'\\\\'", value.mb_chars.downcase.to_escaped_for_sql_like)
where("#{qualified_column_for(attr)} ILIKE ? ESCAPE E'\\\\'", value.mb_chars.to_escaped_for_sql_like)
end
def where_not_ilike(attr, value)
where.not("lower(#{qualified_column_for(attr)}) LIKE ? ESCAPE E'\\\\'", value.mb_chars.downcase.to_escaped_for_sql_like)
where.not("#{qualified_column_for(attr)} ILIKE ? ESCAPE E'\\\\'", value.mb_chars.to_escaped_for_sql_like)
end
# https://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP

View File

@@ -47,7 +47,7 @@ class Pool < ApplicationRecord
def name_matches(name)
name = normalize_name_for_search(name)
name = "*#{name}*" unless name =~ /\*/
where("lower(pools.name) like ? escape E'\\\\'", name.to_escaped_for_sql_like)
where_ilike(:name, name)
end
def default_order
@@ -108,7 +108,7 @@ class Pool < ApplicationRecord
if name =~ /^\d+$/
where("pools.id = ?", name.to_i).first
elsif name
where("lower(pools.name) = ?", normalize_name_for_search(name)).first
where_ilike(:name, normalize_name_for_search(name)).first
else
nil
end

View File

@@ -139,7 +139,7 @@ class User < ApplicationRecord
# XXX downcasing is the wrong way to do case-insensitive comparison for unicode (should use casefolding).
def find_by_name(name)
where("lower(name) = ?", normalize_name(name)).first
where_ilike(:name, normalize_name(name)).first
end
def normalize_name(name)