瀏覽代碼

HUE-6890 [autocomplete] Add support for database prefixed UDFs

Johan Ahlen 8 年之前
父節點
當前提交
f0456e2633

+ 5 - 8
desktop/core/src/desktop/static/desktop/js/autocomplete/globalSearchParser.js

@@ -154,13 +154,9 @@ parseError: function parseError(str, hash) {
     if (hash.recoverable) {
         this.trace(str);
     } else {
-        function _parseError (msg, hash) {
-            this.message = msg;
-            this.hash = hash;
-        }
-        _parseError.prototype = Error;
-
-        throw new _parseError(str, hash);
+        var error = new Error(str);
+        error.hash = hash;
+        throw error;
     }
 },
 parse: function parse(input) {
@@ -229,7 +225,8 @@ parse: function parse(input) {
                     text: lexer.match,
                     token: this.terminals_[symbol] || symbol,
                     line: lexer.yylineno,
-                    loc: yyloc,
+                    loc: lexer.yylloc,
+                    ruleId: stack.slice(stack.length - 2, stack.length).join('_'),
                     expected: expected
                 });
             }

+ 2 - 2
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_error.jison

@@ -81,8 +81,8 @@ ErrorList
  ;
 
 LateralView
- : '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction RegularOrBacktickedIdentifier '<hive>AS' error  -> { }
- | '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction error                                           -> { }
+ : '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction RegularOrBacktickedIdentifier '<hive>AS' error  -> { }
+ | '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction error                                           -> { }
  | '<hive>LATERAL' '<hive>VIEW' OptionalOuter error                                                               -> { }
  | '<hive>LATERAL' error                                                                                          -> { }
  ;

+ 0 - 5
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_insert.jison

@@ -309,11 +309,6 @@ OptionalTable
  | 'TABLE'
  ;
 
-AnyInsert
- : '<hive>INSERT'
- | 'INSERT'
- ;
-
 OptionalInsertRowFormat
  :
  | 'ROW' '<hive>FORMAT' HiveDelimitedRowFormat

+ 99 - 107
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_main.jison

@@ -406,11 +406,6 @@ HiveOrImpalaCreate
  | '<impala>CREATE'
  ;
 
-HiveOrImpalaCurrent
- : '<hive>CURRENT'
- | '<impala>CURRENT'
- ;
-
 HiveOrImpalaDatabasesOrSchemas
  : '<hive>DATABASES'
  | '<hive>SCHEMAS'
@@ -423,11 +418,6 @@ HiveOrImpalaEscaped
  | '<impala>ESCAPED'
  ;
 
-HiveOrImpalaExternal
- : '<hive>EXTERNAL'
- | '<impala>EXTERNAL'
- ;
-
 HiveOrImpalaFields
  : '<hive>FIELDS'
  | '<impala>FIELDS'
@@ -1062,25 +1052,14 @@ DerivedColumnChain_EDIT
  ;
 
 ColumnIdentifier
- : RegularOrBacktickedIdentifier OptionalMapOrArrayKey
-   {
-     if ($2) {
-       $$ = { name: $1, keySet: true };
-     } else {
-       $$ = { name: $1 };
-     }
-   }
+ : RegularOrBacktickedIdentifier                                                                               -> { name: $1 };
+ | RegularOrBacktickedIdentifier HiveOrImpalaLeftSquareBracket ValueExpression HiveOrImpalaRightSquareBracket  -> { name: $1, keySet: true }
+ | RegularOrBacktickedIdentifier HiveOrImpalaLeftSquareBracket HiveOrImpalaRightSquareBracket                  -> { name: $1, keySet: true }
  ;
 
 ColumnIdentifier_EDIT
- : RegularOrBacktickedIdentifier HiveOrImpalaLeftSquareBracket AnyCursor HiveOrImpalaRightSquareBracketOrError
-   {
-     $$ = { name: $1, insideKey: true }
-   }
- | RegularOrBacktickedIdentifier HiveOrImpalaLeftSquareBracket ValueExpression_EDIT HiveOrImpalaRightSquareBracketOrError
-   {
-     $$ = { name: $1 }
-   }
+ : RegularOrBacktickedIdentifier HiveOrImpalaLeftSquareBracket AnyCursor HiveOrImpalaRightSquareBracketOrError             -> { name: $1, insideKey: true }
+ | RegularOrBacktickedIdentifier HiveOrImpalaLeftSquareBracket ValueExpression_EDIT HiveOrImpalaRightSquareBracketOrError  -> { name: $1 };
  ;
 
 PartialBacktickedIdentifierOrPartialCursor
