1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +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();
$last_function = null;
foreach ($tokens as $token) {
$value = implode('', $token['value']);
$operator_string = implode('', $token['operator']);
@ -339,7 +340,26 @@ final class PhutilSearchQueryCompiler
);
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;

View file

@ -156,6 +156,21 @@ final class PhutilSearchQueryCompilerTestCase
'~' => 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);

View file

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