Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15405353
D21109.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
D21109.id.diff
View Options
diff --git a/src/applications/search/compiler/PhutilSearchQueryCompiler.php b/src/applications/search/compiler/PhutilSearchQueryCompiler.php
--- a/src/applications/search/compiler/PhutilSearchQueryCompiler.php
+++ b/src/applications/search/compiler/PhutilSearchQueryCompiler.php
@@ -172,8 +172,10 @@
}
if ($mode == 'operator') {
- if (preg_match('/^\s\z/u', $character)) {
- continue;
+ if (!$current_operator) {
+ if (preg_match('/^\s\z/u', $character)) {
+ continue;
+ }
}
if (preg_match('/^'.$operator_characters.'\z/', $character)) {
@@ -337,6 +339,7 @@
'operator' => $operator,
'quoted' => $is_quoted,
'value' => $value,
+ 'raw' => $this->getDisplayToken($token),
);
if ($enable_functions) {
@@ -355,16 +358,58 @@
$result['function'] = $function;
- if ($result['quoted']) {
- $last_function = null;
- } else {
+ $is_sticky = !$result['quoted'];
+ switch ($operator) {
+ case self::OPERATOR_ABSENT:
+ case self::OPERATOR_PRESENT:
+ $is_sticky = false;
+ break;
+ }
+
+ if ($is_sticky) {
$last_function = $function;
+ } else {
+ $last_function = null;
}
}
$results[] = $result;
}
+ if ($enable_functions) {
+ // If any function is required to be "absent", there must be no other
+ // terms which make assertions about it.
+
+ $present_tokens = array();
+ $absent_tokens = array();
+ foreach ($results as $result) {
+ $function = $result['function'];
+
+ if ($result['operator'] === self::OPERATOR_ABSENT) {
+ $absent_tokens[$function][] = $result;
+ } else {
+ $present_tokens[$function][] = $result;
+ }
+ }
+
+ foreach ($absent_tokens as $function => $tokens) {
+ $absent_token = head($tokens);
+
+ if (empty($present_tokens[$function])) {
+ continue;
+ }
+
+ $present_token = head($present_tokens[$function]);
+
+ throw new PhutilSearchQueryCompilerSyntaxException(
+ pht(
+ 'Query field must be absent ("%s") and present ("%s"). This '.
+ 'is impossible, so the query is not valid.',
+ $absent_token['raw'],
+ $present_token['raw']));
+ }
+ }
+
return $results;
}
diff --git a/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php b/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php
--- a/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php
+++ b/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php
@@ -10,10 +10,6 @@
'cat -dog' => '+"cat" -"dog"',
'cat-dog' => '+"cat-dog"',
- // If there are spaces after an operator, the operator applies to the
- // next search term.
- 'cat - dog' => '+"cat" -"dog"',
-
// Double quotes serve as delimiters even if there is no whitespace
// between terms.
'"cat"dog' => '+"cat" +"dog"',
@@ -40,9 +36,16 @@
// Trailing whitespace should be discarded.
'a b ' => '+"a" +"b"',
- // Functions must have search text.
+ // Tokens must have search text.
'""' => false,
'-' => false,
+
+ // Previously, we permitted spaces to appear inside or after operators.
+
+ // Now that "title:-" is now a valid construction meaning "title is
+ // absent", this had to be tightened. We want "title:- duck" to mean
+ // "title is absent, and any other field matches 'duck'".
+ 'cat - dog' => false,
);
$this->assertCompileQueries($tests);
@@ -171,6 +174,21 @@
array('title', $op_and, 'x'),
array(null, $op_and, 'y'),
),
+
+ // The "present" and "absent" functions are not sticky.
+ 'title:~ x' => array(
+ array('title', $op_present, null),
+ array(null, $op_and, 'x'),
+ ),
+ 'title:- x' => array(
+ array('title', $op_absent, null),
+ array(null, $op_and, 'x'),
+ ),
+
+ // These queries require a field be both present and absent, which is
+ // impossible.
+ 'title:- title:x' => false,
+ 'title:- title:~' => false,
);
$this->assertCompileFunctionQueries($function_tests);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 19, 11:13 AM (3 d, 23 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7624687
Default Alt Text
D21109.id.diff (4 KB)
Attached To
Mode
D21109: Tighten query compiler rules around spaces inside and after operators
Attached
Detach File
Event Timeline
Log In to Comment