@@ -1088,12 +1067,6 @@ PartialBacktickedIdentifierOrPartialCursor
  | 'PARTIAL_CURSOR'
  ;
 
-OptionalMapOrArrayKey
- :
- | HiveOrImpalaLeftSquareBracket ValueExpression HiveOrImpalaRightSquareBracket
- | HiveOrImpalaLeftSquareBracket HiveOrImpalaRightSquareBracket
- ;
-
 HiveOrImpalaRightSquareBracketOrError
  : HiveOrImpalaRightSquareBracket
  | error
@@ -1289,16 +1262,6 @@ QuerySpecification_EDIT
  | CommonTableExpression_EDIT SelectStatement OptionalUnions
  ;
 
-OptionallyParenthesizedSelectStatement
- : SelectStatement
- | '(' SelectStatement ')' // Impala specific
- ;
-
-OptionallyParenthesizedSelectStatement_EDIT
- : SelectStatement_EDIT
- | '(' SelectStatement_EDIT RightParenthesisOrError
- ;
-
 SelectStatement
  : 'SELECT' OptionalAllOrDistinct SelectList                  -> { selectList: $3 }
  | 'SELECT' OptionalAllOrDistinct SelectList TableExpression  -> { selectList: $3, tableExpression: $4 }
@@ -2273,17 +2236,42 @@ InValueList
  | InValueList ',' NonParenthesizedValueExpressionPrimary
  ;
 
-InValueList_EDIT
- : NonParenthesizedValueExpressionPrimary_EDIT
- | InValueList ',' AnyCursor
- | InValueList ',' NonParenthesizedValueExpressionPrimary_EDIT
- | InValueList ',' NonParenthesizedValueExpressionPrimary_EDIT ',' InValueList
- | NonParenthesizedValueExpressionPrimary_EDIT ',' InValueList
- ;
-
 NonParenthesizedValueExpressionPrimary
  : UnsignedValueSpecification
- | ColumnReference             -> { types: ['COLREF'], columnReference: $1 }
+ | ColumnOrArbitraryFunctionRef             -> { types: ['COLREF'], columnReference: $1.chain }
+ | ColumnOrArbitraryFunctionRef ArbitraryFunctionRightPart
+   {
+     // We need to handle arbitrary UDFs here instead of inside UserDefinedFunction or there will be a conflict
+     // with columnReference for functions like: db.udf(foo)
+     var fn = $1.chain[$1.chain.length - 1].name.toLowerCase();
+     $1.lastLoc.type = 'function';
+     $1.lastLoc.function = fn;
+     $1.lastLoc.location = {
+       first_line: $1.lastLoc.location.first_line,
+       last_line: $1.lastLoc.location.last_line,
+       first_column: $1.lastLoc.location.first_column,
+       last_column: $1.lastLoc.location.last_column - 1
+     }
+     if ($1.lastLoc !== $1.firstLoc) {
+        $1.firstLoc.type = 'database';
+     } else {
+       delete $1.lastLoc.identifierChain;
+     }
+     if ($2.expression) {
+       $$ = { function: fn, expression: $2.expression, types: parser.findReturnTypes(fn) }
+     } else {
+       $$ = { function: fn, types: parser.findReturnTypes(fn) }
+     }
+   }
+ | ArbitraryFunctionName ArbitraryFunctionRightPart
+  {
+    parser.addFunctionLocation(@1, $1);
+    if ($2.expression) {
+      $$ = { function: $1, expression: $2.expression, types: parser.findReturnTypes($1) }
+    } else {
+      $$ = { function: $1, types: parser.findReturnTypes($1) }
+    }
+  }
  | UserDefinedFunction
  | 'NULL'                      -> { types: [ 'NULL' ] }
  | ImpalaInterval              -> { types: [ 'TIMESTAMP' ] }
@@ -2291,7 +2279,7 @@ NonParenthesizedValueExpressionPrimary
 
 NonParenthesizedValueExpressionPrimary_EDIT
  : UnsignedValueSpecification_EDIT
- | ColumnReference_EDIT
+ | ColumnOrArbitraryFunctionRef_EDIT
    {
      if ($1.suggestKeywords) {
        $$ = { types: ['COLREF'], columnReference: $1, suggestKeywords: $1.suggestKeywords };
@@ -2299,10 +2287,58 @@ NonParenthesizedValueExpressionPrimary_EDIT
        $$ = { types: ['COLREF'], columnReference: $1 };
      }
    }
