diff --git a/src/applications/search/query/PhabricatorFulltextToken.php b/src/applications/search/query/PhabricatorFulltextToken.php --- a/src/applications/search/query/PhabricatorFulltextToken.php +++ b/src/applications/search/query/PhabricatorFulltextToken.php @@ -60,6 +60,10 @@ $tip = pht('Substring Search'); $shade = PHUITagView::COLOR_VIOLET; break; + case PhutilSearchQueryCompiler::OPERATOR_EXACT: + $tip = pht('Exact Search'); + $shade = PHUITagView::COLOR_GREEN; + break; default: $shade = PHUITagView::COLOR_BLUE; break; diff --git a/src/applications/search/view/PhabricatorSearchResultView.php b/src/applications/search/view/PhabricatorSearchResultView.php --- a/src/applications/search/view/PhabricatorSearchResultView.php +++ b/src/applications/search/view/PhabricatorSearchResultView.php @@ -84,6 +84,7 @@ switch ($operator) { case PhutilSearchQueryCompiler::OPERATOR_SUBSTRING: + case PhutilSearchQueryCompiler::OPERATOR_EXACT: $patterns[] = '(('.preg_quote($value).'))ui'; break; case PhutilSearchQueryCompiler::OPERATOR_AND: diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php --- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php +++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php @@ -1918,6 +1918,7 @@ $op_sub = PhutilSearchQueryCompiler::OPERATOR_SUBSTRING; $op_not = PhutilSearchQueryCompiler::OPERATOR_NOT; + $op_exact = PhutilSearchQueryCompiler::OPERATOR_EXACT; $where = array(); $current_function = 'all'; @@ -1941,6 +1942,25 @@ $is_substring = false; } + // If we're doing exact search, just test the raw corpus. + $is_exact = ($raw_token->getOperator() == $op_exact); + if ($is_exact) { + if ($is_not) { + $where[] = qsprintf( + $conn, + '(%T.rawCorpus != %s)', + $table_alias, + $value); + } else { + $where[] = qsprintf( + $conn, + '(%T.rawCorpus = %s)', + $table_alias, + $value); + } + continue; + } + // If we're doing substring search, we just match against the raw corpus // and we're done. if ($is_substring) {