Kaynağa Gözat

HUE-4031 [editor] Make sure we only suggest clean keywords based on dialect

Johan Ahlen 8 yıl önce
ebeveyn
işleme
7fa834c

+ 23 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/spec/sqlSyntaxParserSpec.js

@@ -53,5 +53,28 @@
       expect(result.text).toEqual('SLELECT');
       expect(result.expected.length).toBeGreaterThan(0);
     });
+
+    it('should suggest expected words for "SLELECT "', function() {
+      var result = sqlSyntaxParser.parseSyntax('SLELECT ', '');
+      expect(result).toBeTruthy();
+      expect(result.expected).toEqual(['ALTER', 'CREATE', 'DROP', 'FROM', 'INSERT', 'SELECT', 'SET', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE', 'WITH']);
+    });
+
+    describe('Hive specific', function () {
+      it('should suggest expected words for "SLELECT "', function() {
+        var result = sqlSyntaxParser.parseSyntax('SLELECT ', '', 'hive');
+        expect(result).toBeTruthy();
+        expect(result.expected).toEqual(['ALTER', 'ANALYZE', 'CREATE', 'CREATE', 'DELETE', 'DESCRIBE', 'DROP', 'EXPLAIN', 'EXPORT', 'FROM', 'GRANT', 'IMPORT', 'INSERT', 'INSERT', 'LOAD', 'MSCK', 'RELOAD', 'REVOKE', 'SELECT', 'SET', 'SHOW', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE', 'USE', 'WITH']);
+      });
+    });
+
+    describe('Impala specific', function () {
+      it('should suggest expected words for "SLELECT "', function() {
+        var result = sqlSyntaxParser.parseSyntax('SLELECT ', '', 'impala');
+        expect(result).toBeTruthy();
+        expect(result.expected).toEqual(['ALTER', 'COMPUTE', 'CREATE', 'CREATE', 'DESCRIBE', 'DROP', 'EXPLAIN', 'FROM', 'GRANT', 'INSERT', 'INSERT', 'INVALIDATE', 'LOAD', 'REFRESH', 'REVOKE', 'SELECT', 'SET', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE', 'WITH']);
+      });
+    })
+
   });
 })();

+ 27 - 7
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlParseSupport.js

@@ -20,12 +20,6 @@ var SqlParseSupport = (function () {
     return a && b && a.toLowerCase() === b.toLowerCase();
   };
 
-  var identifyPartials = function (beforeCursor, afterCursor) {
-    var beforeMatch = beforeCursor.match(/[0-9a-zA-Z_]*$/);
-    var afterMatch = afterCursor.match(/^[0-9a-zA-Z_]*(?:\((?:[^)]*\))?)?/);
-    return {left: beforeMatch ? beforeMatch[0].length : 0, right: afterMatch ? afterMatch[0].length : 0};
-  };
-
   var initSqlParser = function (parser) {
 
     var SIMPLE_TABLE_REF_SUGGESTIONS = ['suggestJoinConditions', 'suggestAggregateFunctions', 'suggestFilters', 'suggestGroupBys', 'suggestOrderBys'];
@@ -576,6 +570,12 @@ var SqlParseSupport = (function () {
       return expand(expandedChain[0].name, expandedChain);
     };
 
+    parser.identifyPartials = function (beforeCursor, afterCursor) {
+      var beforeMatch = beforeCursor.match(/[0-9a-zA-Z_]*$/);
+      var afterMatch = afterCursor.match(/^[0-9a-zA-Z_]*(?:\((?:[^)]*\))?)?/);
+      return {left: beforeMatch ? beforeMatch[0].length : 0, right: afterMatch ? afterMatch[0].length : 0};
+    };
+
     parser.expandLateralViews = function (lateralViews, originalIdentifierChain, columnSuggestion) {
       var identifierChain = originalIdentifierChain.concat(); // Clone in case it's re-used
       var firstIdentifier = identifierChain[0];
@@ -1356,7 +1356,7 @@ var SqlParseSupport = (function () {
         }
       }
 
-      parser.yy.partialLengths = identifyPartials(beforeCursor, afterCursor);
+      parser.yy.partialLengths = parser.identifyPartials(beforeCursor, afterCursor);
 
       if (parser.yy.partialLengths.left > 0) {
         beforeCursor = beforeCursor.substring(0, beforeCursor.length - parser.yy.partialLengths.left);
@@ -1494,6 +1494,11 @@ var SqlParseSupport = (function () {
       parser.yy.error = hash;
     };
 
+    var IGNORED_EXPECTED = {
+      ';': true,
+      'EOF': true
+    };
+
     parser.parseSyntax = function (beforeCursor, afterCursor, dialect, debug) {
       parser.yy.error = undefined;
 
@@ -1524,6 +1529,21 @@ var SqlParseSupport = (function () {
         }
       }
       if (parser.yy.error && !beforeCursor.endsWith(parser.yy.error.text)) {
+
+        var cleanExpected = [];
+        parser.yy.error.expected.forEach(function (expected) {
+          // Strip away the surrounding ' chars
+          expected = expected.substring(1, expected.length - 1);
+          if (!IGNORED_EXPECTED[expected]) {
+            if (expected.length > 0 && expected.indexOf('<') !== 0) {
+              cleanExpected.push(expected);
+            } else if (dialect && expected.indexOf('<' + dialect + '>') == 0) {
+              cleanExpected.push(expected.substring(dialect.length + 2));
+            }
+          }
+        });
+        cleanExpected.sort();
+        parser.yy.error.expected = cleanExpected;
         return parser.yy.error;
       }
       return false;