+ | ColumnOrArbitraryFunctionRef ArbitraryFunctionRightPart_EDIT
+   {
+     var fn = $1.chain[$1.chain.length - 1].name.toLowerCase();
+     $1.lastLoc.type = 'function';
+     $1.lastLoc.function = fn;
+     $1.lastLoc.location = {
+       first_line: $1.lastLoc.location.first_line,
+       last_line: $1.lastLoc.location.last_line,
+       first_column: $1.lastLoc.location.first_column,
+       last_column: $1.lastLoc.location.last_column - 1
+     }
+     if ($1.lastLoc !== $1.firstLoc) {
+        $1.firstLoc.type = 'database';
+     } else {
+       delete $1.lastLoc.identifierChain;
+     }
+     if ($2.position) {
+       parser.applyArgumentTypesToSuggestions(fn, $2.position);
+     }
+     $$ = { types: parser.findReturnTypes(fn) };
+   }
+ | ArbitraryFunctionName ArbitraryFunctionRightPart_EDIT
+   {
+     parser.addFunctionLocation(@1, $1);
+     if ($2.position) {
+       parser.applyArgumentTypesToSuggestions($1, $2.position);
+     }
+     $$ = { types: parser.findReturnTypes($1) };
+   }
  | UserDefinedFunction_EDIT
  | ImpalaInterval_EDIT
  ;
 
+ColumnOrArbitraryFunctionRef
+ : BasicIdentifierChain
+   {
+     var lastLoc = parser.yy.locations[parser.yy.locations.length - 1];
+     lastLoc.type = 'column';
+     // used for function references with db prefix
+     var firstLoc = parser.yy.locations[parser.yy.locations.length - $1.length];
+     $$ = { chain: $1, firstLoc: firstLoc, lastLoc: lastLoc }
+   }
+ | BasicIdentifierChain AnyDot '*'
+   {
+     parser.addAsteriskLocation(@3, $1.concat({ asterisk: true }));
+   }
+ ;
+
+ColumnOrArbitraryFunctionRef_EDIT
+ : BasicIdentifierChain_EDIT
+ ;
+
 ImpalaInterval
  : '<impala>INTERVAL' SignedInteger RegularIdentifier
  ;
@@ -2464,48 +2500,6 @@ SelectList_EDIT
  | SelectList ',' SelectSpecification_EDIT ',' SelectList  -> $3
  ;
 
-DerivedColumn_TWO
- : ColumnIdentifier
-   {
-     parser.addColumnLocation(@1, [$1]);
-   }
- | ColumnIdentifier AnyDot '*'
-   {
-     parser.addColumnLocation(@1, [$1]);
-   }
- | ColumnIdentifier AnyDot DerivedColumnChain
-   {
-     parser.addColumnLocation(@2, [$1].concat($3));
-   }
- ;
-
-DerivedColumn_EDIT_TWO
- : ColumnIdentifier AnyDot PartialBacktickedOrPartialCursor
-   {
-     // TODO: Check if valid: SELECT testMap["key"].* FROM foo
-     if (typeof $1.key === 'undefined') {
-       parser.yy.result.suggestStar = true;
-     }
-     parser.suggestColumns({
-       identifierChain: [ $1 ]
-     });
-   }
- | ColumnIdentifier AnyDot DerivedColumnChain '<impala>.' 'PARTIAL_CURSOR'
-   {
-      $3.unshift($1);
-      parser.suggestColumns({
-        identifierChain: $3
-      });
-    }
- | ColumnIdentifier AnyDot DerivedColumnChain '<hive>.' 'PARTIAL_CURSOR'
-   {
-      $3.unshift($1);
-      parser.suggestColumns({
-        identifierChain: $3
-      });
-    }
- ;
-
 TableReferenceList
  : TableReference
  | TableReferenceList ',' TableReference  -> $3
@@ -2999,8 +2993,7 @@ OptionalLateralViews_EDIT
  ;
 
 UserDefinedFunction
- : ArbitraryFunction
- | AggregateFunction OptionalOverClause
+ : AggregateFunction OptionalOverClause
    {
      if (!$2) {
        $1.suggestKeywords = ['OVER'];
@@ -3013,8 +3006,7 @@ UserDefinedFunction
  ;
 
 UserDefinedFunction_EDIT
- : ArbitraryFunction_EDIT
- | AggregateFunction_EDIT
+ : AggregateFunction_EDIT
  | AggregateFunction OptionalOverClause_EDIT
  | AnalyticFunction_EDIT
  | AnalyticFunction_EDIT OverClause
@@ -3711,8 +3703,8 @@ SumFunction_EDIT
  ;
 
 LateralView
- : '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction RegularOrBacktickedIdentifier LateralViewColumnAliases  -> { lateralView: { udtf: $4, tableAlias: $5, columnAliases: $6 }}
- | '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction RegularOrBacktickedIdentifier
+ : '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction RegularOrBacktickedIdentifier LateralViewColumnAliases  -> { lateralView: { udtf: $4, tableAlias: $5, columnAliases: $6 }}
+ | '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction RegularOrBacktickedIdentifier
    {
      if ($4.function.toLowerCase() === 'explode') {
        $$ = { lateralView: { udtf: $4, tableAlias: $5, columnAliases: ['key', 'value'] }, suggestKeywords: ['AS'] };
@@ -3722,16 +3714,16 @@ LateralView
        $$ = { lateralView: { udtf: $4, tableAlias: $5, columnAliases: [] }, suggestKeywords: ['AS'] };
      }
    }
- | '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction LateralViewColumnAliases                                -> { lateralView: { udtf: $4, columnAliases: $5 }}
+ | '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction LateralViewColumnAliases                                -> { lateralView: { udtf: $4, columnAliases: $5 }}
  ;
 
 LateralView_EDIT
- : '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction_EDIT
- | '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction_EDIT RegularOrBacktickedIdentifier
- | '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction_EDIT RegularOrBacktickedIdentifier LateralViewColumnAliases
- | '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction RegularOrBacktickedIdentifier LateralViewColumnAliases_EDIT
- | '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction PartialBacktickedOrCursor
- | '<hive>LATERAL' '<hive>VIEW' OptionalOuter UserDefinedFunction PartialBacktickedOrCursor LateralViewColumnAliases
+ : '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction_EDIT
+ | '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction_EDIT RegularOrBacktickedIdentifier
+ | '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction_EDIT RegularOrBacktickedIdentifier LateralViewColumnAliases
+ | '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction RegularOrBacktickedIdentifier LateralViewColumnAliases_EDIT
+ | '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction PartialBacktickedOrCursor
+ | '<hive>LATERAL' '<hive>VIEW' OptionalOuter ArbitraryFunction PartialBacktickedOrCursor LateralViewColumnAliases
  | '<hive>LATERAL' '<hive>VIEW' OptionalOuter 'CURSOR'
    {
      if (!$3) {

+ 0 - 60
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_valueExpression_dev.jison

@@ -282,11 +282,6 @@ HiveOrImpalaCreate
  | '<impala>CREATE'
  ;
 
-HiveOrImpalaCurrent
- : '<hive>CURRENT'
- | '<impala>CURRENT'
- ;
-
 HiveOrImpalaDatabasesOrSchemas
  : '<hive>DATABASES'
  | '<hive>SCHEMAS'
@@ -299,11 +294,6 @@ HiveOrImpalaEscaped
  | '<impala>ESCAPED'
  ;
 
-HiveOrImpalaExternal
- : '<hive>EXTERNAL'
- | '<impala>EXTERNAL'
- ;
-
 HiveOrImpalaFields
  : '<hive>FIELDS'
  | '<impala>FIELDS'
@@ -1758,14 +1748,6 @@ InValueList
  | InValueList ',' NonParenthesizedValueExpressionPrimary
  ;
 
-InValueList_EDIT
- : NonParenthesizedValueExpressionPrimary_EDIT
- | InValueList ',' AnyCursor
- | InValueList ',' NonParenthesizedValueExpressionPrimary_EDIT
- | InValueList ',' NonParenthesizedValueExpressionPrimary_EDIT ',' InValueList
- | NonParenthesizedValueExpressionPrimary_EDIT ',' InValueList
- ;
-
 NonParenthesizedValueExpressionPrimary
  : UnsignedValueSpecification
  | ColumnReference             -> { types: ['COLREF'], columnReference: $1 }
@@ -1948,48 +1930,6 @@ SelectList_EDIT
  | SelectList ',' SelectSpecification_EDIT ',' SelectList  -> $3
  ;
 
-DerivedColumn_TWO
- : ColumnIdentifier
-   {
-     parser.addColumnLocation(@1, [$1]);
-   }
- | ColumnIdentifier AnyDot '*'
-   {
-     parser.addColumnLocation(@1, [$1]);
-   }
- | ColumnIdentifier AnyDot DerivedColumnChain
-   {
-     parser.addColumnLocation(@2, [$1].concat($3));
-   }
- ;
-
-DerivedColumn_EDIT_TWO
- : ColumnIdentifier AnyDot PartialBacktickedOrPartialCursor
-   {
-     // TODO: Check if valid: SELECT testMap["key"].* FROM foo
-     if (typeof $1.key === 'undefined') {
-       parser.yy.result.suggestStar = true;
-     }
-     parser.suggestColumns({
-       identifierChain: [ $1 ]
-     });
-   }
- | ColumnIdentifier AnyDot DerivedColumnChain '<impala>.' 'PARTIAL_CURSOR'
-   {
-      $3.unshift($1);
-      parser.suggestColumns({
-        identifierChain: $3
-      });
-    }
- | ColumnIdentifier AnyDot DerivedColumnChain '<hive>.' 'PARTIAL_CURSOR'
-   {
-      $3.unshift($1);
-      parser.suggestColumns({
-        identifierChain: $3
-      });
-    }
- ;
-
 TableReferenceList
  : TableReference
  | TableReferenceList ',' TableReference  -> $3

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

@@ -1798,6 +1798,51 @@
         });
       });
 
+      it('should suggest handle "SELECT db.customUdf(col) FROM bar;"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT db.customUdf(col) FROM bar;',
+          afterCursor: '',
+          containsKeywords: ['SELECT'],
+          noErrors: true,
+          expectedResult: {
+            lowerCase: false,
+            locations: [
+              { type: 'statement', location: { first_line: 1, last_line: 1, first_column: 1, last_column: 34 } },
+              { type: 'database', location: { first_line: 1, last_line: 1, first_column: 8, last_column: 10 }, identifierChain: [{ name: 'db' }] },
+              { type: 'function', location: { first_line: 1, last_line: 1, first_column: 11, last_column: 19 }, identifierChain: [{ name: 'db' }, { name: 'customUdf' }], function: 'customudf' },
+              { type: 'column', location: { first_line: 1, last_line: 1, first_column: 21, last_column: 24 }, identifierChain: [{ name: 'col' }], tables: [{ identifierChain: [{ name: 'bar' }] }] },
+              { type: 'table', location: { first_line: 1, last_line: 1, first_column: 31, last_column: 34 }, identifierChain: [{ name: 'bar' }] }
+            ]
+          }
+        });
+      });
+
+      it('should suggest columns for "SELECT db.customUdf(| FROM bar;"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT db.customUdf(',
+          afterCursor: ' FROM bar;',
+          containsKeywords: ['CASE'],
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: { types: ['T'] },
+            suggestColumns: { types: ['T'], source: 'select', tables: [{ identifierChain: [{ name: 'bar' }] }] }
+          }
+        });
+      });
+
+      it('should suggest columns for "SELECT db.customUdf(1, | FROM bar;"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT db.customUdf(1, ',
+          afterCursor: ' FROM bar;',
+          containsKeywords: ['CASE'],
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: { types: ['T'] },
+            suggestColumns: { types: ['T'], source: 'select', tables: [{ identifierChain: [{ name: 'bar' }] }] }
+          }
+        });
+      });
+
       it('should suggest keywords for "SELECT extract(| FROM bar;"', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT extract( ',

文件差異過大導致無法顯示
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlAutocompleteParser.js


+ 5 - 8
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlStatementsParser.js

@@ -177,13 +177,9 @@ parseError: function parseError(str, hash) {
     if (hash.recoverable) {
         this.trace(str);
     } else {
-        function _parseError (msg, hash) {
-            this.message = msg;
-            this.hash = hash;
-        }
-        _parseError.prototype = Error;
-
-        throw new _parseError(str, hash);
+        var error = new Error(str);
+        error.hash = hash;
+        throw error;
     }
 },
 parse: function parse(input) {
@@ -252,7 +248,8 @@ parse: function parse(input) {
                     text: lexer.match,
                     token: this.terminals_[symbol] || symbol,
                     line: lexer.yylineno,
-                    loc: yyloc,
+                    loc: lexer.yylloc,
+                    ruleId: stack.slice(stack.length - 2, stack.length).join('_'),
                     expected: expected
                 });
             }

文件差異過大導致無法顯示
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlSyntaxParser.js


部分文件因文件數量過多而無法顯示