Browse Source

HUE-4432 [editor] The new autocompleter should be more forgiving when editing incomplete UDFs in select list

This also improves completion around LIKE.
Johan Ahlen 10 năm trước cách đây
mục cha
commit
7fbe1c8abc

+ 172 - 183
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.jison

@@ -516,11 +516,6 @@ HiveOrImpalaCreate
  | '<impala>CREATE'
  ;
 
-HiveOrImpalaCurrent
- : '<hive>CURRENT'
- | '<impala>CURRENT'
- ;
-
 HiveOrImpalaData
  : '<hive>DATA'
  | '<impala>DATA'
@@ -563,16 +558,6 @@ HiveOrImpalaRightSquareBracket
  | '<impala>]'
  ;
 
-HiveOrImpalaRole
- : '<hive>ROLE'
- | '<impala>ROLE'
- ;
-
-HiveOrImpalaRoles
- : '<hive>ROLES'
- | '<impala>ROLES'
- ;
-
 HiveOrImpalaTables
  : '<hive>TABLES'
  | '<impala>TABLES'
@@ -826,11 +811,6 @@ LocalOrSchemaQualifiedName_EDIT
  | RegularOrBackTickedSchemaQualifiedName_EDIT RegularOrBacktickedIdentifier
  ;
 
-ColumnReferenceList
- : ColumnReference
- | ColumnReferenceList ',' ColumnReference
- ;
-
 ColumnReference
  : BasicIdentifierChain
    {
@@ -1189,13 +1169,6 @@ ColumnDefinition_EDIT
    }
  ;
 
-ColumnDefinitionError
- : /* empty, on error we should still suggest the keywords */
-   {
-     suggestTypeKeywords();
-   }
- ;
-
 HdfsLocation
  : HiveOrImpalaLocation HdfsPath
  ;
@@ -1488,6 +1461,10 @@ QuerySpecification_EDIT
      suggestDatabases({ prependQuestionMark: true, prependFrom: true, appendDot: true });
    }
  | 'SELECT' OptionalAllOrDistinct SelectList TableExpression_EDIT
