Browse Source

HUE-5314 [editor] Add support for multiple tables in join autocompletion

Johan Ahlen 9 năm trước cách đây
mục cha
commit
0422d56a08

+ 27 - 6
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_main.jison

@@ -2332,11 +2332,21 @@ TablePrimaryOrJoinedTable
  : TablePrimary
    {
       $$ = $1;
-      var lastTablePrimary = parser.yy.latestTablePrimaries[parser.yy.latestTablePrimaries.length - 1];
-      if (!lastTablePrimary.subQueryAlias) {
+
+      var idx = parser.yy.latestTablePrimaries.length - 1;
+      var tables = [];
+      do {
+        var tablePrimary = parser.yy.latestTablePrimaries[idx];
+        if (!tablePrimary.subQueryAlias) {
+          tables.unshift(tablePrimary.alias ? { identifierChain: tablePrimary.identifierChain, alias: tablePrimary.alias } : { identifierChain: tablePrimary.identifierChain })
+        }
+        idx--;
+      } while (idx >= 0 && tablePrimary.join && !tablePrimary.subQueryAlias)
+
+      if (tables.length > 0) {
         $$.suggestJoins = {
           prependJoin: true,
-          tables: [ lastTablePrimary.alias ? { identifierChain: lastTablePrimary.identifierChain, alias: lastTablePrimary.alias } : { identifierChain: lastTablePrimary.identifierChain }]
+          tables: tables
         };
       }
    }
@@ -2372,6 +2382,7 @@ Joins
      if ($4.suggestKeywords) {
        $$.suggestKeywords = $4.suggestKeywords;
      }
+     parser.yy.latestTablePrimaries[parser.yy.latestTablePrimaries.length - 1].join = true;
    }
  | Joins JoinType OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
    {
@@ -2387,6 +2398,7 @@ Joins
      if ($4.suggestKeywords) {
        $$.suggestKeywords = $4.suggestKeywords;
      }
+     parser.yy.latestTablePrimaries[parser.yy.latestTablePrimaries.length - 1].join = true;
    }
  ;
 
@@ -2412,12 +2424,21 @@ Join_EDIT
        suggestKeywords(['[BROADCAST]', '[SHUFFLE]']);
      }
      if (!$2) {
-       var lastTablePrimary = parser.yy.latestTablePrimaries[parser.yy.latestTablePrimaries.length - 1];
-       if (!lastTablePrimary.subQueryAlias) {
+       var idx = parser.yy.latestTablePrimaries.length - 1;
+       var tables = [];
+       do {
+         var tablePrimary = parser.yy.latestTablePrimaries[idx];
+         if (!tablePrimary.subQueryAlias) {
+           tables.unshift(tablePrimary.alias ? { identifierChain: tablePrimary.identifierChain, alias: tablePrimary.alias } : { identifierChain: tablePrimary.identifierChain })
+         }
+         idx--;
+       } while (idx >= 0 && tablePrimary.join && !tablePrimary.subQueryAlias)
+
+       if (tables.length > 0) {
          suggestJoins({
            prependJoin: false,
            joinType: $1,
-           tables: [ lastTablePrimary.alias ? { identifierChain: lastTablePrimary.identifierChain, alias: lastTablePrimary.alias } : { identifierChain: lastTablePrimary.identifierChain }]
+           tables: tables
          })
        }
      }

+ 27 - 6
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js

@@ -1482,11 +1482,21 @@ break;
 case 1163:
 
       this.$ = $$[$0];
-      var lastTablePrimary = parser.yy.latestTablePrimaries[parser.yy.latestTablePrimaries.length - 1];
-      if (!lastTablePrimary.subQueryAlias) {
+
+      var idx = parser.yy.latestTablePrimaries.length - 1;
+      var tables = [];
+      do {
+        var tablePrimary = parser.yy.latestTablePrimaries[idx];
+        if (!tablePrimary.subQueryAlias) {
+          tables.unshift(tablePrimary.alias ? { identifierChain: tablePrimary.identifierChain, alias: tablePrimary.alias } : { identifierChain: tablePrimary.identifierChain })
+        }
+        idx--;
+      } while (idx >= 0 && tablePrimary.join && !tablePrimary.subQueryAlias)
+
+      if (tables.length > 0) {
         this.$.suggestJoins = {
           prependJoin: true,
-          tables: [ lastTablePrimary.alias ? { identifierChain: lastTablePrimary.identifierChain, alias: lastTablePrimary.alias } : { identifierChain: lastTablePrimary.identifierChain }]
+          tables: tables
         };
       }
    
@@ -1505,6 +1515,7 @@ case 1170:
      if ($$[$0].suggestKeywords) {
        this.$.suggestKeywords = $$[$0].suggestKeywords;
      }
+     parser.yy.latestTablePrimaries[parser.yy.latestTablePrimaries.length - 1].join = true;
    
 break;
 case 1171:
@@ -1521,6 +1532,7 @@ case 1171:
      if ($$[$0-1].suggestKeywords) {
        this.$.suggestKeywords = $$[$0-1].suggestKeywords;
      }
+     parser.yy.latestTablePrimaries[parser.yy.latestTablePrimaries.length - 1].join = true;
    
 break;
 case 1172:
@@ -1535,12 +1547,21 @@ case 1181:
        suggestKeywords(['[BROADCAST]', '[SHUFFLE]']);
      }
      if (!$$[$0-2]) {
-       var lastTablePrimary = parser.yy.latestTablePrimaries[parser.yy.latestTablePrimaries.length - 1];
-       if (!lastTablePrimary.subQueryAlias) {
+       var idx = parser.yy.latestTablePrimaries.length - 1;
+       var tables = [];
+       do {
+         var tablePrimary = parser.yy.latestTablePrimaries[idx];
+         if (!tablePrimary.subQueryAlias) {
+           tables.unshift(tablePrimary.alias ? { identifierChain: tablePrimary.identifierChain, alias: tablePrimary.alias } : { identifierChain: tablePrimary.identifierChain })
+         }
+         idx--;
+       } while (idx >= 0 && tablePrimary.join && !tablePrimary.subQueryAlias)
+
+       if (tables.length > 0) {
          suggestJoins({
            prependJoin: false,
            joinType: $$[$0-3],
-           tables: [ lastTablePrimary.alias ? { identifierChain: lastTablePrimary.identifierChain, alias: lastTablePrimary.alias } : { identifierChain: lastTablePrimary.identifierChain }]
+           tables: tables
          })
        }
      }

+ 21 - 13
desktop/core/src/desktop/static/desktop/js/sqlAutocompleter2.js

@@ -137,9 +137,11 @@ var SqlAutocompleter2 = (function () {
             });
 
             var joinRequired = false;
+            var tablesAdded = false;
             value.tables.forEach(function (table) {
               var tableParts = table.split('.');
               if (!existingTables[tableParts[tableParts.length - 1]]) {
+                tablesAdded = true;
                 var identifier = self.convertNavOptQualifiedIdentifier(table, database, parseResult.suggestJoins.tables, false);
                 suggestionString += joinRequired ? (parseResult.lowerCase ? ' join ' : ' JOIN ') + identifier : identifier;
                 joinRequired = true;
@@ -147,21 +149,27 @@ var SqlAutocompleter2 = (function () {
             });
 
             if (value.joinCols.length > 0) {
+              if (!tablesAdded && parseResult.suggestJoins.prependJoin) {
+                suggestionString = '';
+                tablesAdded = true;
+              }
               suggestionString += parseResult.lowerCase ? ' on ' : ' ON ';
             }
-            value.joinCols.forEach(function (joinColPair) {
-              if (!first) {
-                suggestionString += parseResult.lowerCase ? ' and ' : ' AND ';
-              }
-              suggestionString += self.convertNavOptQualifiedIdentifier(joinColPair.columns[0], database, parseResult.suggestJoins.tables, true) + ' = ' + self.convertNavOptQualifiedIdentifier(joinColPair.columns[1], database, parseResult.suggestJoins.tables, true);
-              first = false;
-            });
-            completions.push({
-              value: suggestionString,
-              meta: 'join',
-              weight: parseResult.suggestJoins.prependJoin ? DEFAULT_WEIGHTS.JOIN : DEFAULT_WEIGHTS.ACTIVE_JOIN,
-              docHTML: self.createJoinHtml(suggestionString)
-            });
+            if (tablesAdded) {
+              value.joinCols.forEach(function (joinColPair) {
+                if (!first) {
+                  suggestionString += parseResult.lowerCase ? ' and ' : ' AND ';
+                }
+                suggestionString += self.convertNavOptQualifiedIdentifier(joinColPair.columns[0], database, parseResult.suggestJoins.tables, true) + ' = ' + self.convertNavOptQualifiedIdentifier(joinColPair.columns[1], database, parseResult.suggestJoins.tables, true);
+                first = false;
+              });
+              completions.push({
+                value: suggestionString,
+                meta: 'join',
+                weight: parseResult.suggestJoins.prependJoin ? DEFAULT_WEIGHTS.JOIN : DEFAULT_WEIGHTS.ACTIVE_JOIN,
+                docHTML: self.createJoinHtml(suggestionString)
+              });
+            }
           });
           joinsDeferral.resolve();
         },

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

@@ -5903,6 +5903,21 @@
         });
       });
 
+      it('should suggest joins for "SELECT * FROM testTable1 JOIN testTable2 JOIN |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM testTable1 JOIN testTable2 JOIN ',
+          afterCursor: '',
+          hasLocations: true,
+          dialect: 'generic',
+          expectedResult: {
+            lowerCase: false,
+            suggestJoins: { prependJoin: false, joinType: 'JOIN', tables: [{ identifierChain: [{ name: 'testTable1' }] }, { identifierChain: [{ name: 'testTable2' }] }] },
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
+          }
+        });
+      });
+
       it('should suggest keywords for "SELECT * FROM testTable1 INNER |"', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT * FROM testTable1 INNER ',