浏览代码

HUE-4173 [editor] Enable autocomplete when there are backticks in table and database names

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

+ 102 - 38
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.jison

@@ -17,7 +17,7 @@
 %lex
 %options case-insensitive
 %s hive impala
-%x hdfs stringValue
+%x hdfs singleQuotedValue backtickedValue
 %%
 
 [ \t\n]                             { /* skip whitespace */ }
@@ -92,16 +92,26 @@
 <hdfs>[']                           { this.popState(); return 'HDFS_END_QUOTE'; }
 <hdfs><<EOF>>                       { return 'EOF'; }
 
-<stringValue>[^']+                  { return 'VALUE'; }
-<stringValue>\'                     { this.popState(); return 'SINGLE_QUOTE'; }
-
 [-+&~|^/%*(),.;!]                   { return yytext; }
 [=<>]                               { return yytext; }
 
+
 \[                                  { return '['; }
 \]                                  { return ']'; }
 
-\'                                  { this.begin('stringValue'); return 'SINGLE_QUOTE'; }
+\`                                  { this.begin('backtickedValue'); return 'BACKTICK'; }
+<backtickedValue>[^`]+              { if (yytext.indexOf('CURSOR|') !== -1) {
+                                        this.popState();
+                                        return 'PARTIAL_VALUE';
+                                      }
+                                      return 'VALUE';
+                                    }
+<backtickedValue>\`                 { this.popState(); return 'BACKTICK'; }
+
+\'                                  { this.begin('singleQuotedValue'); return 'SINGLE_QUOTE'; }
+<singleQuotedValue>[^']+            { return 'VALUE'; }
+<singleQuotedValue>\'               { this.popState(); return 'SINGLE_QUOTE'; }
+
 \"                                  { return 'DOUBLE_QUOTE'; }
 
 <<EOF>>                             { return 'EOF'; }
@@ -269,28 +279,15 @@ TargetTable
 
 TableName
  : LocalOrSchemaQualifiedName
- ;
-
-LocalOrSchemaQualifiedName
- : 'REGULAR_IDENTIFIER' AnyDot 'PARTIAL_CURSOR'
-   {
-     suggestTables({ database: $1 });
-   }
- | 'REGULAR_IDENTIFIER' AnyDot 'REGULAR_IDENTIFIER' 'PARTIAL_CURSOR'
-   {
-     suggestTables({ database: $1 });
-   }
- | 'REGULAR_IDENTIFIER' AnyDot 'REGULAR_IDENTIFIER'
-   {
-     addTablePrimary({ identifierChain: [{ name: $1 }, { name: $3 }] });
-   }
- | 'REGULAR_IDENTIFIER'
-   {
-     addTablePrimary({ identifierChain: [{ name: $1 }] });
-   }
- | 'REGULAR_IDENTIFIER' AnyDot
    {
-     addTablePrimary({ identifierChain: [{ name: $1 }] });
+     // TODO: Replace with TablePrimary?
+     if ($1.partial) {
+       if ($1.identifierChain.length === 1) {
+         suggestTablesOrColumns($1.identifierChain[0].name);
+       }
+     } else if (typeof $1.identifierChain !== 'undefined') {
+       addTablePrimary($1);
+     }
    }
  ;
 
@@ -812,37 +809,104 @@ TableReference
 
 TablePrimaryOrJoinedTable
  : TablePrimary
+   {
+     if ($1.partial) {
+       if ($1.identifierChain.length === 1) {
+         suggestTablesOrColumns($1.identifierChain[0].name);
+       } else if ($1.identifierChain.length === 0) {
+         suggestTables();
+         suggestDatabases({ appendDot: true });
+       }
+     } else if (typeof $1.identifierChain !== 'undefined') {
+       addTablePrimary($1);
+     }
+   }
+ | LateralViewDefinition
+   {
+     addTablePrimary($1);
+   }
  | JoinedTable
  ;
 
+LateralViewDefinition
+ :'REGULAR_IDENTIFIER' LateralViews
+   {
+     $$ = { identifierChain: [ { name: $1 } ], lateralViews: $2 }
+   }
+ | 'REGULAR_IDENTIFIER' 'REGULAR_IDENTIFIER' LateralViews
+   {
+     $$ = { identifierChain: [ { name: $1 } ], alias: $2, lateralViews: $3 };
+   }
+ ;
+
 TablePrimary
+ : LocalOrSchemaQualifiedName
+ ;
+
+RegularOrBacktickedIdentifier
  : 'REGULAR_IDENTIFIER'
+ | 'BACKTICK' 'VALUE' 'BACKTICK'
    {
-     addTablePrimary({ identifierChain: [ { name: $1 } ] });
+     $$ = $1;
    }
- | 'REGULAR_IDENTIFIER' LateralViews
+ ;
+
+RegularOrBackTickedSchemaQualifiedName
+ : 'REGULAR_IDENTIFIER' AnyDot 'REGULAR_IDENTIFIER'
    {
-     addTablePrimary({ identifierChain: [ { name: $1 } ], lateralViews: $2 } );
+     $$ = { identifierChain: [ { name: $1 }, { name: $3 } ] }
    }
- | 'REGULAR_IDENTIFIER' 'REGULAR_IDENTIFIER'
+ | 'BACKTICK' 'VALUE' 'BACKTICK' AnyDot 'REGULAR_IDENTIFIER'
    {
-     addTablePrimary({ identifierChain: [ { name: $1 } ], alias: $2 });
+     $$ = { identifierChain: [ { name: $2 }, { name: $5 } ] }
    }
- | 'REGULAR_IDENTIFIER' 'REGULAR_IDENTIFIER' LateralViews
+ | 'REGULAR_IDENTIFIER' AnyDot 'BACKTICK' 'VALUE' 'BACKTICK'
+   {
+     $$ = { identifierChain: [ { name: $1 }, { name: $4 } ] }
+   }
+ | 'BACKTICK' 'VALUE' 'BACKTICK' AnyDot 'BACKTICK' 'VALUE' 'BACKTICK'
    {
-     addTablePrimary({ identifierChain: [ { name: $1 } ], alias: $2, lateralViews: $3 } );
+     $$ = { identifierChain: [ { name: $2 }, { name: $6 } ] }
    }
- | 'REGULAR_IDENTIFIER' AnyDot 'REGULAR_IDENTIFIER'
+ | 'BACKTICK' 'VALUE' 'BACKTICK' AnyDot 'BACKTICK' 'PARTIAL_VALUE'
    {
-     addTablePrimary({ identifierChain: [ { name: $1 }, { name: $3 } ] });
+     $$ = { partial: true, identifierChain: [ { name: $2 } ] };
    }
- | 'REGULAR_IDENTIFIER' AnyDot 'REGULAR_IDENTIFIER' 'REGULAR_IDENTIFIER'
+ | 'REGULAR_IDENTIFIER' AnyDot 'REGULAR_IDENTIFIER' 'PARTIAL_CURSOR'
    {
-     addTablePrimary({ identifierChain: [ { name: $1 }, { name: $3 } ], alias: $4 });
+     $$ = { partial: true, identifierChain: [ { name: $1 } ] };
+   }
+ | 'BACKTICK' 'VALUE' 'BACKTICK' AnyDot 'PARTIAL_CURSOR'
+   {
+     $$ = { partial: true, identifierChain: [ { name: $2 } ] };
+   }
+ | 'BACKTICK' 'PARTIAL_VALUE'
+   {
+     $$ = { partial: true, identifierChain: [ ] };
    }
  | 'REGULAR_IDENTIFIER' AnyDot 'PARTIAL_CURSOR'
    {
-     suggestTablesOrColumns($1);
+     $$ = { partial: true, identifierChain: [ { name: $1 } ] };
+   }
+ | 'BACKTICK' 'VALUE' 'BACKTICK'
+   {
+     $$ = { identifierChain: [ { name: $2 } ] }
+   }
+ ;
+
+LocalOrSchemaQualifiedName
+ : 'REGULAR_IDENTIFIER'
+   {
+     $$ = { identifierChain: [ { name: $1 } ] }
+   }
+ | 'REGULAR_IDENTIFIER' 'REGULAR_IDENTIFIER'
+   {
+     $$ = { identifierChain: [ { name: $1 } ], alias: $2 };
+   }
+ | RegularOrBackTickedSchemaQualifiedName
+ | RegularOrBackTickedSchemaQualifiedName 'REGULAR_IDENTIFIER'
+   {
+     $$ = { identifierChain: $1.identifierChain, alias: $2 }
    }
  ;
 

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


+ 52 - 0
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpec.js

@@ -615,6 +615,20 @@ define([
         });
       });
 
+      it('should suggest database or table names after FROM with started backticked name', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM `tes',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {},
+            suggestDatabases: {
+              appendDot: true
+            }
+          }
+        });
+      });
+
       it('should suggest table names after FROM with database reference', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT * FROM database_two.',
@@ -628,6 +642,32 @@ define([
         });
       });
 
+      it('should suggest table names after FROM with backticked database reference', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM `database_two`.',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {
+              database: 'database_two'
+            }
+          }
+        });
+      });
+
+      it('should suggest table names after FROM with partial backticked table reference', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM `database_two`.`bla ',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {
+              database: 'database_two'
+            }
+          }
+        });
+      });
+
       it('should suggest aliases', function() {
         assertAutoComplete({
           serverResponses: {},
@@ -1676,6 +1716,18 @@ define([
         });
       });
 
+      it('should suggest columns for table with grave accents', function () {
+        assertAutoComplete({
+          beforeCursor: 'select ',
+          afterCursor: ' from `database one`.`test table`',
+          expectedResult: {
+            lowerCase: true,
+            suggestStar: true,
+            suggestColumns: { table: 'test table', database: 'database one' }
+          }
+        });
+      });
+
       it('should suggest columns for table after WHERE', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT * FROM testTable WHERE ',

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