浏览代码

HUE-4377 [editor] Autocompleter should support variable references like '${var}' in statements

Johan Ahlen 9 年之前
父节点
当前提交
98700202af

+ 12 - 9
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.jison

@@ -17,7 +17,7 @@
 %lex
 %options case-insensitive flex
 %s between hive impala
-%x hdfs DoubleQuotedValue SingleQuotedValue backtickedValue
+%x hdfs doubleQuotedValue singleQuotedValue backtickedValue
 %%
 
 [ \t\n]                             { /* skip whitespace */ }
@@ -279,6 +279,8 @@
 '['                                 { return '['; }
 ']'                                 { return ']'; }
 
+\$\{[^}]*\}                         { return 'VARIABLE_REFERENCE'; }
+
 \`                                  { this.begin('backtickedValue'); return 'BACKTICK'; }
 <backtickedValue>[^`]+              {
                                       if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) {
@@ -289,16 +291,18 @@
                                     }
 <backtickedValue>\`                 { this.popState(); return 'BACKTICK'; }
 
-\'                                  { this.begin('SingleQuotedValue'); return 'SINGLE_QUOTE'; }
-<SingleQuotedValue>[^']+            { return 'VALUE'; }
-<SingleQuotedValue>\'               { this.popState(); return 'SINGLE_QUOTE'; }
+\'                                  { this.begin('singleQuotedValue'); return 'SINGLE_QUOTE'; }
+<singleQuotedValue>[^']+            { return 'VALUE'; }
+<singleQuotedValue>\'               { this.popState(); return 'SINGLE_QUOTE'; }
 
-\"                                  { this.begin('DoubleQuotedValue'); return 'DOUBLE_QUOTE'; }
-<DoubleQuotedValue>[^"]+            { return 'VALUE'; }
-<DoubleQuotedValue>\"               { this.popState(); return 'DOUBLE_QUOTE'; }
+\"                                  { this.begin('doubleQuotedValue'); return 'DOUBLE_QUOTE'; }
+<doubleQuotedValue>[^"]+            { return 'VALUE'; }
+<doubleQuotedValue>\"               { this.popState(); return 'DOUBLE_QUOTE'; }
 
 <<EOF>>                             { return 'EOF'; }
 
+.                                   { /* Ignore anything else, to prevent console logging */ }
+
 /lex
 
 /* operators and precedence levels */
@@ -361,6 +365,7 @@ NonReservedKeyword
 
 RegularIdentifier
  : 'REGULAR_IDENTIFIER'
+ | 'VARIABLE_REFERENCE'
  | NonReservedKeyword
  ;
 
@@ -2515,12 +2520,10 @@ RightPart_EDIT
  | PartialBacktickedIdentifier
  ;
 
-// TODO: Expand with more choices
 NonParenthesizedValueExpressionPrimary
  : UnsignedValueSpecification
  | ColumnReference             -> { types: ['COLREF'], columnReference: $1 }
  | UserDefinedFunction
-// | GroupingOperation
  | 'NULL'                      -> { types: [ 'NULL' ] }
  ;
 

文件差异内容过多而无法显示
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js


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

@@ -72,7 +72,15 @@
         colRefDeferral.resolve();
       };
 
-      self.fetchFieldsForIdentifiers(editor, parseResult.colRef.table, parseResult.colRef.database || database, parseResult.colRef.identifierChain, colRefCallback, colRefDeferral.resolve);
+      var foundVarRef = parseResult.colRef.identifierChain.filter(function (identifier) {
+        return identifier.name.indexOf('${') === 0;
+      });
+
+      if (foundVarRef.length > 0) {
+        colRefCallback({ type: 'T' });
+      } else {
+        self.fetchFieldsForIdentifiers(editor, parseResult.colRef.table, parseResult.colRef.database || database, parseResult.colRef.identifierChain, colRefCallback, colRefDeferral.resolve);
+      }
 
     } else {
       colRefDeferral.resolve();

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

@@ -944,6 +944,50 @@ define([
       });
     });
 
+    describe('Variable References', function () {
+      it('should suggest tables for "SELECT | FROM ${some_variable};"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT ',
+          afterCursor: ' FROM ${some_variable};',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['*', 'ALL', 'DISTINCT'],
+            suggestAggregateFunctions: true,
+            suggestFunctions: {},
+            suggestColumns: {table: '${some_variable}'}
+          }
+        });
+      });
+
+      it('should suggest tables for "SELECT * FROM testTable WHERE ${some_variable} |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM testTable WHERE ${some_variable} ',
+          afterCursor: '',
+          hasLocations: true,
+          containsKeywords: ['<', 'BETWEEN'],
+          containsColRefKeywords: true,
+          expectedResult: {
+            lowerCase: false,
+            colRef: { identifierChain:[{ name: '${some_variable}' }], table: 'testTable'}
+          }
+        });
+      });
+
+      it('should suggest tables for "SELECT * FROM testTable WHERE ${some_variable} + 1 = |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM testTable WHERE ${some_variable} + 1 = ',
+          afterCursor: '',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: { types: ['NUMBER']},
+            suggestColumns: { types: ['NUMBER'], table: 'testTable'}
+          }
+        });
+      });
+    });
+
     describe('Functions', function () {
       it('should suggest tables for "SELECT COUNT(*) |"', function() {
         assertAutoComplete({

部分文件因为文件数量过多而无法显示