+ | 'SELECT' OptionalAllOrDistinct SelectList_EDIT error TableExpression
+   {
+     console.log(1);
+   }
  | 'SELECT' OptionalAllOrDistinct SelectList_EDIT TableExpression
    {
      if ($3.cursorAtStart) {
@@ -1522,6 +1499,8 @@ QuerySpecification_EDIT
    }
  | 'SELECT' OptionalAllOrDistinct error TableExpression
  | 'SELECT' OptionalAllOrDistinct error TableExpression_EDIT
+ | 'SELECT' OptionalAllOrDistinct SelectList error TableExpression        // Causes conflict but solves issue
+ | 'SELECT' OptionalAllOrDistinct SelectList error TableExpression_EDIT   // with SELECT a, b, cos(| c AS d
  | 'SELECT' OptionalAllOrDistinct SelectList 'CURSOR' TableExpression
    {
      checkForSelectListKeywords($3);
@@ -1691,7 +1670,7 @@ OptionalGroupByClause_EDIT
 
 GroupByColumnList
  : DerivedColumnOrUnsignedInteger
- | GroupByColumnList, DerivedColumnOrUnsignedInteger
+ | GroupByColumnList ',' DerivedColumnOrUnsignedInteger
  ;
 
 GroupByColumnList_EDIT
@@ -1918,6 +1897,7 @@ ValueExpression
  | 'CASE' ValueExpression CaseRightPart  -> $3
  ;
 
+// CASE
 ValueExpression_EDIT
  : 'CASE' CaseRightPart_EDIT                         -> $2
  | 'CASE' 'CURSOR' EndOrError
@@ -2119,7 +2099,18 @@ CaseWhenThenListPartTwo_EDIT
 
 ValueExpression_EDIT
  : NonParenthesizedValueExpressionPrimary_EDIT
- | 'NOT' ValueExpression_EDIT                           -> { types: [ 'BOOLEAN' ] }
+ | 'EXISTS' TableSubQuery_EDIT                               -> { types: [ 'BOOLEAN' ] }
+ | '(' ValueExpression_EDIT RightParenthesisOrError          -> $2
+ | '(' AnyCursor RightParenthesisOrError
+   {
+     valueExpressionSuggest();
+     $$ = { types: ['T'] };
+   }
+ ;
+
+// UNARY
+ValueExpression_EDIT
+ : 'NOT' ValueExpression_EDIT                           -> { types: [ 'BOOLEAN' ] }
  | 'NOT' 'CURSOR'
    {
      suggestFunctions();
@@ -2152,8 +2143,31 @@ ValueExpression_EDIT
      suggestColumns({ types: [ 'NUMBER' ] });
      $$ = { types: [ 'NUMBER' ] };
    }
- | 'EXISTS' TableSubQuery_EDIT                               -> { types: [ 'BOOLEAN' ] }
- | ValueExpression_EDIT 'NOT' 'LIKE' ValueExpression         -> { types: [ 'BOOLEAN' ] }
+ | ValueExpression 'IS' 'NOT' 'CURSOR'
+    {
+      suggestKeywords(['NULL']);
+      $$ = { types: [ 'BOOLEAN' ] };
+    }
+ | ValueExpression 'IS' 'CURSOR'
+   {
+     suggestKeywords(['NOT NULL', 'NULL']);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ | ValueExpression 'IS' 'CURSOR' 'NULL'
+   {
+     suggestKeywords(['NOT']);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ | ValueExpression 'NOT' 'CURSOR'
+   {
+     suggestKeywords(['BETWEEN', 'EXISTS', 'IN', 'LIKE']);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ ;
+
+// LIKE, RLIKE, REGEXP
+ValueExpression_EDIT
+ : ValueExpression_EDIT 'NOT' 'LIKE' ValueExpression         -> { types: [ 'BOOLEAN' ] }
  | ValueExpression_EDIT 'LIKE' ValueExpression               -> { types: [ 'BOOLEAN' ] }
  | ValueExpression_EDIT 'RLIKE' ValueExpression              -> { types: [ 'BOOLEAN' ] }
  | ValueExpression_EDIT 'REGEXP' ValueExpression             -> { types: [ 'BOOLEAN' ] }
@@ -2161,11 +2175,29 @@ ValueExpression_EDIT
  | ValueExpression 'LIKE' ValueExpression_EDIT               -> { types: [ 'BOOLEAN' ] }
  | ValueExpression 'RLIKE' ValueExpression_EDIT              -> { types: [ 'BOOLEAN' ] }
  | ValueExpression 'REGEXP' ValueExpression_EDIT             -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'NOT' 'LIKE' PartialBacktickedOrCursor
+ | 'CURSOR' 'NOT' 'LIKE' ValueExpression
    {
-     suggestFunctions({ types: [ 'STRING' ] });
-     suggestColumns({ types: [ 'STRING' ] });
-     $$ = { types: ['BOOLEAN'] }
+     valueExpressionSuggest();
+     applyTypeToSuggestions([ 'STRING' ]);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ | 'CURSOR' 'LIKE' ValueExpression
+   {
+     valueExpressionSuggest();
+     applyTypeToSuggestions([ 'STRING' ]);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ | 'CURSOR' 'RLIKE' ValueExpression
+   {
+     valueExpressionSuggest();
+     applyTypeToSuggestions([ 'STRING' ]);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ | 'CURSOR' 'REGEXP' ValueExpression
+   {
+     valueExpressionSuggest();
+     applyTypeToSuggestions([ 'STRING' ]);
+     $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'LIKE' PartialBacktickedOrCursor
    {
@@ -2185,34 +2217,9 @@ ValueExpression_EDIT
      suggestColumns({ types: [ 'STRING' ] });
      $$ = { types: ['BOOLEAN'] }
    }
- | '(' ValueExpression_EDIT RightParenthesisOrError          -> $2
- | '(' AnyCursor RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     $$ = { types: ['T'] };
-   }
- | ValueExpression 'IS' 'NOT' 'CURSOR'
-   {
-     suggestKeywords(['NULL']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'IS' 'CURSOR'
-   {
-     suggestKeywords(['NOT NULL', 'NULL']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'IS' 'CURSOR' 'NULL'
-   {
-     suggestKeywords(['NOT']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'NOT' 'CURSOR'
-   {
-     suggestKeywords(['BETWEEN', 'EXISTS', 'IN', 'LIKE']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
  ;
 
+// IN
 ValueExpression_EDIT
  : ValueExpression 'NOT' 'IN' ValueExpressionInSecondPart_EDIT
    {
@@ -2248,6 +2255,7 @@ ValueExpressionInSecondPart_EDIT
  | '(' AnyCursor RightParenthesisOrError                -> { inValueEdit: true, cursorAtStart: true }
  ;
 
+// BETWEEN
 ValueExpression_EDIT
  : ValueExpression_EDIT 'NOT' 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression
    {
@@ -2325,45 +2333,30 @@ ValueExpression_EDIT
    }
  ;
 
+// COMPARISON
 ValueExpression_EDIT
- : ValueExpression '=' ValueExpression_EDIT
+ : 'CURSOR' '=' ValueExpression
    {
-     applyTypeToSuggestions($1.types);
-     addColRefIfExists($1);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression 'COMPARISON_OPERATOR' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions($1.types);
-     addColRefIfExists($1);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression '-' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($1);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression '*' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($1);
-     $$ = { types: [ 'NUMBER' ] };
+     valueExpressionSuggest($3);
+     applyTypeToSuggestions($3.types);
+     $$ = { types: [ 'BOOLEAN' ] };
    }
- | ValueExpression 'ARITHMETIC_OPERATOR' ValueExpression_EDIT
+ | 'CURSOR' 'COMPARISON_OPERATOR' ValueExpression
    {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($1);
-     $$ = { types: [ 'NUMBER' ] };
+     valueExpressionSuggest($3);
+     applyTypeToSuggestions($3.types);
+     $$ = { types: [ 'BOOLEAN' ] };
    }
- | ValueExpression 'OR' ValueExpression_EDIT
+ | ValueExpression_EDIT '=' ValueExpression
    {
-     addColRefIfExists($1);
+     applyTypeToSuggestions($3.types);
+     addColRefIfExists($3);
      $$ = { types: [ 'BOOLEAN' ] }
    }
- | ValueExpression 'AND' ValueExpression_EDIT
+ | ValueExpression_EDIT 'COMPARISON_OPERATOR' ValueExpression
    {
-     addColRefIfExists($1);
+     applyTypeToSuggestions($3.types);
+     addColRefIfExists($3);
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression '=' PartialBacktickedOrAnyCursor
@@ -2378,48 +2371,33 @@ ValueExpression_EDIT
      applyTypeToSuggestions($1.types);
      $$ = { types: [ 'BOOLEAN' ] };
    }
- | ValueExpression '-' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions(['NUMBER']);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression '*' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions(['NUMBER']);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression 'ARITHMETIC_OPERATOR' PartialBacktickedOrAnyCursor
+ | ValueExpression '=' ValueExpression_EDIT
    {
-     valueExpressionSuggest();
-     applyTypeToSuggestions(['NUMBER']);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression 'OR' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ 'BOOLEAN' ] };
+     applyTypeToSuggestions($1.types);
+     addColRefIfExists($1);
+     $$ = { types: [ 'BOOLEAN' ] }
    }
- | ValueExpression 'AND' PartialBacktickedOrAnyCursor
+ | ValueExpression 'COMPARISON_OPERATOR' ValueExpression_EDIT
    {
-     valueExpressionSuggest();
-     $$ = { types: [ 'BOOLEAN' ] };
+     applyTypeToSuggestions($1.types);
+     addColRefIfExists($1);
+     $$ = { types: [ 'BOOLEAN' ] }
    }
  ;
 
+// ARITHMETIC
 ValueExpression_EDIT
- : ValueExpression_EDIT '=' ValueExpression
+ : 'CURSOR' '*' ValueExpression
    {
-     applyTypeToSuggestions($3.types);
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
+     valueExpressionSuggest();
+     applyTypeToSuggestions([ 'NUMBER' ]);
+     $$ = { types: [ 'NUMBER' ] };
    }
- | ValueExpression_EDIT 'COMPARISON_OPERATOR' ValueExpression
+ | 'CURSOR' 'ARITHMETIC_OPERATOR' ValueExpression
    {
-     applyTypeToSuggestions($3.types);
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
+     valueExpressionSuggest();
+     applyTypeToSuggestions([ 'NUMBER' ]);
+     $$ = { types: [ 'NUMBER' ] };
    }
  | ValueExpression_EDIT '-' ValueExpression
    {
@@ -2439,50 +2417,86 @@ ValueExpression_EDIT
      addColRefIfExists($3);
      $$ = { types: [ 'NUMBER' ] }
    }
- | ValueExpression_EDIT 'OR' ValueExpression
+ | ValueExpression '-' PartialBacktickedOrAnyCursor
    {
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
+     valueExpressionSuggest();
+     applyTypeToSuggestions(['NUMBER']);
+     $$ = { types: [ 'NUMBER' ] };
    }
- | ValueExpression_EDIT 'AND' ValueExpression
+ | ValueExpression '*' PartialBacktickedOrAnyCursor
    {
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
+     valueExpressionSuggest();
+     applyTypeToSuggestions(['NUMBER']);
+     $$ = { types: [ 'NUMBER' ] };
    }
- | 'CURSOR' '=' ValueExpression
+ | ValueExpression 'ARITHMETIC_OPERATOR' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest($3);
-     applyTypeToSuggestions($3.types);
-     $$ = { types: [ 'BOOLEAN' ] };
+     valueExpressionSuggest();
+     applyTypeToSuggestions(['NUMBER']);
+     $$ = { types: [ 'NUMBER' ] };
    }
- | 'CURSOR' 'COMPARISON_OPERATOR' ValueExpression
+ | ValueExpression '-' ValueExpression_EDIT
    {
-     valueExpressionSuggest($3);
-     applyTypeToSuggestions($3.types);
-     $$ = { types: [ 'BOOLEAN' ] };
+     applyTypeToSuggestions(['NUMBER']);
+     addColRefIfExists($1);
+     $$ = { types: [ 'NUMBER' ] };
    }
- | 'CURSOR' '*' ValueExpression
+ | ValueExpression '*' ValueExpression_EDIT
    {
-     valueExpressionSuggest($3);
-     applyTypeToSuggestions([ 'NUMBER' ]);
+     applyTypeToSuggestions(['NUMBER']);
+     addColRefIfExists($1);
      $$ = { types: [ 'NUMBER' ] };
    }
- | 'CURSOR' 'ARITHMETIC_OPERATOR' ValueExpression
+ | ValueExpression 'ARITHMETIC_OPERATOR' ValueExpression_EDIT
    {
-     valueExpressionSuggest($3);
-     applyTypeToSuggestions([ 'NUMBER' ]);
+     applyTypeToSuggestions(['NUMBER']);
+     addColRefIfExists($1);
      $$ = { types: [ 'NUMBER' ] };
    }
- | 'CURSOR' 'OR' ValueExpression
+ ;
+
+// AND or OR
+ValueExpression_EDIT
+ : 'CURSOR' 'OR' ValueExpression
    {
-     valueExpressionSuggest($3);
+     valueExpressionSuggest();
      $$ = { types: [ 'BOOLEAN' ] };
    }
+ | ValueExpression_EDIT 'OR' ValueExpression
+   {
+     addColRefIfExists();
+     $$ = { types: [ 'BOOLEAN' ] }
+   }
+ | ValueExpression 'OR' PartialBacktickedOrAnyCursor
+   {
+     valueExpressionSuggest();
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ | ValueExpression 'OR' ValueExpression_EDIT
+   {
+     addColRefIfExists($1);
+     $$ = { types: [ 'BOOLEAN' ] }
+   }
  | 'CURSOR' 'AND' ValueExpression
    {
-     valueExpressionSuggest($3);
+     valueExpressionSuggest();
      $$ = { types: [ 'BOOLEAN' ] };
    }
+ | ValueExpression_EDIT 'AND' ValueExpression
+   {
+     addColRefIfExists($3);
+     $$ = { types: [ 'BOOLEAN' ] }
+   }
+ | ValueExpression 'AND' PartialBacktickedOrAnyCursor
+   {
+     valueExpressionSuggest();
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ | ValueExpression 'AND' ValueExpression_EDIT
+   {
+     addColRefIfExists($1);
+     $$ = { types: [ 'BOOLEAN' ] }
+   }
  ;
 
 ValueExpressionList
@@ -3157,35 +3171,6 @@ OptionalLateralViews_EDIT
  : OptionalLateralViews LateralView_EDIT OptionalLateralViews
  ;
 
-// TODO: '<hive>[pos]explode' '(' 'CURSOR' possible?
-UserDefinedTableGeneratingFunction
- : '<hive>EXPLODE(' DerivedColumnChain ')'
-   {
-     addColumnLocation(@2, $2);
-     $$ = { function: $1.substring(0, $1.length - 1), expression: $2 }
-   }
- | '<hive>POSEXPLODE(' DerivedColumnChain ')'
-   {
-     addColumnLocation(@2, $2);
-     $$ = { function: $1.substring(0, $1.length - 1), expression: $2 }
-   }
- ;
-
-UserDefinedTableGeneratingFunction_EDIT
- : '<hive>EXPLODE(' DerivedColumnChain_EDIT error
-   {
-     suggestColumns($2);
-   }
- | '<hive>POSEXPLODE(' PartialBacktickedOrPartialCursor error
-   {
-     suggestColumns();
-   }
- ;
-
-GroupingOperation
- : 'GROUPING' '(' ColumnReferenceList ')'
- ;
-
 UserDefinedFunction
  : ArbitraryFunction
  | AggregateFunction
@@ -4118,7 +4103,6 @@ UpdateStatement
 
 UpdateStatement_EDIT
  : 'UPDATE' TargetTable_EDIT 'SET' SetClauseList OptionalWhereClause
-   }
  | 'UPDATE' TargetTable 'SET' SetClauseList_EDIT OptionalWhereClause
  | 'UPDATE' TargetTable 'SET' SetClauseList OptionalWhereClause_EDIT
  | 'UPDATE' TargetTable 'SET' SetClauseList OptionalWhereClause 'CURSOR'
@@ -4236,7 +4220,7 @@ var prepareNewStatement = function () {
   parser.yy.subQueries = [];
 
   parser.parseError = function (message, error) {
-    parser.yy.result.error = error;
+    parser.yy.errors.push(error);
     return message;
   };
 }
@@ -4936,6 +4920,7 @@ parser.parseSql = function(beforeCursor, afterCursor, dialect, sqlFunctions, deb
   parser.yy.locations = [];
   parser.yy.allLocations = [];
   parser.yy.subQueries = [];
+  parser.yy.errors = [];
 
   delete parser.yy.cursorFound;
   delete parser.yy.partialCursor;
@@ -4956,13 +4941,14 @@ parser.parseSql = function(beforeCursor, afterCursor, dialect, sqlFunctions, deb
 
   // Hack to set the inital state of the lexer without first having to hit a token
   // has to be done as the first token found can be dependant on dialect
-  if (!lexerModified && typeof dialect !== 'undefined') {
+  if (!lexerModified) {
     var originalSetInput = parser.lexer.setInput;
-    parser.lexer.setInput = function (input) {
-      var lexer = originalSetInput.bind(parser.lexer)(input);
+    parser.lexer.setInput = function (input, yy) {
+      var lexer = originalSetInput.bind(parser.lexer)(input, yy);
       if (typeof parser.yy.activeDialect !== 'undefined') {
         lexer.begin(parser.yy.activeDialect);
       }
+      return lexer;
     }
     lexerModified = true;
   }
@@ -4980,11 +4966,14 @@ parser.parseSql = function(beforeCursor, afterCursor, dialect, sqlFunctions, deb
       console.log(err);
       console.error(err.stack);
     }
-    if (parser.yy.result.error && !parser.yy.result.error.recoverable) {
-      console.log(parser.yy.result.error);
-    }
     result = parser.yy.result;
   }
+  if (parser.yy.errors.length > 0) {
+    parser.yy.result.errors = parser.yy.errors;
+    if (debug) {
+      console.log(parser.yy.errors);
+    }
+  }
   linkTablePrimaries();
   commitLocations();
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js


+ 1 - 1
desktop/core/src/desktop/static/desktop/js/sqlAutocompleter2.js

@@ -39,7 +39,7 @@
 
   SqlAutocompleter2.prototype.autocomplete = function (beforeCursor, afterCursor, callback, editor) {
     var self = this;
-    var parseResult = sqlParser.parseSql(beforeCursor, afterCursor, self.snippet.type(), sqlFunctions, true);
+    var parseResult = sqlParser.parseSql(beforeCursor, afterCursor, self.snippet.type(), sqlFunctions, false);
 
     var deferrals = [];
     var completions = [];

+ 49 - 0
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecSelect.js

@@ -3135,6 +3135,20 @@ define([
         });
       });
 
+      it('should suggest keywords for "SELECT cast(\'1\' AS | b, c bla, d"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT cast(\'1\' AS ',
+          afterCursor: ' b, c bla, d',
+          dialect: 'impala',
+          containsKeywords: ['BIGINT', 'REAL'],
+          doesNotContainKeywords: ['DATE'],
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
       it('should suggest columns for "SELECT cos(| FROM testTable"', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT cos(',
@@ -3191,6 +3205,20 @@ define([
         });
       });
 
+      it('should suggest typed columns for "SELECT a, ceiling(| b, c AS bla, d FROM testTable"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT ceiling(',
+          afterCursor: ' b, c AS bla, d FROM testTable',
+          dialect: 'impala',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: { types: ['DECIMAL', 'DOUBLE'] },
+            suggestColumns: { types: ['DECIMAL', 'DOUBLE'], table: 'testTable' }
+          }
+        });
+      });
+
       it('should not suggest columns for "SELECT cos(1, | FROM testTable"', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT cos(1, ',
@@ -5548,6 +5576,27 @@ define([
         });
       });
 
+      it('should suggest identifiers for "SELECT cos(| FROM (SELECT b FROM foo) boo, (SELECT a FROM bla) bar"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT cos(',
+          afterCursor: ' FROM (SELECT b FROM foo) boo, (SELECT a FROM bla) bar',
+          hasLocations: true,
+          dialect: 'generic',
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: { types: ['T'] },
+            subQueries: [{
+              alias: 'boo',
+              columns: [{ identifierChain: [{ name: 'b' }], type: 'COLREF', table: 'foo' }]
+            }, {
+              alias: 'bar',
+              columns: [{ identifierChain: [{ name: 'a' }], type: 'COLREF', table: 'bla' }]
+            }],
+            suggestIdentifiers: [{ name: 'boo.', type: 'sub-query' }, { name: 'bar.', type: 'sub-query' }]
+          }
+        });
+      });
+
       it('should suggest tables for "SELECT * FROM (SELECT |)"', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT * FROM (SELECT ',

+ 8 - 2
desktop/core/src/desktop/static/desktop/spec/autocompleterTestUtils.js

@@ -41,8 +41,14 @@ define([
       toEqualDefinition : function() {
         return {
           compare: function(actualResponse, testDefinition) {
-            if (testDefinition.ignoreErrors) {
-              delete actualResponse.error;
+            if (actualResponse.errors) {
+              var allRecoverable = true;
+              actualResponse.errors.forEach(function (error) {
+                allRecoverable = allRecoverable && error.recoverable;
+              });
+              if (allRecoverable) {
+                delete actualResponse.errors;
+              }
             }
             if (testDefinition.hasLocations) {
               if (actualResponse.locations.length === 0) {

+ 1 - 1
tools/jison/hue-jison.sh

@@ -16,7 +16,7 @@
 # limitations under the License.
 
 echo "Generating parser..."
-npm install jison -g
+# npm install jison -g
 jison ../../desktop/core/src/desktop/static/desktop/js/autocomplete/sql.jison -m amd
 cat license.txt sql.js > ../../desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js
 rm sql.js

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác