Эх сурвалжийг харах

HUE-4271 [editor] New autocompleter should support UDAFs and numeric expressions

This adds initial support for aggregate functions like count and sum. Up to this point I've followed the sql-2003 BNF but it turns out there's a conflict with the boolean and numeric value expressions (they both reduce to nonparenthesized value expression primary) so I had to merge them into one, they're both contained in ValueExpression now.

Some additional improvements:

- [SHUFFLE|BROADCAST] added for impala joins
- Completion in explode functions
- Hive DESCRIBE updated to > 2.0
- Suggest columns as well as values in equality expressions
- Better error handling throughout
Johan Ahlen 9 жил өмнө
parent
commit
84fa031

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 409 - 390
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.jison


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js


+ 0 - 4
desktop/core/src/desktop/static/desktop/js/sqlAutocompleter2.js

@@ -55,10 +55,6 @@
       });
     }
 
-    if (parseResult.suggestStar) {
-      completions.push({ value: '*', meta: 'keyword' });
-    }
-
     if (parseResult.suggestDatabases || parseResult.suggestHdfs || parseResult.suggestTables || parseResult.suggestColumns || parseResult.suggestValues) {
       var database = parseResult.useDatabase || self.snippet.database();
 

+ 46 - 30
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecDescribe.js

@@ -46,7 +46,7 @@ define([
 
       it('should handle DESCRIBE tbl.col.field', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE tbl.col.field;',
+          beforeCursor: 'DESCRIBE tbl col.field;',
           afterCursor: '',
           dialect: 'hive',
           containsKeywords: ['SELECT'],
@@ -68,9 +68,9 @@ define([
         });
       });
 
-      it('should handle EXTENDED tbl.col.field', function() {
+      it('should handle EXTENDED tbl col.field', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE EXTENDED tbl.col.field;',
+          beforeCursor: 'DESCRIBE EXTENDED tbl col.field;',
           afterCursor: '',
           dialect: 'hive',
           containsKeywords: ['SELECT'],
@@ -94,7 +94,7 @@ define([
 
       it('should handle FORMATTED tbl.col.field', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE FORMATTED tbl.col.field;',
+          beforeCursor: 'DESCRIBE FORMATTED tbl col.field;',
           afterCursor: '',
           dialect: 'hive',
           containsKeywords: ['SELECT'],
@@ -112,7 +112,8 @@ define([
           expectedResult: {
             lowerCase: false,
             suggestKeywords: ['DATABASE', 'EXTENDED', 'FORMATTED', 'SCHEMA'],
-            suggestTables: {}
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
           }
         });
       });
@@ -125,35 +126,34 @@ define([
           expectedResult: {
             lowerCase: false,
             suggestKeywords: ['DATABASE', 'EXTENDED', 'FORMATTED', 'SCHEMA'],
-            suggestTables: {}
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
           }
         });
       });
 
-      it('should suggest columns after DESCRIBE tbl.', function() {
+      it('should suggest tables after DESCRIBE db.', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE tbl.',
+          beforeCursor: 'DESCRIBE db.',
           afterCursor: '',
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
-            suggestColumns: {
-              table: 'tbl'
-            }
+            suggestTables: { database: 'db' }
           }
         });
       });
 
-      it('should suggest fields after DESCRIBE tbl.bla.', function() {
+      it('should suggest columns after DESCRIBE db.tb ', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE tbl.bla.',
+          beforeCursor: 'DESCRIBE db.tbl ',
           afterCursor: '',
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
             suggestColumns: {
-              identifierChain: [{ name: 'bla' }],
-              table: 'tbl'
+              table: 'tbl',
+              database: 'db'
             }
           }
         });
@@ -290,34 +290,33 @@ define([
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
-            suggestTables: {}
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
           }
         });
       });
 
-      it('should suggest columns after DESCRIBE EXTENDED tbl.', function() {
+      it('should suggest tables after DESCRIBE EXTENDED db.', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE EXTENDED tbl.',
+          beforeCursor: 'DESCRIBE EXTENDED db.',
           afterCursor: '',
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
-            suggestColumns: {
-              table: 'tbl'
-            }
+            suggestTables: { database: 'db' }
           }
         });
       });
 
-      it('should suggest fields after DESCRIBE EXTENDED tbl.bla.', function() {
+      it('should suggest columns after DESCRIBE EXTENDED db.tbl', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE EXTENDED tbl.bla.',
+          beforeCursor: 'DESCRIBE EXTENDED db.tbl ',
           afterCursor: '',
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
             suggestColumns: {
-              identifierChain: [{ name: 'bla' }],
+              database: 'db',
               table: 'tbl'
             }
           }
@@ -331,34 +330,51 @@ define([
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
-            suggestTables: {}
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest tables after DESCRIBE FORMATTED db.', function() {
+        assertAutoComplete({
+          beforeCursor: 'DESCRIBE FORMATTED db.',
+          afterCursor: '',
+          dialect: 'hive',
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {
+              database: 'db'
+            }
           }
         });
       });
 
-      it('should suggest columns after DESCRIBE FORMATTED tbl.', function() {
+      it('should suggest columns after DESCRIBE FORMATTED db.tbl', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE FORMATTED tbl.',
+          beforeCursor: 'DESCRIBE FORMATTED db.tbl ',
           afterCursor: '',
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
             suggestColumns: {
+              database: 'db',
               table: 'tbl'
             }
           }
         });
       });
 
