Permalink
Browse files

PERF: exact email match bypass

instead of scanning full table when there is an exact email match ONLY
return the actual user.
  • Loading branch information...
SamSaffron committed Nov 9, 2017
1 parent 86e6732 commit 2d5bf0705acab3702f6bfd183ff71e63474a6078
Showing with 29 additions and 4 deletions.
  1. +17 −4 lib/admin_user_index_query.rb
  2. +12 −0 spec/components/admin_user_index_query_spec.rb
@@ -101,13 +101,26 @@ def filter_by_query_classification
end
end
def filter_by_user_with_bypass(filter)
if filter =~ /.+@.+/
# probably an email so try the bypass
user_id = UserEmail.where(email: filter.downcase).pluck(:user_id).first
if user_id
return @query.where('users.id = ?', user_id)
end
end
@query.where('username_lower ILIKE :filter OR user_emails.email ILIKE :filter', filter: "%#{params[:filter]}%")
end
def filter_by_search
if params[:filter].present?
params[:filter].strip!
if ip = IPAddr.new(params[:filter]) rescue nil
filter = params[:filter]
if filter.present?
filter.strip!
if ip = IPAddr.new(filter) rescue nil
@query.where('ip_address <<= :ip OR registration_ip_address <<= :ip', ip: ip.to_cidr_s)
else
@query.where('username_lower ILIKE :filter OR user_emails.email ILIKE :filter', filter: "%#{params[:filter]}%")
filter_by_user_with_bypass(filter)
end
end
end
@@ -178,6 +178,18 @@ def real_users_count(query)
describe "filtering" do
context "exact email bypass" do
it "can correctly bypass expensive ilike query" do
user = Fabricate(:user, email: 'sam@Sam.com')
query = AdminUserIndexQuery.new(filter: 'Sam@sam.com').find_users_query
expect(query.count).to eq(1)
expect(query.first.id).to eq(user.id)
expect(query.to_sql.downcase).not_to include("ilike")
end
end
context "by email fragment" do
before(:each) { Fabricate(:user, email: "test1@example.com") }

0 comments on commit 2d5bf07

Please sign in to comment.