From b3a8754013ccc970cf44c4785363fae3f7ac93d2 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 14 Apr 2020 10:08:45 -0700 Subject: [PATCH] Make the Ferret query compiler keep functions sticky across non-initial quoted tokens Summary: Ref T13509. In `title:big "red" dog`, keep "title" sticky across all three terms, since this seems like it's probably the best match for intent. Test Plan: Added unit tests; ran unit tests. Maniphest Tasks: T13509 Differential Revision: https://secure.phabricator.com/D21111 --- .../search/compiler/PhutilSearchQueryCompiler.php | 9 ++++++++- .../__tests__/PhutilSearchQueryCompilerTestCase.php | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/applications/search/compiler/PhutilSearchQueryCompiler.php b/src/applications/search/compiler/PhutilSearchQueryCompiler.php index 17a2483755..891cfcce28 100644 --- a/src/applications/search/compiler/PhutilSearchQueryCompiler.php +++ b/src/applications/search/compiler/PhutilSearchQueryCompiler.php @@ -358,7 +358,14 @@ final class PhutilSearchQueryCompiler $result['function'] = $function; - $is_sticky = !$result['quoted']; + // Note that the function remains sticky across quoted terms appearing + // after the function term. For example, all of these terms are title + // terms: + // + // title:a "b c" d + + $is_sticky = (!$result['quoted'] || ($token['function'] === null)); + switch ($operator) { case self::OPERATOR_ABSENT: case self::OPERATOR_PRESENT: diff --git a/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php b/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php index bae95a8647..dca1b16e94 100644 --- a/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php +++ b/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php @@ -185,6 +185,14 @@ final class PhutilSearchQueryCompilerTestCase array(null, $op_and, 'x'), ), + // Functions like "title:" continue to stick across quotes if the + // quotes aren't the initial argument. + 'title:a "b c" d' => array( + array('title', $op_and, 'a'), + array('title', $op_and, 'b c'), + array('title', $op_and, 'd'), + ), + // These queries require a field be both present and absent, which is // impossible. 'title:- title:x' => false,