-      it('should suggest fields after DESCRIBE FORMATTED tbl.bla.', function() {
+      it('should suggest fields after DESCRIBE FORMATTED db.tbl col.', function() {
         assertAutoComplete({
-          beforeCursor: 'DESCRIBE FORMATTED tbl.bla.',
+          beforeCursor: 'DESCRIBE FORMATTED db.tbl col.',
           afterCursor: '',
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
             suggestColumns: {
-              identifierChain: [{ name: 'bla' }],
+              identifierChain: [{ name: 'col' }],
+              database: 'db',
               table: 'tbl'
             }
           }

+ 213 - 88
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecSelect.js

@@ -107,6 +107,18 @@ define([
       });
     });
 
+    it('should handle asterisked complete SELECT statement ', function() {
+      assertAutoComplete({
+        serverResponses: {},
+        beforeCursor: 'SELECT tta.* FROM testTableA tta, testTableB; ',
+        afterCursor: '',
+        containsKeywords: ['SELECT'],
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
     it('should suggest keywords after SELECT SelectList FROM TablePrimary ', function() {
       assertAutoComplete({
         serverResponses: {},
@@ -126,18 +138,18 @@ define([
         afterCursor: '',
         expectedResult: {
           lowerCase: false,
-          suggestKeywords: ['AND', 'GROUP BY', 'LIMIT', 'ORDER BY']
+          suggestKeywords: ['<', '<=', '<>', '=', '>', '>=', 'AND', 'GROUP BY', 'IN', 'LIMIT', 'NOT IN', 'OR', 'ORDER BY']
         }
       });
     });
 
     it('should suggest keywords after SELECT FROM TablePrimary WHERE SearchCondition ', function () {
       assertAutoComplete({
-        beforeCursor: 'SELECT FROM foo WHERE id = 1 ',
+        beforeCursor: 'SELECT * FROM foo WHERE id = 1 ',
         afterCursor: '',
         expectedResult: {
           lowerCase: false,
-          suggestKeywords: ['AND', 'GROUP BY', 'LIMIT', 'ORDER BY']
+          suggestKeywords: ['<', '<=', '<>', '=', '>', '>=', 'AND', 'GROUP BY', 'IN', 'LIMIT', 'NOT IN', 'OR', 'ORDER BY']
         }
       });
     });
@@ -210,7 +222,7 @@ define([
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
-            suggestKeywords: ['AND', 'GROUP BY', 'LIMIT', 'ORDER BY']
+            suggestKeywords: ['<', '<=', '<>', '=', '>', '>=', 'AND', 'GROUP BY', 'IN', 'LIMIT', 'NOT IN', 'OR', 'ORDER BY']
           }
         });
       });
@@ -295,7 +307,7 @@ define([
           afterCursor: '',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestTables: {
               prependQuestionMark: true,
               prependFrom: true
@@ -315,7 +327,7 @@ define([
           afterCursor: '',
           expectedResult: {
             lowerCase: true,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestTables: {
               prependQuestionMark: true,
               prependFrom: true
@@ -329,42 +341,37 @@ define([
         });
       });
 
-      it('should suggest table names with *', function() {
+      it('should suggest table names if FROM is already there', function() {
         assertAutoComplete({
-          beforeCursor: 'SELECT * ',
-          afterCursor: '',
+          beforeCursor: 'SELECT ',
+          afterCursor: ' FROM tableA;',
           expectedResult: {
             lowerCase: false,
-            suggestTables: {
-              prependFrom: true
-            },
-            suggestDatabases: {
-              prependFrom: true,
-              appendDot: true
-            }
+            suggestKeywords: ['*'],
+            suggestColumns: {table: 'tableA'}
           }
         });
       });
 
-      it('should suggest table names if FROM is already there', function() {
+      it('should suggest table names if FROM is already there after a column', function() {
         assertAutoComplete({
-          beforeCursor: 'SELECT ',
+          beforeCursor: 'SELECT a, ',
           afterCursor: ' FROM tableA;',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: {table: 'tableA'}
           }
         });
       });
 
-      it('should suggest table names if FROM is already there after a column', function() {
+      it('should suggest table names if FROM is already there after *', function() {
         assertAutoComplete({
-          beforeCursor: 'SELECT a, ',
+          beforeCursor: 'SELECT *, ',
           afterCursor: ' FROM tableA;',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: {table: 'tableA'}
           }
         });
@@ -403,6 +410,17 @@ define([
         });
       });
 
+      it('should suggest keywords after a column reference before comma', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT a ',
+          afterCursor: ', FROM tableA;',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['AS']
+          }
+        });
+      });
+
       it('should suggest table names with started FROM', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT * fr',
@@ -508,7 +526,7 @@ define([
           afterCursor: ' FROM testTableA   tta, testTableB',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestIdentifiers: [{ name: 'tta.', type: 'alias' }, { name: 'testTableB.', type: 'table' }]
           }
         });
@@ -520,29 +538,88 @@ define([
           afterCursor: ' FROM testTableA   tta, testTableB',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestIdentifiers: [{ name: 'tta.', type: 'alias' }, { name: 'testTableB.', type: 'table' }]
           }
         });
       });
 
-      // TODO: fix me, issue is SUM function
-      xit('should suggest table aliases and select aliases', function() {
+      it('should suggest table aliases and select aliases', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT ',
           afterCursor: ' FROM testTableA tta, (SELECT SUM(A*B) total FROM tta.array) ttaSum, testTableB ttb',
           ignoreErrors: true,
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
-            suggestIdentifiers: [{ name: 'tta.', type: 'alias' }, { name: 'ttaSum', type: 'alias' }, { name: 'ttb.', type: 'alias' }]
+            suggestKeywords: ['*'],
+            suggestIdentifiers: [{ name: 'tta.', type: 'alias' }, { name: 'ttaSum.', type: 'subquery' }, { name: 'ttb.', type: 'alias' }]
           }
         });
       });
     });
 
     describe('functions', function () {
-      xit('should suggest fields in functions', function () {
+      it('should handle count', function () {
+        assertAutoComplete({
+          beforeCursor: 'SELECT COUNT(*) FROM testTable;',
+          afterCursor: '',
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should suggest table names with just a function', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT COUNT(*) ',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {
+              prependFrom: true
+            },
+            suggestDatabases: {
+              prependFrom: true,
+              appendDot: true
+            },
+            suggestKeywords: ['AS']
+          }
+        });
+      });
+
+      it('should suggest columns in aggregate functions', function () {
+        var aggregateFunctions = [
+          { name: 'COUNT', dialect: 'generic'}];
+        aggregateFunctions.forEach(function (aggregateFunction) {
+          if (aggregateFunction.name === 'COUNT') {
+            assertAutoComplete({
+              beforeCursor: 'SELECT ' + aggregateFunction.name + '(',
+              afterCursor: ') FROM testTable',
+              expectedResult: {
+                lowerCase: false,
+                suggestColumns: {
+                  table: 'testTable'
+                },
+                suggestKeywords: ['*']
+              }
+            });
+          } else {
+            assertAutoComplete({
+              beforeCursor: 'SELECT ' + aggregateFunction.name + '(',
+              afterCursor: ') FROM testTable',
+              expectedResult: {
+                lowerCase: false,
+                suggestColumns: {
+                  table: 'testTable'
+                }
+              }
+            });
+          }
+        })
+      });
+
+      it('should suggest fields in functions', function () {
         assertAutoComplete({
           beforeCursor: 'SELECT id, SUM(',
           afterCursor: ' FROM testTable',
@@ -556,9 +633,9 @@ define([
         });
       });
 
-      xit('should suggest fields in functions after operators', function () {
+      it('should suggest fields in functions after operators', function () {
         assertAutoComplete({
-          beforeCursor: 'SELECT id, SUM(a * ',
+          beforeCursor: 'SELECT id, SUM(a *  ',
           afterCursor: ' FROM testTable',
           ignoreErrors: true,
           expectedResult: {
@@ -582,7 +659,8 @@ define([
             suggestColumns : {
               table: 'testTable',
               identifierChain: [{ name: 'testMap', key: '\"anyKey\"' }]
-            }
+            },
+            suggestKeywords: ['*']
           }
         });
       });
@@ -597,7 +675,8 @@ define([
             suggestColumns : {
               table: 'testTable',
               identifierChain: [{ name: 'testMap', key: null }]
-            }
+            },
+            suggestKeywords: ['*']
           }
         });
       });
@@ -612,7 +691,8 @@ define([
             suggestColumns : {
               table: 'testTable',
               identifierChain: [{ name: 'testMap', key: '\"anyKey\"' }, { name: 'fieldC' }]
-            }
+            },
+            suggestKeywords: ['*']
           }
         });
       });
@@ -627,7 +707,8 @@ define([
             suggestColumns : {
               table: 'testTable',
               identifierChain: [{ name: 'testArray', key: 1 }, { name: 'fieldC' }]
-            }
+            },
+            suggestKeywords: ['*']
           }
         });
       });
