@@ -238,21 +238,30 @@ impl SuggestDao<'_> {
238238 continue ;
239239 } ;
240240
241- let candidate = candidate_chunk. join ( " " ) ;
242-
243- if self . conn . query_row_and_then_cachable (
244- "
245- SELECT EXISTS (
246- SELECT 1 FROM yelp_modifiers WHERE type = :type AND keyword = :word LIMIT 1
247- )
248- " ,
241+ let mut candidate = candidate_chunk. join ( " " ) ;
242+
243+ if let Some ( keyword_lowercase) = self . conn . try_query_one :: < String , _ > (
244+ if n == query_words. len ( ) {
245+ "
246+ SELECT keyword FROM yelp_modifiers
247+ WHERE type = :type AND keyword BETWEEN :word AND :word || x'FFFF'
248+ LIMIT 1
249+ "
250+ } else {
251+ "
252+ SELECT keyword FROM yelp_modifiers
253+ WHERE type = :type AND keyword = :word
254+ LIMIT 1
255+ "
256+ } ,
249257 named_params ! {
250258 ":type" : modifier_type,
251259 ":word" : candidate. to_lowercase( ) ,
252260 } ,
253- |row| row. get :: < _ , bool > ( 0 ) ,
254261 true ,
255262 ) ? {
263+ // Preserve the query as the user typed it including its case.
264+ candidate. push_str ( keyword_lowercase. get ( candidate. len ( ) ..) . unwrap_or_default ( ) ) ;
256265 return Ok ( Some ( ( candidate, rest) ) ) ;
257266 }
258267 }
@@ -353,20 +362,29 @@ impl SuggestDao<'_> {
353362 continue ;
354363 } ;
355364
356- let candidate = candidate_chunk. join ( " " ) ;
357-
358- if self . conn . query_row_and_then_cachable (
359- "
360- SELECT EXISTS (
361- SELECT 1 FROM yelp_location_signs WHERE keyword = :word LIMIT 1
362- )
363- " ,
365+ let mut candidate = candidate_chunk. join ( " " ) ;
366+
367+ if let Some ( keyword_lowercase) = self . conn . try_query_one :: < String , _ > (
368+ if n == query_words. len ( ) {
369+ "
370+ SELECT keyword FROM yelp_location_signs
371+ WHERE keyword BETWEEN :word AND :word || x'FFFF'
372+ LIMIT 1
373+ "
374+ } else {
375+ "
376+ SELECT keyword FROM yelp_location_signs
377+ WHERE keyword = :word
378+ LIMIT 1
379+ "
380+ } ,
364381 named_params ! {
365382 ":word" : candidate. to_lowercase( ) ,
366383 } ,
367- |row| row. get :: < _ , bool > ( 0 ) ,
368384 true ,
369385 ) ? {
386+ // Preserve the query as the user typed it including its case.
387+ candidate. push_str ( keyword_lowercase. get ( candidate. len ( ) ..) . unwrap_or_default ( ) ) ;
370388 return Ok ( Some ( ( candidate, rest) ) ) ;
371389 }
372390 }
@@ -513,9 +531,24 @@ mod tests {
513531 ( "" , Modifier :: Post , FindFrom :: First , None ) ,
514532 ( "" , Modifier :: Yelp , FindFrom :: First , None ) ,
515533 // Single word modifier.
516- ( "b" , Modifier :: Pre , FindFrom :: First , None ) ,
517- ( "be" , Modifier :: Pre , FindFrom :: First , None ) ,
518- ( "bes" , Modifier :: Pre , FindFrom :: First , None ) ,
534+ (
535+ "b" ,
536+ Modifier :: Pre ,
537+ FindFrom :: First ,
538+ Some ( ( "best" . to_string ( ) , & [ ] ) ) ,
539+ ) ,
540+ (
541+ "be" ,
542+ Modifier :: Pre ,
543+ FindFrom :: First ,
544+ Some ( ( "best" . to_string ( ) , & [ ] ) ) ,
545+ ) ,
546+ (
547+ "bes" ,
548+ Modifier :: Pre ,
549+ FindFrom :: First ,
550+ Some ( ( "best" . to_string ( ) , & [ ] ) ) ,
551+ ) ,
519552 (
520553 "best" ,
521554 Modifier :: Pre ,
@@ -572,10 +605,42 @@ mod tests {
572605 ) ,
573606 ( "same_modifier" , Modifier :: Yelp , FindFrom :: First , None ) ,
574607 // Multiple word modifier.
575- ( "super" , Modifier :: Pre , FindFrom :: First , None ) ,
576- ( "super b" , Modifier :: Pre , FindFrom :: First , None ) ,
577- ( "super be" , Modifier :: Pre , FindFrom :: First , None ) ,
578- ( "super bes" , Modifier :: Pre , FindFrom :: First , None ) ,
608+ (
609+ "s" ,
610+ Modifier :: Pre ,
611+ FindFrom :: First ,
612+ Some ( ( "same_modifier" . to_string ( ) , & [ ] ) ) ,
613+ ) ,
614+ (
615+ "su" ,
616+ Modifier :: Pre ,
617+ FindFrom :: First ,
618+ Some ( ( "super best" . to_string ( ) , & [ ] ) ) ,
619+ ) ,
620+ (
621+ "super" ,
622+ Modifier :: Pre ,
623+ FindFrom :: First ,
624+ Some ( ( "super best" . to_string ( ) , & [ ] ) ) ,
625+ ) ,
626+ (
627+ "super b" ,
628+ Modifier :: Pre ,
629+ FindFrom :: First ,
630+ Some ( ( "super best" . to_string ( ) , & [ ] ) ) ,
631+ ) ,
632+ (
633+ "super be" ,
634+ Modifier :: Pre ,
635+ FindFrom :: First ,
636+ Some ( ( "super best" . to_string ( ) , & [ ] ) ) ,
637+ ) ,
638+ (
639+ "super bes" ,
640+ Modifier :: Pre ,
641+ FindFrom :: First ,
642+ Some ( ( "super best" . to_string ( ) , & [ ] ) ) ,
643+ ) ,
579644 (
580645 "super best" ,
581646 Modifier :: Pre ,
@@ -626,6 +691,9 @@ mod tests {
626691 FindFrom :: Last ,
627692 Some ( ( "DeLiVeRy" . to_string ( ) , & [ "SpIcY" , "rAmEn" ] ) ) ,
628693 ) ,
694+ // Prefix match is available only for last words.
695+ ( "be ramen" , Modifier :: Pre , FindFrom :: First , None ) ,
696+ ( "bes ramen" , Modifier :: Pre , FindFrom :: First , None ) ,
629697 ] ;
630698 for ( query, modifier, findfrom, expected) in find_modifer_tests {
631699 assert_eq ! (
@@ -675,14 +743,16 @@ mod tests {
675743 let find_location_sign_tests: & [ FindLocationSignTestCase ] = & [
676744 // Query, Expected result.
677745 ( "" , None ) ,
678- ( "n" , None ) ,
679- ( "ne" , None ) ,
680- ( "nea" , None ) ,
746+ ( "n" , Some ( ( "near" . to_string ( ) , & [ ] ) ) ) ,
747+ ( "ne" , Some ( ( "near" . to_string ( ) , & [ ] ) ) ) ,
748+ ( "nea" , Some ( ( "near" . to_string ( ) , & [ ] ) ) ) ,
681749 ( "near" , Some ( ( "near" . to_string ( ) , & [ ] ) ) ) ,
682750 ( "near " , Some ( ( "near" . to_string ( ) , & [ ] ) ) ) ,
683- ( "near b" , Some ( ( "near" . to_string ( ) , & [ "b" ] ) ) ) ,
751+ ( "near b" , Some ( ( "near by " . to_string ( ) , & [ ] ) ) ) ,
684752 ( "near by" , Some ( ( "near by" . to_string ( ) , & [ ] ) ) ) ,
685753 ( "near by a" , Some ( ( "near by" . to_string ( ) , & [ "a" ] ) ) ) ,
754+ // Prefix match is available only for last words.
755+ ( "nea r" , None ) ,
686756 ] ;
687757 for ( query, expected) in find_location_sign_tests {
688758 assert_eq ! (
0 commit comments