Pārlūkot izejas kodu

HUE-2451 [dashboard] Don't handle partial values in the query parser

Johan Ahlen 8 gadi atpakaļ
vecāks
revīzija
a7a82ec

+ 46 - 40
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/solrQueryParser.jison

@@ -24,7 +24,6 @@
 [/][*][^*]*[*]+([^/*][^*]*[*]+)*[/]            { /* skip comments */ }
 
 '\u2020'                                       { parser.yy.cursorFound = yylloc; return 'CURSOR'; }
-'\u2021'                                       { parser.yy.cursorFound = yylloc; return 'PARTIAL_CURSOR'; }
 
 'AND'                                          { return 'AND'; }
 '&&'                                           { return 'AND'; }
@@ -63,7 +62,7 @@
 \'                                             { this.begin('singleQuotedValue'); return 'SINGLE_QUOTE'; }
 <singleQuotedValue>(?:\\[']|[^'])+             {
                                                  if (parser.handleQuotedValueWithCursor(this, yytext, yylloc, '\'')) {
-                                                   yytext = yytext.replace(/[\u2020\u2021].*/, '');
+                                                   yytext = yytext.replace(/[\u2020].*/, '');
                                                    return 'PARTIAL_VALUE';
                                                  }
                                                  return 'VALUE';
@@ -73,21 +72,21 @@
 \"                                             { this.begin('doubleQuotedValue'); return 'DOUBLE_QUOTE'; }
 <doubleQuotedValue>(?:\\["]|[^"])+             {
                                                  if (parser.handleQuotedValueWithCursor(this, yytext, yylloc, '"')) {
-                                                   yytext = yytext.replace(/[\u2020\u2021].*/, '');
+                                                   yytext = yytext.replace(/[\u2020].*/, '');
                                                    return 'PARTIAL_VALUE';
                                                  }
                                                  return 'VALUE';
                                                }
 <doubleQuotedValue>\"                          { this.popState(); return 'DOUBLE_QUOTE'; }
 
-[^\s\u3000!():"'^+\-!\[\]{}~*?/\u2020\u2021]+  { return 'TERM'; }
+[^\s\u3000!():"'^+\-!\[\]{}~*?/\u2020]+        { return 'TERM'; }
 
 <<EOF>>                                        { return 'EOF'; }
 
 /lex
 
 %left 'AND' 'OR' '&&' '||' BooleanOperator
-%left 'CURSOR' 'PARTIAL_CURSOR' AnyCursor       // Cursor precedence needed to not conflict with operators i.e. x 'CURSOR' y vs. x 'AND' y
+%left 'CURSOR'  // Cursor precedence needed to not conflict with operators i.e. x 'CURSOR' y vs. x 'AND' y
 
 %start SolrQueryAutocomplete
 
@@ -102,15 +101,15 @@ SolrQueryAutocomplete
    {
      return $1;
    }
- | AnyCursor 'EOF'
+ | 'CURSOR' 'EOF'
    {
-     return { suggestFields: {} }
+     return { suggestFields: { appendColon: true } }
    }
  ;
 
 SolrQuery
  : NonParenthesizedSolrQuery
- | '(' NonParenthesizedSolrQuery ')'
+ | '(' NonParenthesizedSolrQuery ')'                           --> $2
  ;
 
 SolrQuery_EDIT
@@ -121,12 +120,11 @@ SolrQuery_EDIT
 NonParenthesizedSolrQuery
  : 'NUMBER'
  | 'TERM'
- | KeywordMatch
+ | KeywordMatch                                                --> { hasKeywordMatch: true }
  ;
 
 NonParenthesizedSolrQuery_EDIT
- : 'TERM' 'PARTIAL_CURSOR'                                     --> { suggestFields: { startsWith: $1 }, suggestValues: { field: $1, prependColon: true }, suggestKeywords: [':'] }
- | KeywordMatch_EDIT
+ : KeywordMatch_EDIT
  ;
 
 NonParenthesizedSolrQuery
@@ -134,14 +132,28 @@ NonParenthesizedSolrQuery
  ;
 
 NonParenthesizedSolrQuery_EDIT
- : SolrQuery 'CURSOR'                                          --> { suggestKeywords: ['AND', 'OR', '&&', '||'] }
- | SolrQuery 'CURSOR' SolrQuery                                --> { suggestKeywords: ['AND', 'OR', '&&', '||'] }
- | 'CURSOR' SolrQuery                                          --> { suggestFields: {} }
+ : SolrQuery 'CURSOR'
+   {
+     if ($1.hasKeywordMatch) {
+       $$ = { suggestKeywords: ['AND', 'OR'] };
+     } else {
+       $$ = { suggestKeywords: ['AND', 'OR', ':'], suggestValues: { field: $1, prependColon: true } };
+     }
+   }
+ | SolrQuery 'CURSOR' SolrQuery
+   {
+     if ($1.hasKeywordMatch) {
+       $$ = { suggestKeywords: ['AND', 'OR'] };
+     } else {
+       $$ = { suggestKeywords: ['AND', 'OR', ':'], suggestValues: { field: $1, prependColon: true } };
+     }
+   }
+ | 'CURSOR' SolrQuery                                          --> { suggestFields: { appendColon: true } }
  ;
 
 NonParenthesizedSolrQuery_EDIT
- : SolrQuery BooleanOperator 'CURSOR'                         --> { suggestFields: {} }
- | 'CURSOR' BooleanOperator SolrQuery                         --> { suggestFields: {} }
+ : SolrQuery BooleanOperator 'CURSOR'                          --> { suggestFields: { appendColon: true } }
+ | 'CURSOR' BooleanOperator SolrQuery                          --> { suggestFields: { appendColon: true } }
  | SolrQuery BooleanOperator SolrQuery_EDIT                    --> $3
  | SolrQuery_EDIT BooleanOperator SolrQuery                    --> $1
  ;
@@ -152,25 +164,24 @@ KeywordMatch
  ;
 
 KeywordMatch_EDIT
- : 'TERM' ':' AnyCursor                                        --> { suggestValues: { field: $1 } }
- | 'TERM' ':' 'TERM' 'PARTIAL_CURSOR'                          --> { suggestValues: { field: $1, startsWith: $3 } }
- | 'TERM' ':' QuotedValue_EDIT                                 --> { suggestValues: { field: $1, startsWith: $3 } }
+ : 'TERM' ':' 'CURSOR'                                         --> { suggestValues: { field: $1 } }
+ | 'TERM' ':' QuotedValue_EDIT                                 --> { suggestValues: { field: $1 } }
  ;
 
 // ======= Common constructs =======
-AnyCursor
-: 'CURSOR' | 'PARTIAL_CURSOR';
 
 BooleanOperator
-: 'AND' | 'OR' | '&&' | '||';
+ : 'AND' | 'OR' | '&&' | '||';
 
 QuotedValue
-: 'SINGLE_QUOTE' 'VALUE' 'SINGLE_QUOTE' | 'DOUBLE_QUOTE' 'VALUE' 'DOUBLE_QUOTE';
+ : 'SINGLE_QUOTE' 'VALUE' 'SINGLE_QUOTE'                       --> $2
+ | 'DOUBLE_QUOTE' 'VALUE' 'DOUBLE_QUOTE'                       --> $2
+ ;
 
 QuotedValue_EDIT
-: 'SINGLE_QUOTE' 'PARTIAL_VALUE'                               --> $2
-| 'DOUBLE_QUOTE' 'PARTIAL_VALUE'                               --> $2
-;
+ : 'SINGLE_QUOTE' 'PARTIAL_VALUE'                              --> $2
+ | 'DOUBLE_QUOTE' 'PARTIAL_VALUE'                              --> $2
+ ;
 
 RightParenthesisOrError: ')' | error;
 %%
@@ -182,15 +193,14 @@ parser.addFieldLocation = function (location, name) {
 }
 
 parser.identifyPartials = function (beforeCursor, afterCursor) {
-  var beforeMatch = beforeCursor.match(/[^()-*+/,\s]*$/);
-  var afterMatch = afterCursor.match(/^[^()-*+/,\s]*/);
+  var beforeMatch = beforeCursor.match(/[^()-*+/,:\s]*$/);
+  var afterMatch = afterCursor.match(/^[^()-*+/,:\s]*/);
   return { left: beforeMatch ? beforeMatch[0].length : 0, right: afterMatch ? afterMatch[0].length : 0 };
 };
 
 parser.handleQuotedValueWithCursor = function (lexer, yytext, yylloc, quoteChar) {
-  if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) {
-    parser.yy.partialCursor = yytext.indexOf('\u2021') !== -1;
-    var cursorIndex = parser.yy.partialCursor ? yytext.indexOf('\u2021') : yytext.indexOf('\u2020');
+  if (yytext.indexOf('\u2020') !== -1) {
+    var cursorIndex = yytext.indexOf('\u2020');
     parser.yy.cursorFound = {
       first_line: yylloc.first_line,
       last_line: yylloc.last_line,
@@ -242,12 +252,8 @@ parser.autocompleteSolrQuery = function (beforeCursor, afterCursor, debug) {
 
   parser.yy.partialCursor = parser.yy.partialLengths.left > 0;
 
-
-  var cursorChar = parser.yy.partialCursor ? '\u2021' : '\u2020';
-
-  // TODO: Remove left adjust if no need for it
-  if (parser.yy.partialCursor) {
-    parser.yy.partialLengths.left = 0;
+  if (parser.yy.partialLengths.left > 0) {
+    beforeCursor = beforeCursor.substring(0, beforeCursor.length - parser.yy.partialLengths.left);
   }
 
   if (parser.yy.partialLengths.right > 0) {
@@ -256,7 +262,7 @@ parser.autocompleteSolrQuery = function (beforeCursor, afterCursor, debug) {
 
   var result;
   try {
-    result = parser.parse(beforeCursor + cursorChar + afterCursor);
+    result = parser.parse(beforeCursor + '\u2020' + afterCursor);
   } catch (err) {
     // Workaround for too many missing parentheses (it's the only error we handle in the parser)
     if (err && err.toString().indexOf('Parsing halted while starting to recover from another error') !== -1) {
@@ -268,13 +274,13 @@ parser.autocompleteSolrQuery = function (beforeCursor, afterCursor, debug) {
         rightCount++;
       }
       try {
-        result = parser.parse(beforeCursor + cursorChar + parenthesisPad);
+        result = parser.parse(beforeCursor + '\u2020' + parenthesisPad);
       } catch (err) {
         return { locations: parser.yy.locations }
       }
     } else {
       if (debug) {
-        console.log(beforeCursor + cursorChar + afterCursor);
+        console.log(beforeCursor + '\u2020' + afterCursor);
         console.log(err);
         console.error(err.stack);
       }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/solrQueryParser.js


+ 21 - 25
desktop/core/src/desktop/static/desktop/spec/autocomplete/solrQueryParserSpec.js

@@ -14,7 +14,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 (function () {
-  fdescribe('solrQueryParser.js', function () {
+  describe('solrQueryParser.js', function () {
     var testAutocomplete = function (beforeCursor, afterCursor, expectedResult) {
       var result = solrQueryParser.autocompleteSolrQuery(beforeCursor, afterCursor, true);
       if (!expectedResult.locations) {
@@ -26,21 +26,20 @@
 
     it('should suggest fields for "|"', function () {
       testAutocomplete('', '', {
-        suggestFields: {}
+        suggestFields: { appendColon: true }
       });
     });
 
     it('should suggest values for "field|"', function () {
       testAutocomplete('field', '', {
-        suggestFields: { startsWith: 'field' },
-        suggestValues: { field: 'field', prependColon: true },
-        suggestKeywords: [':']
+        suggestFields: { appendColon: true }
       });
     });
 
     it('should suggest AND or OR for "field |"', function () {
       testAutocomplete('field ', '', {
-        suggestKeywords: ['AND', 'OR', '&&', '||']
+        suggestKeywords: ['AND', 'OR', ':'],
+        suggestValues: { field: 'field', prependColon: true }
       });
     });
 
@@ -52,71 +51,68 @@
 
     it('should suggest values for "field:someVal|"', function () {
       testAutocomplete('field:someVal', '', {
-        suggestValues: { field: 'field', startsWith: 'someVal' }
+        suggestValues: { field: 'field' }
       });
     });
 
     it('should suggest values for "field:"some Val|"', function () {
       testAutocomplete('field:"some Val', '', {
-        suggestValues: { field: 'field', startsWith: 'some Val' }
+        suggestValues: { field: 'field' }
       });
     });
 
     it('should suggest values for "field:"some Val| foo"', function () {
       testAutocomplete('field:"some Val', ' foo"', {
-        suggestValues: { field: 'field', startsWith: 'some Val' }
+        suggestValues: { field: 'field' }
       });
     });
 
     it('should suggest AND or OR for "field:value |"', function () {
       testAutocomplete('field:value ', '', {
-        suggestKeywords: ['AND', 'OR', '&&', '||']
+        suggestKeywords: ['AND', 'OR']
       });
     });
 
     it('should suggest fields for "field:value AND |"', function () {
       testAutocomplete('field:value AND ', '', {
-        suggestFields: {}
+        suggestFields: { appendColon: true }
       });
     });
 
     it('should suggest fields for "(field:value OR foo) AND |"', function () {
       testAutocomplete('(field:value OR foo) AND ', '', {
-        suggestFields: {}
+        suggestFields: { appendColon: true }
       });
     });
 
     it('should suggest fields for "| field"', function () {
       testAutocomplete('', ' field', {
-        suggestFields: {}
+        suggestFields: { appendColon: true }
       });
     });
 
     it('should suggest fields for "| && field"', function () {
       testAutocomplete('', ' && field', {
-        suggestFields: {}
+        suggestFields: { appendColon: true }
       });
     });
 
-    it('should suggest values for "foo and b|"', function () {
-      testAutocomplete('foo and b', '', {
-        suggestFields: { startsWith: 'b' },
-        suggestValues: { field: 'b', prependColon: true },
-        suggestKeywords: [':']
+    it('should suggest values for "foo AND b|"', function () {
+      testAutocomplete('foo AND b', '', {
+        suggestFields: { appendColon: true }
       });
     });
 
-    it('should suggest values for "f| or boo"', function () {
-      testAutocomplete('f', ' or boo', {
-        suggestFields: { startsWith: 'f' },
-        suggestValues: { field: 'f', prependColon: true },
-        suggestKeywords: [':']
+    it('should suggest values for "f| OR boo"', function () {
+      testAutocomplete('f', ' OR boo', {
+        suggestFields: { appendColon: true }
       });
     });
 
     it('should suggest AND or OR for "foo | field:value "', function () {
       testAutocomplete('foo ', ' field:value', {
-        suggestKeywords: ['AND', 'OR', '&&', '||']
+        suggestKeywords: ['AND', 'OR', ':'],
+        suggestValues: { field: 'foo', prependColon: true }
       });
     });
   });

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels