Przeglądaj źródła

HUE-5287 [editor] Add join condition suggestions to the autocomplete parser

Johan Ahlen 9 lat temu
rodzic
commit
530744919c

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

@@ -87,7 +87,7 @@ LateralView
  | '<hive>LATERAL' error                                                                                          -> { }
  ;
 
-JoinTypes_EDIT
+JoinType_EDIT
  : 'FULL' 'CURSOR' error
    {
      suggestKeywords(['JOIN', 'OUTER JOIN']);

+ 42 - 18
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_main.jison

@@ -1395,6 +1395,9 @@ TableExpression_EDIT
        if ($1.suggestKeywords) {
          keywords = createWeightedKeywords($1.suggestKeywords, 3);
        }
+       if ($1.tableReferenceList.suggestJoinConditions) {
+         joinConditionsSuggest($1.tableReferenceList.suggestJoinConditions);
+       }
        if (!$1.hasLateralViews && $1.tableReferenceList.suggestKeywords) {
          keywords = keywords.concat(createWeightedKeywords($1.tableReferenceList.suggestKeywords, 3));
        }
@@ -2342,21 +2345,41 @@ JoinedTable_EDIT
  ;
 
 Joins
- : JoinTypes OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
+ : JoinType OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
    {
-     $4.joinType = $1;
-     $$ = $4;
+     if ($4 && $4.valueExpression) {
+       $$ = $4.valueExpression;
+     } else {
+       $$ = {};
+     }
+     $$.joinType = $1;
+     if ($4.noJoinCondition) {
+       $$.suggestJoinConditions = { prependOn: true, tablePrimaries: parser.yy.latestTablePrimaries.concat() }
+     }
+     if ($4.suggestKeywords) {
+       $$.suggestKeywords = $4.suggestKeywords;
+     }
    }
- | Joins JoinTypes OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
+ | Joins JoinType OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
    {
-     $5.joinType = $1;
-     $$ = $5;
+     if ($4 && $4.valueExpression) {
+       $$ = $4.valueExpression;
+     } else {
+       $$ = {};
+     }
+     $$.joinType = $1;
+     if ($4.noJoinCondition) {
+       $$.suggestJoinConditions = { prependOn: true, tablePrimaries: parser.yy.latestTablePrimaries.concat() }
+     }
+     if ($4.suggestKeywords) {
+       $$.suggestKeywords = $4.suggestKeywords;
+     }
    }
  ;
 
 Joins_INVALID
- : JoinTypes OptionalImpalaBroadcastOrShuffle                                           -> { joinType: $1 }
- | JoinTypes OptionalImpalaBroadcastOrShuffle Joins                                     -> { joinType: $1 }
+ : JoinType OptionalImpalaBroadcastOrShuffle                                           -> { joinType: $1 }
+ | JoinType OptionalImpalaBroadcastOrShuffle Joins                                     -> { joinType: $1 }
  ;
 
 OptionalImpalaBroadcastOrShuffle
@@ -2366,11 +2389,11 @@ OptionalImpalaBroadcastOrShuffle
  ;
 
 Join_EDIT
- : JoinTypes_EDIT OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
- | JoinTypes_EDIT OptionalImpalaBroadcastOrShuffle
- | JoinTypes OptionalImpalaBroadcastOrShuffle TablePrimary_EDIT OptionalJoinCondition
- | JoinTypes OptionalImpalaBroadcastOrShuffle TablePrimary JoinCondition_EDIT
- | JoinTypes OptionalImpalaBroadcastOrShuffle 'CURSOR' OptionalJoinCondition
+ : JoinType_EDIT OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
+ | JoinType_EDIT OptionalImpalaBroadcastOrShuffle
+ | JoinType OptionalImpalaBroadcastOrShuffle TablePrimary_EDIT OptionalJoinCondition
+ | JoinType OptionalImpalaBroadcastOrShuffle TablePrimary JoinCondition_EDIT
+ | JoinType OptionalImpalaBroadcastOrShuffle 'CURSOR' OptionalJoinCondition
    {
      if (!$2 && isImpala()) {
        suggestKeywords(['[BROADCAST]', '[SHUFFLE]']);
@@ -2389,7 +2412,7 @@ Joins_EDIT
  | Joins Join_EDIT Joins
  ;
 
-JoinTypes
+JoinType
  : 'JOIN'
  | '<hive>CROSS' 'JOIN'
  | 'INNER' 'JOIN'
@@ -2405,7 +2428,7 @@ JoinTypes
  | 'RIGHT' 'SEMI' 'JOIN'
  ;
 
-JoinTypes_EDIT
+JoinType_EDIT
  : '<hive>CROSS' 'CURSOR'
    {
      suggestKeywords(['JOIN']);
@@ -2467,9 +2490,9 @@ JoinTypes_EDIT
  ;
 
 OptionalJoinCondition
- :                       -> { suggestKeywords: isImpala() ? ['ON', 'USING'] : ['ON'] }
- | 'ON' ValueExpression  -> $2
- | '<impala>USING' '(' UsingColList ')'
+ :                                       -> { noJoinCondition: true, suggestKeywords: isImpala() ? ['ON', 'USING'] : ['ON'] }
+ | 'ON' ValueExpression                  -> { valueExpression: $2 }
+ | '<impala>USING' '(' UsingColList ')'  -> {}
  ;
 
 UsingColList
@@ -2482,6 +2505,7 @@ JoinCondition_EDIT
  | 'ON' 'CURSOR'
    {
      valueExpressionSuggest();
+     joinConditionsSuggest({ prependOn: false });
    }
  ;
 

Plik diff jest za duży
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js


+ 26 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sql_support.js

@@ -207,6 +207,13 @@ var selectListNoTableSuggest = function (selectListEdit, hasDistinctOrAll) {
   }
 };
 
+var joinConditionsSuggest = function (details) {
+  parser.yy.result.suggestJoinConditions = details || {};
+  if (parser.yy.latestTablePrimaries && !parser.yy.result.suggestJoinConditions.tablePrimaries) {
+    parser.yy.result.suggestJoinConditions.tablePrimaries = parser.yy.latestTablePrimaries.concat();
+  }
+};
+
 var valueExpressionSuggest = function (oppositeValueExpression, operator) {
   if (oppositeValueExpression && oppositeValueExpression.columnReference) {
     suggestValues();
@@ -423,6 +430,12 @@ var prioritizeSuggestions = function () {
     delete parser.yy.result.subQueries;
   }
 
+  if (typeof parser.yy.result.suggestJoinConditions !== 'undefined') {
+    if (typeof parser.yy.result.suggestJoinConditions.tables === 'undefined' || parser.yy.result.suggestJoinConditions.tables.length === 0) {
+      delete parser.yy.result.suggestJoinConditions;
+    }
+  }
+
   if (typeof parser.yy.result.suggestTables !== 'undefined' && typeof parser.yy.latestCommonTableExpressions !== 'undefined') {
     var ctes = [];
     parser.yy.latestCommonTableExpressions.forEach(function (identifier) {
@@ -771,6 +784,16 @@ var linkTablePrimaries = function () {
   }
 
   var tablePrimaries = parser.yy.latestTablePrimaries;
+  if (typeof parser.yy.result.suggestJoinConditions !== 'undefined' && parser.yy.result.suggestJoinConditions.tablePrimaries && !parser.yy.result.suggestJoinConditions.linked) {
+    parser.yy.result.suggestJoinConditions.tables = [];
+    parser.yy.result.suggestJoinConditions.tablePrimaries.forEach(function (tablePrimary) {
+      if (!tablePrimary.subQueryAlias) {
+        parser.yy.result.suggestJoinConditions.tables.push({ identifierChain: tablePrimary.identifierChain.concat() });
+      }
+    });
+    delete parser.yy.result.suggestJoinConditions.tablePrimaries;
+    parser.yy.result.suggestJoinConditions.linked = true;
+  }
   if (typeof parser.yy.result.suggestColumns !== 'undefined' && !parser.yy.result.suggestColumns.linked) {
     tablePrimaries = filterTablePrimariesForOwner(parser.yy.result.suggestColumns.owner);
     if (!parser.yy.result.suggestColumns.tables) {
@@ -1266,6 +1289,9 @@ parser.parseSql = function (beforeCursor, afterCursor, dialect, debug) {
   if (typeof parser.yy.result.suggestColumns !== 'undefined') {
     delete parser.yy.result.suggestColumns.linked;
   }
+  if (typeof parser.yy.result.suggestJoinConditions !== 'undefined') {
+    delete parser.yy.result.suggestJoinConditions.linked;
+  }
   if (typeof parser.yy.result.colRef !== 'undefined') {
     delete parser.yy.result.colRef.linked;
   }

+ 26 - 7
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecSelect.js

@@ -2515,7 +2515,8 @@
           hasLocations: true,
           containsKeywords: ['ON'],
           expectedResult: {
-            lowerCase: false
+            lowerCase: false,
+            suggestJoinConditions: { prependOn: true, tables: [{ identifierChain: [{ name: 'foo' }] }, { identifierChain: [{ name: 'baz' }] }] }
           }
         });
       });
@@ -2528,7 +2529,8 @@
           containsKeywords: ['ON'],
           hasLocations: true,
           expectedResult: {
-            lowerCase: false
+            lowerCase: false,
+            suggestJoinConditions: { prependOn: true, tables: [{ identifierChain: [{ name: 'foo' }] }, { identifierChain: [{ name: 'baz' }] }] }
           }
         });
       });
@@ -6005,6 +6007,19 @@
         });
       });
 
+      it('should suggest join conditions for "SELECT testTable1.* FROM testTable1 JOIN testTable2 |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT testTable1.* FROM testTable1 JOIN testTable2 ',
+          afterCursor: '',
+          hasLocations: true,
+          containsKeywords: ['ON'],
+          expectedResult: {
+            lowerCase: false,
+            suggestJoinConditions: { prependOn: true, tables: [{ identifierChain: [{ name: 'testTable1' }] }, { identifierChain: [{ name: 'testTable2' }] }] }
+          }
+        });
+      });
+
       it('should suggest tables for "SELECT testTable1.* FROM testTable1 JOIN testTable2 ON |"', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT testTable1.* FROM testTable1 JOIN testTable2 ON ',
@@ -6012,10 +6027,11 @@
           hasLocations: true,
           containsKeywords: ['CASE'],
           expectedResult: {
-            lowerCase: false,
-            suggestFunctions: {},
             suggestColumns: { tables: [{ identifierChain: [{ name: 'testTable1' }] }, { identifierChain: [{ name: 'testTable2' }] }] },
-            suggestIdentifiers: [{ name: 'testTable1.', type: 'table' }, { name: 'testTable2.', type: 'table' }]
+            suggestFunctions: {},
+            suggestJoinConditions: { prependOn: false, tables: [{ identifierChain: [{ name: 'testTable1' }] }, { identifierChain: [{ name: 'testTable2' }] }] },
+            suggestIdentifiers: [{ name: 'testTable1.', type: 'table' }, { name: 'testTable2.', type: 'table' }],
+            lowerCase: false
           }
         });
       });