@@ -642,7 +723,8 @@ define([
             suggestColumns : {
               table: 'testTable',
               identifierChain: [{ name: 'testArray', key: 1 }, { name: 'testMap', key: '\"key\"' }]
-            }
+            },
+            suggestKeywords: ['*']
           }
         });
       });
@@ -671,7 +753,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Verify that this is true
+              suggestKeywords: ['*'], // TODO: Verify that this is true
               suggestColumns: {
                 table: 'testTable'
               },
@@ -680,12 +762,13 @@ define([
           });
         });
 
-        xit('should suggest columns in explode', function () {
+        it('should suggest columns in explode', function () {
           assertAutoComplete({
             beforeCursor: 'SELECT * FROM testTable LATERAL VIEW explode(',
             afterCursor: '',
             dialect: 'hive',
             expectedResult: {
+              lowerCase: false,
               suggestColumns: {
                 table: 'testTable'
               }
@@ -693,12 +776,13 @@ define([
           });
         });
 
-        xit('should suggest columns in explode for structs', function () {
+        it('should suggest columns in explode for structs', function () {
           assertAutoComplete({
             beforeCursor: 'SELECT * FROM testTable LATERAL VIEW explode(a.b.',
             afterCursor: '',
             dialect: 'hive',
             expectedResult: {
+              lowerCase: false,
               suggestColumns: {
                 table: 'testTable',
                 identifierChain: [ { name: 'a' }, { name: 'b' }]
@@ -707,12 +791,13 @@ define([
           });
         });
 
-        xit('should suggest columns in posexplode', function () {
+        it('should suggest columns in posexplode', function () {
           assertAutoComplete({
             beforeCursor: 'SELECT * FROM testTable LATERAL VIEW posexplode(',
             afterCursor: '',
             dialect: 'hive',
             expectedResult: {
+              lowerCase: false,
               suggestColumns: {
                 table: 'testTable'
               }
@@ -727,7 +812,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Verify that this is true
+              suggestKeywords: ['*'], // TODO: Verify that this is true
               suggestColumns: {
                 table: 'testTable'
               },
@@ -743,7 +828,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Verify that this is true
+              suggestKeywords: ['*'], // TODO: Verify that this is true
               suggestColumns: {
                 table: 'testTable',
                 identifierChain: [{ name: 'testArray' }, { name: 'item' }]
@@ -761,7 +846,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Verify that this is true
+              suggestKeywords: ['*'], // TODO: Verify that this is true
               suggestColumns: {
                 table: 'testTable',
                 identifierChain: [{ name: 'testArrayA' }, { name: 'item' }]
@@ -779,7 +864,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Verify that this is true
+              suggestKeywords: ['*'], // TODO: Verify that this is true
               suggestColumns: {
                 table: 'testTable2',
                 identifierChain: [{ name: 'testArrayB' }, { name: 'item' }]
@@ -798,7 +883,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Verify that this is true
+              suggestKeywords: ['*'], // TODO: Verify that this is true
               suggestColumns: {
                 table: 'testTable',
                 identifierChain: [{ name: 'testArray1' }, { name: 'item' }, { name: 'testArray2' }, { name: 'item' }]
@@ -817,7 +902,8 @@ define([
               suggestColumns: {
                 table: 'testTable',
                 identifierChain: [{ name: 'testArray' }, { name: 'item' }]
-              }
+              },
+              suggestKeywords: ['*']
             }
           });
         });
@@ -838,7 +924,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Verify that this is true
+              suggestKeywords: ['*'], // TODO: Verify that this is true
               suggestColumns: {
                 table: 'testTable',
                 identifierChain: [{ name: 'testArray' }, { name: 'item' }]
@@ -854,11 +940,11 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Verify that this is true
               suggestColumns: {
                 table: 'testTable',
                 identifierChain: [{ name: 'testMap' }, { name: 'value' }]
-              }
+              },
+              suggestKeywords: ['*'] // TODO: Verify that this is true
             }
           });
         });
@@ -873,7 +959,8 @@ define([
               suggestColumns: {
                 table: 'testTable',
                 identifierChain: [{ name: 'testMap' }, { name: 'value' }]
-              }
+              },
+              suggestKeywords: ['*'] // TODO: Verify that this is true
             }
           });
         });
@@ -886,8 +973,8 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Check if really true
-              suggestIdentifiers: [{ name: 'testMapKey', type: 'alias' }, { name: 'testMapValue', type: 'alias' }]
+              suggestIdentifiers: [{ name: 'testMapKey', type: 'alias' }, { name: 'testMapValue', type: 'alias' }],
+              suggestKeywords: ['*'] // TODO: Check if really true
             }
           });
         });
@@ -904,7 +991,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestStar: true, // TODO: Check if really true
+              suggestKeywords: ['*'], // TODO: Check if really true
               suggestIdentifiers: [{ name: 'explodedMap.', type: 'alias' }, { name: 'testMapKey', type: 'alias' }, { name: 'testMapValue', type: 'alias' }],
               suggestColumns: {
                 table: 'testTable'
@@ -916,6 +1003,20 @@ define([
     });
 
     describe('Impala specific', function() {
+
+      // Fails on YEAR(, and ROUND but recoverable error
+      xit('should handle complex query 1', function () {
+        assertAutoComplete({
+          beforeCursor: 'SELECT tmp.book_category, ROUND(tmp.revenue, 2) AS revenue FROM ( SELECT tst_a_db_0001.books_001.category AS book_category, SUM(tst_a_db_0001.books_001.price * transactions.quantity) AS revenue FROM tst_a_db_0001.books_001 JOIN [SHUFFLE] transactions ON ( transactions.book_id = tst_a_db_0001.books_001.id AND YEAR(transactions.transaction_date) BETWEEN 2008 AND 2010) GROUP BY tst_a_db_0001.books_001.category) tmp ORDER BY revenue DESC LIMIT 60;',
+          afterCursor: '',
+          dialect: 'impala',
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
       it('should not suggest struct from map values with hive style syntax', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT testMap[\"anyKey\"].',
@@ -926,7 +1027,8 @@ define([
             suggestColumns: {
               table: 'testTable',
               identifierChain: [{ name: 'testMap',  key: '\"anyKey\"' }]
-            }
+            },
+            suggestKeywords: ['*'] // TODO: Verify that this is true
           }
         });
       });
@@ -941,7 +1043,8 @@ define([
             suggestColumns: {
               table: 'testTable',
               identifierChain: [{ name: 'columnA' }, { name: 'fieldC' }]
-            }
+            },
+            suggestKeywords: ['*'] // TODO: Verify that this is true
           }
         });
       });
@@ -956,7 +1059,8 @@ define([
             suggestColumns: {
               table: 'testTable',
               identifierChain: [{ name: 'columnA' }, { name: 'fieldC' }]
-            }
+            },
+            suggestKeywords: ['*'] // TODO: Verify that this is true
           }
         });
       });
@@ -971,7 +1075,8 @@ define([
             suggestColumns: {
               table: 'testTable',
               identifierChain: [{ name: 'columnA' }, { name: 'fieldC' }]
-            }
+            },
+            suggestKeywords: ['*'] // TODO: Verify that this is true
           }
         });
       });
@@ -988,7 +1093,7 @@ define([
           dialect: 'impala',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns : {
               table: 'testTable',
               identifierChain: [{ name: 'testMap' }]
@@ -1004,7 +1109,7 @@ define([
           dialect: 'impala',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns : {
               table: 'testTable',
               identifierChain: [{ name: 'testMap' }]
@@ -1051,7 +1156,7 @@ define([
           dialect: 'impala',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true, // TODO: Check if really so
+            suggestKeywords: ['*'], // TODO: Check if really so
             suggestIdentifiers: [{ name: 't.', type: 'alias' }, { name: 'tm.', type: 'alias' }]
           }
         });
@@ -1129,7 +1234,7 @@ define([
           dialect: 'impala',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true, // TODO: Verify that this is true
+            suggestKeywords: ['*'], // TODO: Verify that this is true
             suggestColumns: {
               table: 'testTable',
               identifierChain: [{ name: 'columnA' }]
@@ -1148,7 +1253,8 @@ define([
             suggestColumns: {
               table: 'testTable',
               identifierChain: [{ name: 'columnA' }, { name: 'fieldC' }]
-            }
+            },
+            suggestKeywords: ['*'] // TODO: Verify that this is true
           }
         });
       });
@@ -1164,7 +1270,8 @@ define([
               table: 'testTable',
               database: 'database_two',
               identifierChain: [{ name: 'columnA' }, { name: 'fieldC' }]
-            }
+            },
+            suggestKeywords: ['*'] // TODO: Verify that this is true
           }
         });
       });
@@ -1180,11 +1287,28 @@ define([
             suggestValues: {
               table: 'testTable',
               identifierChain: [{ name: 'id' }]
-            }
+            },
+            suggestColumns: { table: 'testTable' }
           }
         });
       });
 
+      it('should suggest values for columns in conditions reversed', function() {
+        assertAutoComplete({
+          beforeCursor: 'SELECT * FROM testTable WHERE ',
+          afterCursor: ' = id',
+          expectedResult: {
+            lowerCase: false,
+            suggestValues: {
+              table: 'testTable',
+              identifierChain: [{ name: 'id' }]
+            },
+            suggestColumns: { table: 'testTable' }
+          }
+        });
+      });
+
+
       it('should suggest values for columns in conditions', function() {
         assertAutoComplete({
           beforeCursor: 'SELECT a, b, c FROM testTable WHERE d >= ',
@@ -1194,7 +1318,8 @@ define([
             suggestValues: {
               table: 'testTable',
               identifierChain: [{ name: 'd' }]
-            }
+            },
+            suggestColumns: { table: 'testTable' }
           }
         });
       });
@@ -1207,7 +1332,7 @@ define([
           afterCursor: ' FROM testTable',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTable' }
           }
         });
@@ -1219,7 +1344,7 @@ define([
           afterCursor: ' a, b, c, d FROM testTable WHERE a = \'US\' AND b >= 998 ORDER BY c DESC LIMIT 15',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTable' }
           }
         });
@@ -1231,7 +1356,7 @@ define([
           afterCursor: ',c, d FROM testTable WHERE a = \'US\' AND b >= 998 ORDER BY c DESC LIMIT 15',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTable' }
           }
         });
@@ -1243,7 +1368,7 @@ define([
           afterCursor: ' FROM testTable',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true, // TODO: Correct?
+            suggestKeywords: ['*'], // TODO: Correct?
             suggestColumns: { table: 'testTable' }
           }
         });
@@ -1255,7 +1380,7 @@ define([
           afterCursor: ' FROM testTable',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true, // TODO: Correct?
+            suggestKeywords: ['*'], // TODO: Correct?
             suggestColumns: { table: 'testTable' }
           }
         });
@@ -1267,7 +1392,7 @@ define([
           afterCursor: ' FROM testwhere',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testwhere' }
           }
         });
@@ -1279,7 +1404,7 @@ define([
           afterCursor: ' FROM teston',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'teston' }
           }
         });
@@ -1291,7 +1416,7 @@ define([
           afterCursor: ' from database_two.testTable',
           expectedResult: {
             lowerCase: true,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTable', database: 'database_two' }
           }
         });
@@ -1303,7 +1428,7 @@ define([
           afterCursor: ' from `database one`.`test table`',
           expectedResult: {
             lowerCase: true,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'test table', database: 'database one' }
           }
         });
@@ -1658,7 +1783,7 @@ define([
           afterCursor: ' FROM testTable',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTable' }
           }
         });
@@ -1670,7 +1795,7 @@ define([
           afterCursor: ' FROM testTable tt',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTable' }
           }
         });
@@ -1682,7 +1807,7 @@ define([
           afterCursor: ' FROM database_two.testTable tt',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTable', database: 'database_two' }
           }
         });
@@ -1694,7 +1819,7 @@ define([
           afterCursor: ' FROM testTableA tta, testTableB ttb',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTableA' }
           }
         });
@@ -1703,7 +1828,7 @@ define([
           afterCursor: ' FROM testTableA tta, testTableB ttb',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: { table: 'testTableB' }
           }
         });
@@ -1979,7 +2104,7 @@ define([
 
         it('should handle multiple joins', function() {
           assertAutoComplete({
-            beforeCursor: 'SELECT t1.* FROM table1 t1 CROSS JOIN table2 LEFT OUTER JOIN table3 JOIN table4 t4 ON (t1.c1 = t2.c2); ',
+            beforeCursor: 'SELECT t1.foo FROM table1 t1 CROSS JOIN table2 LEFT OUTER JOIN table3 JOIN table4 t4 ON (t1.c1 = t2.c2); ',
             afterCursor: '',
             dialect: 'hive',
             containsKeywords: ['SELECT'],
@@ -2110,7 +2235,7 @@ define([
           afterCursor: '',
           expectedResult: {
             lowerCase: false,
-            suggestKeywords: ['<', '<=', '<>', '=', '=>', '>', 'GROUP BY', 'IN', 'LIMIT', 'NOT IN', 'ORDER BY']
+            suggestKeywords: ['<', '<=', '<>', '=', '>', '>=', 'AND', 'GROUP BY', 'IN', 'LIMIT', 'NOT IN', 'OR', 'ORDER BY']
           }
         });
       });
@@ -2165,7 +2290,7 @@ define([
           afterCursor: '',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestTables: {
               prependQuestionMark: true,
               prependFrom: true
@@ -2186,7 +2311,7 @@ define([
           afterCursor: ')',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestTables: {
               prependQuestionMark: true,
               prependFrom: true
@@ -2230,7 +2355,7 @@ define([
           afterCursor: '',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestTables: {
               prependQuestionMark: true,
               prependFrom: true
@@ -2250,7 +2375,7 @@ define([
           afterCursor: ' FROM (SELECT bla FROM abc WHERE foo > 1) bar',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestIdentifiers: [{ name: 'bar.', type: 'subquery'}]
           }
         });
@@ -2262,7 +2387,7 @@ define([
           afterCursor: ')',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestTables: {
               prependQuestionMark: true,
               prependFrom: true
@@ -2282,7 +2407,7 @@ define([
           afterCursor: ' FROM (SELECT * FROM tableOne) AS subqueryOne, someDb.tableTwo tAlias, tableThree, (SELECT * FROM t3 JOIN t4 ON t3.id = t4.id) subqueryTwo;',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestIdentifiers: [{ name: 'subqueryOne.', type: 'subquery'}, { name: 'tAlias.', type: 'alias'}, { name: 'tableThree.', type: 'table'}, { name: 'subqueryTwo.', type: 'subquery'}]
           }
         });
@@ -2294,7 +2419,7 @@ define([
           afterCursor: ' FROM tableOne) subqueryOne, someDb.tableTwo talias, (SELECT * FROM t3 JOIN t4 ON t3.id = t4.id) AS subqueryTwo;',
           expectedResult: {
             lowerCase: false,
-            suggestStar: true,
+            suggestKeywords: ['*'],
             suggestColumns: {
               table: 'tableOne'
             }

+ 2 - 1
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecUpdate.js

@@ -180,7 +180,8 @@ define([
             database: 'bar',
             table: 'foo',
             identifierChain: [{ name: 'id' }]
-          }
+          },
+          suggestColumns : { database: 'bar', table: 'foo' }
         }
       });
     });

+ 3 - 3
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecUse.js

@@ -72,7 +72,7 @@ define([
         expectedResult: {
           useDatabase: 'database_two',
           lowerCase: true,
-          suggestStar: true,
+          suggestKeywords: ['*'],
           suggestTables: {
             prependQuestionMark: true,
             prependFrom: true
@@ -93,7 +93,7 @@ define([
         expectedResult: {
           useDatabase: 'closest_db',
           lowerCase: false,
-          suggestStar: true,
+          suggestKeywords: ['*'],
           suggestTables: {
             prependQuestionMark: true,
             prependFrom: true
@@ -114,7 +114,7 @@ define([
         expectedResult: {
           useDatabase: 'closest_db',
           lowerCase: false,
-          suggestStar: true,
+          suggestKeywords: ['*'],
           suggestTables: {
             prependQuestionMark: true,
             prependFrom: true

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно