1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 10:12:41 +01:00

Make Ferret query functions sticky only if their values are not quoted

Summary:
Ref T13509. Currently, functions are "sticky", but this stickness is in the query execution layer.

Instead:

  - move stickiness to the query compiler; and
  - make it so that functions are not sticky if their arguments are quoted.

For example:

  - `title:x y` previously meant `title:x title:y` (and still does). The "title:" is sticky.
  - `title:"x" y` previously meant `title:x title:y`. It now means `title:x all:y`. The "title:" is not sticky because the argument is quoted.

Test Plan: Added unit tests, ran unit tests.

Maniphest Tasks: T13509

Differential Revision: https://secure.phabricator.com/D21108
This commit is contained in:
epriestley 2020-04-14 09:10:18 -07:00
parent f31b9987ba
commit 8fa8d0e648
3 changed files with 38 additions and 5 deletions

View file

@ -262,6 +262,7 @@ final class PhutilSearchQueryCompiler
} }
$results = array(); $results = array();
$last_function = null;
foreach ($tokens as $token) { foreach ($tokens as $token) {
$value = implode('', $token['value']); $value = implode('', $token['value']);
$operator_string = implode('', $token['operator']); $operator_string = implode('', $token['operator']);
@ -339,7 +340,26 @@ final class PhutilSearchQueryCompiler
); );
if ($enable_functions) { if ($enable_functions) {
$result['function'] = $token['function']; // If a user provides a query like "title:a b c", we interpret all
// of the terms to be title terms: the "title:" function sticks
// until we encounter another function.
// If a user provides a query like "title:"a"" (with a quoted term),
// the function is not sticky.
if ($token['function'] !== null) {
$function = $token['function'];
} else {
$function = $last_function;
}
$result['function'] = $function;
if ($result['quoted']) {
$last_function = null;
} else {
$last_function = $function;
}
} }
$results[] = $result; $results[] = $result;

View file

@ -156,6 +156,21 @@ final class PhutilSearchQueryCompilerTestCase
'~' => false, '~' => false,
'-' => false, '-' => false,
// Functions like "title:" apply to following terms if their term is
// not specified with double quotes.
'title:x y' => array(
array('title', $op_and, 'x'),
array('title', $op_and, 'y'),
),
'title: x y' => array(
array('title', $op_and, 'x'),
array('title', $op_and, 'y'),
),
'title:"x" y' => array(
array('title', $op_and, 'x'),
array(null, $op_and, 'y'),
),
); );
$this->assertCompileFunctionQueries($function_tests); $this->assertCompileFunctionQueries($function_tests);

View file

@ -1801,7 +1801,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$this->ferretEngine = $engine; $this->ferretEngine = $engine;
$this->ferretTokens = $fulltext_tokens; $this->ferretTokens = $fulltext_tokens;
$current_function = $engine->getDefaultFunctionKey(); $default_function = $engine->getDefaultFunctionKey();
$table_map = array(); $table_map = array();
$idx = 1; $idx = 1;
foreach ($this->ferretTokens as $fulltext_token) { foreach ($this->ferretTokens as $fulltext_token) {
@ -1809,7 +1809,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$function = $raw_token->getFunction(); $function = $raw_token->getFunction();
if ($function === null) { if ($function === null) {
$function = $current_function; $function = $default_function;
} }
$raw_field = $engine->getFieldForFunction($function); $raw_field = $engine->getFieldForFunction($function);
@ -1821,8 +1821,6 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
'key' => $raw_field, 'key' => $raw_field,
); );
} }
$current_function = $function;
} }
// Join the title field separately so we can rank results. // Join the title field separately so we can rank results.