Pārlūkot izejas kodu

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 9 gadi atpakaļ
vecāks
revīzija
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();
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 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

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