@@ -6108,6 +6124,7 @@
           expectedResult: {
             lowerCase: true,
             suggestFunctions: {},
+            suggestJoinConditions: { prependOn: false, tables: [{ identifierChain: [{ name: 'testTable1' }] }, { identifierChain: [{ name: 'db' }, { name: 'testTable2' }] }] },
             suggestColumns: { tables: [{ identifierChain: [{ name: 'testTable1' }] }, { identifierChain: [{ name: 'db' }, { name: 'testTable2' }] }] },
             suggestIdentifiers: [{ name: 'testTable1.', type: 'table' }, { name: 'testTable2.', type: 'table' }]
           }
@@ -6192,7 +6209,8 @@
           hasLocations: true,
           expectedResult: {
             lowerCase: false,
-            suggestKeywords: ['ON', 'FULL', 'FULL OUTER', 'INNER', 'LEFT', 'LEFT OUTER', 'RIGHT', 'RIGHT OUTER']
+            suggestKeywords: ['ON', 'FULL', 'FULL OUTER', 'INNER', 'LEFT', 'LEFT OUTER', 'RIGHT', 'RIGHT OUTER'],
+            suggestJoinConditions: { prependOn: true, tables: [{ identifierChain: [{ name: 'table1' }] }, { identifierChain: [{ name: 'table2' }] }] }
           }
         });
       });
@@ -6531,7 +6549,8 @@
             hasLocations: true,
             containsKeywords: ['FULL', 'FULL OUTER', 'INNER', 'LEFT', 'LEFT OUTER', 'ON', 'RIGHT', 'RIGHT OUTER', 'USING'],
             expectedResult: {
-              lowerCase: false
+              lowerCase: false,
+              suggestJoinConditions: { prependOn: true, tables: [{ identifierChain: [{ name: 'table1' }] }, { identifierChain: [{ name: 'table2' }] }] }
             }
           });
         });

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików