瀏覽代碼

HUE-6092 [autocomplete] Extract parser js logic to a separate file

With this we can make changes to some of the parser logic without having to rebuild the parser
Johan Ahlen 8 年之前
父節點
當前提交
a1cef1b
共有 26 個文件被更改,包括 2996 次插入2970 次删除
  1. 67 67
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql.jisonlex
  2. 119 119
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_alter.jison
  3. 48 48
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_analyze.jison
  4. 172 172
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_create.jison
  5. 70 70
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_drop.jison
  6. 21 21
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_error.jison
  7. 73 73
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_grant.jison
  8. 56 56
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_insert.jison
  9. 55 55
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_load.jison
  10. 193 193
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_main.jison
  11. 3 3
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_set.jison
  12. 102 102
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_show.jison
  13. 7 7
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_update.jison
  14. 1 1
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_use.jison
  15. 148 148
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_valueExpression.jison
  16. 182 182
      desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_valueExpression_dev.jison
  17. 199 199
      desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js
  18. 1453 0
      desktop/core/src/desktop/static/desktop/js/autocomplete/sqlParseSupport.js
  19. 18 0
      desktop/core/src/desktop/static/desktop/js/autocomplete/sql_end.jison
  20. 0 1447
      desktop/core/src/desktop/static/desktop/js/autocomplete/sql_support.js
  21. 1 0
      desktop/core/src/desktop/templates/hue.mako
  22. 1 1
      desktop/core/src/desktop/templates/jasmineRunner.html
  23. 1 0
      desktop/libs/indexer/src/indexer/templates/importer.mako
  24. 1 0
      desktop/libs/notebook/src/notebook/templates/editor_components.mako
  25. 1 0
      desktop/libs/notebook/src/notebook/templates/editor_m.mako
  26. 4 6
      tools/jison/hue-jison.sh

+ 67 - 67
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql.jisonlex

@@ -34,21 +34,21 @@
 <hive>'BINARY'                             { return '<hive>BINARY'; }
 <hive>'COLUMN'                             { return '<hive>COLUMN'; }
 <hive>'CONF'                               { return '<hive>CONF'; }
-<hive>'CREATE'                             { determineCase(yytext); return '<hive>CREATE'; }
+<hive>'CREATE'                             { parser.determineCase(yytext); return '<hive>CREATE'; }
 <hive>'CROSS'                              { return '<hive>CROSS'; }
 <hive>'CUBE'                               { return '<hive>CUBE'; }
 <hive>'CURRENT'                            { return '<hive>CURRENT'; }
 <hive>'DATE'                               { return '<hive>DATE'; }
-<hive>'DELETE'                             { determineCase(yytext); return '<hive>DELETE'; }
-<hive>'DESCRIBE'                           { determineCase(yytext); return '<hive>DESCRIBE'; }
+<hive>'DELETE'                             { parser.determineCase(yytext); return '<hive>DELETE'; }
+<hive>'DESCRIBE'                           { parser.determineCase(yytext); return '<hive>DESCRIBE'; }
 <hive>'EXTENDED'                           { return '<hive>EXTENDED'; }
 <hive>'EXTERNAL'                           { return '<hive>EXTERNAL'; }
 <hive>'FOR'                                { return '<hive>FOR'; }
 <hive>'FUNCTION'                           { return '<hive>FUNCTION'; }
 <hive>'GRANT'                              { return '<hive>GRANT'; }
 <hive>'GROUPING'                           { return '<hive>GROUPING'; }
-<hive>'IMPORT'                             { determineCase(yytext); return '<hive>IMPORT'; }
-<hive>'INSERT'                             { determineCase(yytext); return '<hive>INSERT'; }
+<hive>'IMPORT'                             { parser.determineCase(yytext); return '<hive>IMPORT'; }
+<hive>'INSERT'                             { parser.determineCase(yytext); return '<hive>INSERT'; }
 <hive>'LATERAL'                            { return '<hive>LATERAL'; }
 <hive>'LOCAL'                              { return '<hive>LOCAL'; }
 <hive>'MACRO'                              { return '<hive>MACRO'; }
@@ -66,7 +66,7 @@
 <hive>'ADD'                                { return '<hive>ADD'; }
 <hive>'ADMIN'                              { return '<hive>ADMIN'; }
 <hive>'AFTER'                              { return '<hive>AFTER'; }
-<hive>'ANALYZE'                            { determineCase(yytext); return '<hive>ANALYZE'; }
+<hive>'ANALYZE'                            { parser.determineCase(yytext); return '<hive>ANALYZE'; }
 <hive>'ARCHIVE'                            { return '<hive>ARCHIVE'; }
 <hive>'ASC'                                { return '<hive>ASC'; }
 <hive>'AVRO'                               { return '<hive>AVRO'; }
@@ -97,8 +97,8 @@
 <hive>'ESCAPED'                            { return '<hive>ESCAPED'; }
 <hive>'ENABLE'                             { return '<hive>ENABLE'; }
 <hive>'EXCHANGE'                           { return '<hive>EXCHANGE'; }
-<hive>'EXPLAIN'                            { determineCase(yytext); return '<hive>EXPLAIN'; }
-<hive>'EXPORT'                             { determineCase(yytext); return '<hive>EXPORT'; }
+<hive>'EXPLAIN'                            { parser.determineCase(yytext); return '<hive>EXPLAIN'; }
+<hive>'EXPORT'                             { parser.determineCase(yytext); return '<hive>EXPORT'; }
 <hive>'FIELDS'                             { return '<hive>FIELDS'; }
 <hive>'FILE'                               { return '<hive>FILE'; }
 <hive>'FILEFORMAT'                         { return '<hive>FILEFORMAT'; }
@@ -116,7 +116,7 @@
 <hive>'JAR'                                { return '<hive>JAR'; }
 <hive>'KEYS'                               { return '<hive>KEYS'; }
 <hive>'LINES'                              { return '<hive>LINES'; }
-<hive>'LOAD'                               { determineCase(yytext); return '<hive>LOAD'; }
+<hive>'LOAD'                               { parser.determineCase(yytext); return '<hive>LOAD'; }
 <hive>'LOCATION'                           { this.begin('hdfs'); return '<hive>LOCATION'; }
 <hive>'LOCK'                               { return '<hive>LOCK'; }
 <hive>'LOCKS'                              { return '<hive>LOCKS'; }
@@ -136,7 +136,7 @@
 <hive>'PURGE'                              { return '<hive>PURGE'; }
 <hive>'RCFILE'                             { return '<hive>RCFILE'; }
 <hive>'REBUILD'                            { return '<hive>REBUILD'; }
-<hive>'RELOAD'                             { determineCase(yytext); return '<hive>RELOAD'; }
+<hive>'RELOAD'                             { parser.determineCase(yytext); return '<hive>RELOAD'; }
 <hive>'REPAIR'                             { return '<hive>REPAIR'; }
 <hive>'REPLICATION'                        { return '<hive>REPLICATION'; }
 <hive>'RECOVER'                            { return '<hive>RECOVER'; }
@@ -151,7 +151,7 @@
 <hive>'SERDE'                              { return '<hive>SERDE'; }
 <hive>'SERDEPROPERTIES'                    { return '<hive>SERDEPROPERTIES'; }
 <hive>'SETS'                               { return '<hive>SETS'; }
-<hive>'SHOW'                               { determineCase(yytext); return '<hive>SHOW'; }
+<hive>'SHOW'                               { parser.determineCase(yytext); return '<hive>SHOW'; }
 <hive>'SHOW_DATABASE'                      { return '<hive>SHOW_DATABASE'; }
 <hive>'SKEWED'                             { return '<hive>SKEWED'; }
 <hive>'SKEWED LOCATION'                    { return '<hive>SKEWED_LOCATION'; } // Hack to prevent hdfs lexer state
@@ -173,7 +173,7 @@
 <hive>'TRANSACTIONS'                       { return '<hive>TRANSACTIONS'; }
 <hive>'UNARCHIVE'                          { return '<hive>UNARCHIVE'; }
 <hive>'UNIONTYPE'                          { return '<hive>UNIONTYPE'; }
-<hive>'USE'                                { determineCase(yytext); return '<hive>USE'; }
+<hive>'USE'                                { parser.determineCase(yytext); return '<hive>USE'; }
 <hive>'VIEW'                               { return '<hive>VIEW'; }
 <hive>'WINDOW'                             { return '<hive>WINDOW'; }
 
@@ -191,14 +191,14 @@
 <impala>'COLUMN'                           { return '<impala>COLUMN'; }
 <impala>'COLUMNS'                          { return '<impala>COLUMNS'; }
 <impala>'COMMENT'                          { return '<impala>COMMENT'; }
-<impala>'COMPUTE'                          { determineCase(yytext); return '<impala>COMPUTE'; }
-<impala>'CREATE'                           { determineCase(yytext); return '<impala>CREATE'; }
+<impala>'COMPUTE'                          { parser.determineCase(yytext); return '<impala>COMPUTE'; }
+<impala>'CREATE'                           { parser.determineCase(yytext); return '<impala>CREATE'; }
 <impala>'DATA'                             { return '<impala>DATA'; }
 <impala>'DATABASES'                        { return '<impala>DATABASES'; }
 <impala>'DELIMITED'                        { return '<impala>DELIMITED'; }
-<impala>'DESCRIBE'                         { determineCase(yytext); return '<impala>DESCRIBE'; }
+<impala>'DESCRIBE'                         { parser.determineCase(yytext); return '<impala>DESCRIBE'; }
 <impala>'ESCAPED'                          { return '<impala>ESCAPED'; }
-<impala>'EXPLAIN'                          { determineCase(yytext); return '<impala>EXPLAIN'; }
+<impala>'EXPLAIN'                          { parser.determineCase(yytext); return '<impala>EXPLAIN'; }
 <impala>'EXTERNAL'                         { return '<impala>EXTERNAL'; }
 <impala>'EXTENDED'                         { return '<impala>EXTENDED'; }
 <impala>'FIELDS'                           { return '<impala>FIELDS'; }
@@ -212,10 +212,10 @@
 <impala>'GROUP'                            { return '<impala>GROUP'; }
 <impala>'HASH'                             { return '<impala>HASH'; }
 <impala>'INCREMENTAL'                      { return '<impala>INCREMENTAL'; }
-<impala>'INSERT'                           { determineCase(yytext); return '<impala>INSERT'; }
+<impala>'INSERT'                           { parser.determineCase(yytext); return '<impala>INSERT'; }
 <impala>'INTERVAL'                         { return '<impala>INTERVAL'; }
 <impala>'INIT_FN'                          { return '<impala>INIT_FN'; }
-<impala>'INVALIDATE'                       { determineCase(yytext); return '<impala>INVALIDATE'; }
+<impala>'INVALIDATE'                       { parser.determineCase(yytext); return '<impala>INVALIDATE'; }
 <impala>'INPATH'                           { this.begin('hdfs'); return '<impala>INPATH'; }
 <impala>'KEY'                              { return '<impala>KEY'; }
 <impala>'KUDU'                             { return '<impala>KUDU'; }
@@ -223,7 +223,7 @@
 <impala>LIKE\s+PARQUET                     { this.begin('hdfs'); return '<impala>LIKE_PARQUET'; }
 <impala>'LIMIT'                            { return '<impala>LIMIT'; }
 <impala>'LINES'                            { return '<impala>LINES'; }
-<impala>'LOAD'                             { determineCase(yytext); return '<impala>LOAD'; }
+<impala>'LOAD'                             { parser.determineCase(yytext); return '<impala>LOAD'; }
 <impala>'LOCATION'                         { this.begin('hdfs'); return '<impala>LOCATION'; }
 <impala>'MERGE_FN'                         { return '<impala>MERGE_FN'; }
 <impala>'METADATA'                         { return '<impala>METADATA'; }
@@ -237,7 +237,7 @@
 <impala>'PRIMARY'                          { return '<impala>PRIMARY'; }
 <impala>'RCFILE'                           { return '<impala>RCFILE'; }
 <impala>'REAL'                             { return '<impala>REAL'; }
-<impala>'REFRESH'                          { determineCase(yytext); return '<impala>REFRESH'; }
+<impala>'REFRESH'                          { parser.determineCase(yytext); return '<impala>REFRESH'; }
 <impala>'RENAME'                           { return '<impala>RENAME'; }
 <impala>'REPLACE'                          { return '<impala>REPLACE'; }
 <impala>'RETURNS'                          { return '<impala>RETURNS'; }
@@ -286,7 +286,7 @@
 
 // Reserved Keywords
 'ALL'                                      { return 'ALL'; }
-'ALTER'                                    { determineCase(yytext); return 'ALTER'; }
+'ALTER'                                    { parser.determineCase(yytext); return 'ALTER'; }
 'AND'                                      { return 'AND'; }
 'AS'                                       { return 'AS'; }
 'ASC'                                      { return 'ASC'; }
@@ -296,21 +296,21 @@
 'BY'                                       { return 'BY'; }
 'CASE'                                     { return 'CASE'; }
 'CHAR'                                     { return 'CHAR'; }
-'CREATE'                                   { determineCase(yytext); return 'CREATE'; }
+'CREATE'                                   { parser.determineCase(yytext); return 'CREATE'; }
 'CURRENT'                                  { return 'CURRENT'; }
 'DATABASE'                                 { return 'DATABASE'; }
 'DECIMAL'                                  { return 'DECIMAL'; }
 'DISTINCT'                                 { return 'DISTINCT'; }
 'DOUBLE'                                   { return 'DOUBLE'; }
 'DESC'                                     { return 'DESC'; }
-'DROP'                                     { determineCase(yytext); return 'DROP'; }
+'DROP'                                     { parser.determineCase(yytext); return 'DROP'; }
 'ELSE'                                     { return 'ELSE'; }
 'END'                                      { return 'END'; }
 'EXISTS'                                   { parser.yy.correlatedSubQuery = true; return 'EXISTS'; }
 'FALSE'                                    { return 'FALSE'; }
 'FLOAT'                                    { return 'FLOAT'; }
 'FOLLOWING'                                { return 'FOLLOWING'; }
-'FROM'                                     { determineCase(yytext); return 'FROM'; }
+'FROM'                                     { parser.determineCase(yytext); return 'FROM'; }
 'FULL'                                     { return 'FULL'; }
 'GROUP'                                    { return 'GROUP'; }
 'HAVING'                                   { return 'HAVING'; }
@@ -341,10 +341,10 @@
 'ROW'                                      { return 'ROW'; }
 'ROWS'                                     { return 'ROWS'; }
 'SCHEMA'                                   { return 'SCHEMA'; }
-'SELECT'                                   { determineCase(yytext); return 'SELECT'; }
+'SELECT'                                   { parser.determineCase(yytext); return 'SELECT'; }
 'SEMI'                                     { return 'SEMI'; }
-'SET'                                      { determineCase(yytext); return 'SET'; }
-'SHOW'                                     { determineCase(yytext); return 'SHOW'; }
+'SET'                                      { parser.determineCase(yytext); return 'SET'; }
+'SHOW'                                     { parser.determineCase(yytext); return 'SHOW'; }
 'SMALLINT'                                 { return 'SMALLINT'; }
 'STRING'                                   { return 'STRING'; }
 'TABLE'                                    { return 'TABLE'; }
@@ -353,60 +353,60 @@
 'TINYINT'                                  { return 'TINYINT'; }
 'TO'                                       { return 'TO'; }
 'TRUE'                                     { return 'TRUE'; }
-'TRUNCATE'                                 { determineCase(yytext); return 'TRUNCATE'; }
+'TRUNCATE'                                 { parser.determineCase(yytext); return 'TRUNCATE'; }
 'UNBOUNDED'                                { return 'UNBOUNDED'; }
-'UPDATE'                                   { determineCase(yytext); return 'UPDATE'; }
-'USE'                                      { determineCase(yytext); return 'USE'; }
+'UPDATE'                                   { parser.determineCase(yytext); return 'UPDATE'; }
+'USE'                                      { parser.determineCase(yytext); return 'USE'; }
 'UNION'                                    { return 'UNION'; }
 'VIEW'                                     { return 'VIEW'; }
 'VARCHAR'                                  { return 'VARCHAR'; } // Not in Impala
 'VALUES'                                   { return 'VALUES'; }
 'WHEN'                                     { return 'WHEN'; }
 'WHERE'                                    { return 'WHERE'; }
-'WITH'                                     { determineCase(yytext); return 'WITH'; }
+'WITH'                                     { parser.determineCase(yytext); return 'WITH'; }
 
 // Non-reserved Keywords
 'OVER'                                     { return 'OVER'; }
 'ROLE'                                     { return 'ROLE'; }
 
 // --- UDFs ---
-AVG\s*\(                                    { yy.lexer.unput('('); yytext = 'avg'; addFunctionLocation(yylloc, yytext); return 'AVG'; }
-CAST\s*\(                                  { yy.lexer.unput('('); yytext = 'cast'; addFunctionLocation(yylloc, yytext); return 'CAST'; }
-COUNT\s*\(                                 { yy.lexer.unput('('); yytext = 'count'; addFunctionLocation(yylloc, yytext); return 'COUNT'; }
-MAX\s*\(                                   { yy.lexer.unput('('); yytext = 'max'; addFunctionLocation(yylloc, yytext); return 'MAX'; }
-MIN\s*\(                                   { yy.lexer.unput('('); yytext = 'min'; addFunctionLocation(yylloc, yytext); return 'MIN'; }
-STDDEV_POP\s*\(                            { yy.lexer.unput('('); yytext = 'stddev_pop'; addFunctionLocation(yylloc, yytext); return 'STDDEV_POP'; }
-STDDEV_SAMP\s*\(                           { yy.lexer.unput('('); yytext = 'stddev_samp'; addFunctionLocation(yylloc, yytext); return 'STDDEV_SAMP'; }
-SUM\s*\(                                   { yy.lexer.unput('('); yytext = 'sum'; addFunctionLocation(yylloc, yytext); return 'SUM'; }
-VARIANCE\s*\(                              { yy.lexer.unput('('); yytext = 'variance'; addFunctionLocation(yylloc, yytext); return 'VARIANCE'; }
-VAR_POP\s*\(                               { yy.lexer.unput('('); yytext = 'var_pop'; addFunctionLocation(yylloc, yytext); return 'VAR_POP'; }
-VAR_SAMP\s*\(                              { yy.lexer.unput('('); yytext = 'var_samp'; addFunctionLocation(yylloc, yytext); return 'VAR_SAMP'; }
-<hive>COLLECT_SET\s*\(                     { yy.lexer.unput('('); yytext = 'collect_set'; addFunctionLocation(yylloc, yytext); return '<hive>COLLECT_SET'; }
-<hive>COLLECT_LIST\s*\(                    { yy.lexer.unput('('); yytext = 'collect_list'; addFunctionLocation(yylloc, yytext); return '<hive>COLLECT_LIST'; }
-<hive>CORR\s*\(                            { yy.lexer.unput('('); yytext = 'corr'; addFunctionLocation(yylloc, yytext); return '<hive>CORR'; }
-<hive>COVAR_POP\s*\(                       { yy.lexer.unput('('); yytext = 'covar_pop'; addFunctionLocation(yylloc, yytext); return '<hive>COVAR_POP'; }
-<hive>COVAR_SAMP\s*\(                      { yy.lexer.unput('('); yytext = 'covar_samp'; addFunctionLocation(yylloc, yytext); return '<hive>COVAR_SAMP'; }
-<hive>HISTOGRAM_NUMERIC\s*\(               { yy.lexer.unput('('); yytext = 'histogram_numeric'; addFunctionLocation(yylloc, yytext); return '<hive>HISTOGRAM_NUMERIC'; }
-<hive>NTILE\s*\(                           { yy.lexer.unput('('); yytext = 'ntile'; addFunctionLocation(yylloc, yytext); return '<hive>NTILE'; }
-<hive>PERCENTILE\s*\(                      { yy.lexer.unput('('); yytext = 'percentile'; addFunctionLocation(yylloc, yytext); return '<hive>PERCENTILE'; }
-<hive>PERCENTILE_APPROX\s*\(               { yy.lexer.unput('('); yytext = 'percentile_approx'; addFunctionLocation(yylloc, yytext); return '<hive>PERCENTILE_APPROX'; }
-<impala>APPX_MEDIAN\s*\(                   { yy.lexer.unput('('); yytext = 'appx_median'; addFunctionLocation(yylloc, yytext); return '<impala>APPX_MEDIAN'; }
-<impala>EXTRACT\s*\(                       { yy.lexer.unput('('); yytext = 'extract'; addFunctionLocation(yylloc, yytext); return '<impala>EXTRACT'; }
-<impala>GROUP_CONCAT\s*\(                  { yy.lexer.unput('('); yytext = 'group_concat'; addFunctionLocation(yylloc, yytext); return '<impala>GROUP_CONCAT'; }
-<impala>STDDEV\s*\(                        { yy.lexer.unput('('); yytext = 'stddev'; addFunctionLocation(yylloc, yytext); return '<impala>STDDEV'; }
-<impala>VARIANCE_POP\s*\(                  { yy.lexer.unput('('); yytext = 'variance_pop'; addFunctionLocation(yylloc, yytext); return '<impala>VARIANCE_POP'; }
-<impala>VARIANCE_SAMP\s*\(                 { yy.lexer.unput('('); yytext = 'variance_samp'; addFunctionLocation(yylloc, yytext); return '<impala>VARIANCE_SAMP'; }
+AVG\s*\(                                   { yy.lexer.unput('('); yytext = 'avg'; parser.addFunctionLocation(yylloc, yytext); return 'AVG'; }
+CAST\s*\(                                  { yy.lexer.unput('('); yytext = 'cast'; parser.addFunctionLocation(yylloc, yytext); return 'CAST'; }
+COUNT\s*\(                                 { yy.lexer.unput('('); yytext = 'count'; parser.addFunctionLocation(yylloc, yytext); return 'COUNT'; }
+MAX\s*\(                                   { yy.lexer.unput('('); yytext = 'max'; parser.addFunctionLocation(yylloc, yytext); return 'MAX'; }
+MIN\s*\(                                   { yy.lexer.unput('('); yytext = 'min'; parser.addFunctionLocation(yylloc, yytext); return 'MIN'; }
+STDDEV_POP\s*\(                            { yy.lexer.unput('('); yytext = 'stddev_pop'; parser.addFunctionLocation(yylloc, yytext); return 'STDDEV_POP'; }
+STDDEV_SAMP\s*\(                           { yy.lexer.unput('('); yytext = 'stddev_samp'; parser.addFunctionLocation(yylloc, yytext); return 'STDDEV_SAMP'; }
+SUM\s*\(                                   { yy.lexer.unput('('); yytext = 'sum'; parser.addFunctionLocation(yylloc, yytext); return 'SUM'; }
+VARIANCE\s*\(                              { yy.lexer.unput('('); yytext = 'variance'; parser.addFunctionLocation(yylloc, yytext); return 'VARIANCE'; }
+VAR_POP\s*\(                               { yy.lexer.unput('('); yytext = 'var_pop'; parser.addFunctionLocation(yylloc, yytext); return 'VAR_POP'; }
+VAR_SAMP\s*\(                              { yy.lexer.unput('('); yytext = 'var_samp'; parser.addFunctionLocation(yylloc, yytext); return 'VAR_SAMP'; }
+<hive>COLLECT_SET\s*\(                     { yy.lexer.unput('('); yytext = 'collect_set'; parser.addFunctionLocation(yylloc, yytext); return '<hive>COLLECT_SET'; }
+<hive>COLLECT_LIST\s*\(                    { yy.lexer.unput('('); yytext = 'collect_list'; parser.addFunctionLocation(yylloc, yytext); return '<hive>COLLECT_LIST'; }
+<hive>CORR\s*\(                            { yy.lexer.unput('('); yytext = 'corr'; parser.addFunctionLocation(yylloc, yytext); return '<hive>CORR'; }
+<hive>COVAR_POP\s*\(                       { yy.lexer.unput('('); yytext = 'covar_pop'; parser.addFunctionLocation(yylloc, yytext); return '<hive>COVAR_POP'; }
+<hive>COVAR_SAMP\s*\(                      { yy.lexer.unput('('); yytext = 'covar_samp'; parser.addFunctionLocation(yylloc, yytext); return '<hive>COVAR_SAMP'; }
+<hive>HISTOGRAM_NUMERIC\s*\(               { yy.lexer.unput('('); yytext = 'histogram_numeric'; parser.addFunctionLocation(yylloc, yytext); return '<hive>HISTOGRAM_NUMERIC'; }
+<hive>NTILE\s*\(                           { yy.lexer.unput('('); yytext = 'ntile'; parser.addFunctionLocation(yylloc, yytext); return '<hive>NTILE'; }
+<hive>PERCENTILE\s*\(                      { yy.lexer.unput('('); yytext = 'percentile'; parser.addFunctionLocation(yylloc, yytext); return '<hive>PERCENTILE'; }
+<hive>PERCENTILE_APPROX\s*\(               { yy.lexer.unput('('); yytext = 'percentile_approx'; parser.addFunctionLocation(yylloc, yytext); return '<hive>PERCENTILE_APPROX'; }
+<impala>APPX_MEDIAN\s*\(                   { yy.lexer.unput('('); yytext = 'appx_median'; parser.addFunctionLocation(yylloc, yytext); return '<impala>APPX_MEDIAN'; }
+<impala>EXTRACT\s*\(                       { yy.lexer.unput('('); yytext = 'extract'; parser.addFunctionLocation(yylloc, yytext); return '<impala>EXTRACT'; }
+<impala>GROUP_CONCAT\s*\(                  { yy.lexer.unput('('); yytext = 'group_concat'; parser.addFunctionLocation(yylloc, yytext); return '<impala>GROUP_CONCAT'; }
+<impala>STDDEV\s*\(                        { yy.lexer.unput('('); yytext = 'stddev'; parser.addFunctionLocation(yylloc, yytext); return '<impala>STDDEV'; }
+<impala>VARIANCE_POP\s*\(                  { yy.lexer.unput('('); yytext = 'variance_pop'; parser.addFunctionLocation(yylloc, yytext); return '<impala>VARIANCE_POP'; }
+<impala>VARIANCE_SAMP\s*\(                 { yy.lexer.unput('('); yytext = 'variance_samp'; parser.addFunctionLocation(yylloc, yytext); return '<impala>VARIANCE_SAMP'; }
 
 // Analytical functions
-DENSE_RANK\s*\(                            { yy.lexer.unput('('); yytext = 'dense_rank'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
-FIRST_VALUE\s*\(                           { yy.lexer.unput('('); yytext = 'first_value'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
-LAG\s*\(                                   { yy.lexer.unput('('); yytext = 'lag'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
-LAST_VALUE\s*\(                            { yy.lexer.unput('('); yytext = 'last_value'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
-LEAD\s*\(                                  { yy.lexer.unput('('); yytext = 'lead'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
-RANK\s*\(                                  { yy.lexer.unput('('); yytext = 'rank'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
-ROW_NUMBER\s*\(                            { yy.lexer.unput('('); yytext = 'row_number'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
-<hive>CUME_DIST\s*\(                       { yy.lexer.unput('('); yytext = 'cume_dist'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
-<hive>PERCENT_RANK\s*\(                    { yy.lexer.unput('('); yytext = 'percent_rank'; addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+DENSE_RANK\s*\(                            { yy.lexer.unput('('); yytext = 'dense_rank'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+FIRST_VALUE\s*\(                           { yy.lexer.unput('('); yytext = 'first_value'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+LAG\s*\(                                   { yy.lexer.unput('('); yytext = 'lag'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+LAST_VALUE\s*\(                            { yy.lexer.unput('('); yytext = 'last_value'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+LEAD\s*\(                                  { yy.lexer.unput('('); yytext = 'lead'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+RANK\s*\(                                  { yy.lexer.unput('('); yytext = 'rank'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+ROW_NUMBER\s*\(                            { yy.lexer.unput('('); yytext = 'row_number'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+<hive>CUME_DIST\s*\(                       { yy.lexer.unput('('); yytext = 'cume_dist'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
+<hive>PERCENT_RANK\s*\(                    { yy.lexer.unput('('); yytext = 'percent_rank'; parser.addFunctionLocation(yylloc, yytext); return 'ANALYTIC'; }
 
 [0-9]+                                     { return 'UNSIGNED_INTEGER'; }
 [0-9]+(?:[YSL]|BD)?                        { return 'UNSIGNED_INTEGER'; }
@@ -416,7 +416,7 @@ ROW_NUMBER\s*\(                            { yy.lexer.unput('('); yytext = 'row_
 <hdfs>'\u2020'                             { parser.yy.cursorFound = true; return 'CURSOR'; }
 <hdfs>'\u2021'                             { parser.yy.cursorFound = true; return 'PARTIAL_CURSOR'; }
 <hdfs>\s+[']                               { return 'HDFS_START_QUOTE'; }
-<hdfs>[^'\u2020\u2021]+                    { addHdfsLocation(yylloc, yytext); return 'HDFS_PATH'; }
+<hdfs>[^'\u2020\u2021]+                    { parser.addHdfsLocation(yylloc, yytext); return 'HDFS_PATH'; }
 <hdfs>[']                                  { this.popState(); return 'HDFS_END_QUOTE'; }
 <hdfs><<EOF>>                              { return 'EOF'; }
 

+ 119 - 119
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_alter.jison

@@ -38,10 +38,10 @@ AlterStatement_EDIT
  | ReloadFunction_EDIT
  | 'ALTER' 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['INDEX', 'TABLE', 'VIEW']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['INDEX', 'TABLE', 'VIEW']);
      } else {
-       suggestKeywords(['TABLE', 'VIEW']);
+       parser.suggestKeywords(['TABLE', 'VIEW']);
      }
    }
  ;
@@ -49,32 +49,32 @@ AlterStatement_EDIT
 AlterIndex
  : 'ALTER' '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' SchemaQualifiedTableIdentifier OptionalPartitionSpec '<hive>REBUILD'
    {
-     addTablePrimary($5);
+     parser.addTablePrimary($5);
    }
  ;
 
 AlterIndex_EDIT
  : 'ALTER' '<hive>INDEX' RegularOrBacktickedIdentifier 'CURSOR'
    {
-     suggestKeywords(['ON']);
+     parser.suggestKeywords(['ON']);
    }
  | 'ALTER' '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'ALTER' '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' SchemaQualifiedTableIdentifier_EDIT
  | 'ALTER' '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT
    {
-     addTablePrimary($5);
+     parser.addTablePrimary($5);
    }
  | 'ALTER' '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
    {
-     addTablePrimary($5);
+     parser.addTablePrimary($5);
      if (!$6) {
-       suggestKeywords(['PARTITION', 'REBUILD']);
+       parser.suggestKeywords(['PARTITION', 'REBUILD']);
      } else {
-       suggestKeywords(['REBUILD']);
+       parser.suggestKeywords(['REBUILD']);
      }
    }
  ;
@@ -98,34 +98,34 @@ AlterTable_EDIT
  | AlterTableLeftSide_EDIT PartitionSpec OptionalPartitionOperations
  | AlterTableLeftSide AnyAdd OptionalIfNotExists 'CURSOR'
    {
-     if (isHive()) {
+     if (parser.isHive()) {
        if (!$3) {
-         suggestKeywords([{ value: 'IF NOT EXISTS', weight: 3 }, { value: 'COLUMNS', weight: 2 }, { value: 'PARTITION', weight: 1 }]);
+         parser.suggestKeywords([{ value: 'IF NOT EXISTS', weight: 3 }, { value: 'COLUMNS', weight: 2 }, { value: 'PARTITION', weight: 1 }]);
        } else {
-         suggestKeywords(['PARTITION']);
+         parser.suggestKeywords(['PARTITION']);
        }
-     } else if (isImpala()) {
-       suggestKeywords([{ value: 'COLUMNS', weight: 2 }, { value: 'PARTITION', weight: 1 }]);
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords([{ value: 'COLUMNS', weight: 2 }, { value: 'PARTITION', weight: 1 }]);
      }
    }
  | AlterTableLeftSide AnyReplace 'CURSOR'
    {
-     suggestKeywords(['COLUMNS']);
+     parser.suggestKeywords(['COLUMNS']);
    }
  | AlterTableLeftSide AnyAdd OptionalIfNotExists_EDIT
  | AlterTableLeftSide AnyAdd OptionalIfNotExists PartitionSpec HdfsLocation_EDIT OptionalPartitionSpecs
  | AlterTableLeftSide AnyAdd OptionalIfNotExists PartitionSpec OptionalHdfsLocation OptionalPartitionSpecs_EDIT
  | AlterTableLeftSide AnyAdd OptionalIfNotExists PartitionSpec OptionalHdfsLocation OptionalPartitionSpecs 'CURSOR'
    {
-     if (isHive()) {
+     if (parser.isHive()) {
        if (!$5 && !$6) {
-         suggestKeywords(['LOCATION', 'PARTITION']);
+         parser.suggestKeywords(['LOCATION', 'PARTITION']);
        } else if ($6 && $6.suggestKeywords) {
-         var keywords = createWeightedKeywords($6.suggestKeywords, 2);
+         var keywords = parser.createWeightedKeywords($6.suggestKeywords, 2);
          keywords.push({ value: 'PARTITION', weight: 1 });
-         suggestKeywords(keywords);
+         parser.suggestKeywords(keywords);
        } else {
-         suggestKeywords(['PARTITION']);
+         parser.suggestKeywords(['PARTITION']);
        }
      }
    }
@@ -135,53 +135,53 @@ AlterTable_EDIT
  | AlterTableLeftSide DropOperations_EDIT
  | AlterTableLeftSide 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['ADD COLUMNS', 'ADD IF NOT EXISTS', 'ADD PARTITION', 'ARCHIVE PARTITION', 'CHANGE',
+     if (parser.isHive()) {
+       parser.suggestKeywords(['ADD COLUMNS', 'ADD IF NOT EXISTS', 'ADD PARTITION', 'ARCHIVE PARTITION', 'CHANGE',
          'CLUSTERED BY', 'CONCATENATE', 'COMPACT', 'DISABLE NO_DROP', 'DISABLE OFFLINE', 'DROP', 'ENABLE NO_DROP',
          'ENABLE OFFLINE', 'EXCHANGE PARTITION', 'NOT SKEWED', 'NOT STORED AS DIRECTORIES', 'PARTITION',
          'RECOVER PARTITIONS', 'RENAME TO', 'REPLACE COLUMNS', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDE',
          'SET SERDEPROPERTIES', 'SET SKEWED LOCATION', 'SET TBLPROPERTIES', 'SKEWED BY', 'TOUCH', 'UNARCHIVE PARTITION']);
-     } else if (isImpala()) {
-       suggestKeywords(['ADD COLUMNS', 'ADD PARTITION', 'CHANGE', 'DROP COLUMN', 'DROP PARTITION', 'PARTITION',
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords(['ADD COLUMNS', 'ADD PARTITION', 'CHANGE', 'DROP COLUMN', 'DROP PARTITION', 'PARTITION',
          'RENAME TO', 'REPLACE COLUMNS', 'SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDEPROPERTIES',
          'SET TBLPROPERTIES', 'SET UNCACHED']);
      }
    }
  | AlterTableLeftSide PartitionSpec 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['ADD COLUMNS', 'CHANGE', 'COMPACT', 'CONCATENATE', 'DISABLE NO_DROP', 'DISABLE OFFLINE',
+     if (parser.isHive()) {
+       parser.suggestKeywords(['ADD COLUMNS', 'CHANGE', 'COMPACT', 'CONCATENATE', 'DISABLE NO_DROP', 'DISABLE OFFLINE',
          'ENABLE NO_DROP', 'ENABLE OFFLINE', 'RENAME TO PARTITION', 'REPLACE COLUMNS', 'SET FILEFORMAT', 'SET LOCATION',
          'SET SERDE', 'SET SERDEPROPERTIES']);
-     } else if (isImpala()) {
-       suggestKeywords(['SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDEPROPERTIES', 'SET TBLPROPERTIES',
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords(['SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDEPROPERTIES', 'SET TBLPROPERTIES',
          'SET UNCACHED']);
      }
    }
  | AlterTableLeftSide PartitionSpec AddOrReplace 'CURSOR'
    {
-     suggestKeywords(['COLUMNS']);
+     parser.suggestKeywords(['COLUMNS']);
    }
  | AlterTableLeftSide PartitionSpec 'SET' 'CURSOR'
     {
-      if (isHive()) {
-        suggestKeywords(['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES']);
-      } else if (isImpala()) {
-        suggestKeywords(['CACHED IN', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES','TBLPROPERTIES', 'UNCACHED']);
+      if (parser.isHive()) {
+        parser.suggestKeywords(['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES']);
+      } else if (parser.isImpala()) {
+        parser.suggestKeywords(['CACHED IN', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES','TBLPROPERTIES', 'UNCACHED']);
       }
     }
  | AlterTableLeftSide 'SET' 'CURSOR'
     {
-      if (isHive()) {
-        suggestKeywords(['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES', 'SKEWED LOCATION', 'TBLPROPERTIES']);
-      } else if (isImpala()) {
-        suggestKeywords(['CACHED IN', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES', 'TBLPROPERTIES', 'UNCACHED']);
+      if (parser.isHive()) {
+        parser.suggestKeywords(['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES', 'SKEWED LOCATION', 'TBLPROPERTIES']);
+      } else if (parser.isImpala()) {
+        parser.suggestKeywords(['CACHED IN', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES', 'TBLPROPERTIES', 'UNCACHED']);
       }
     }
  | AlterTableLeftSide PartitionSpec OptionalPartitionOperations_EDIT
  | AlterTableLeftSide AnyRename 'CURSOR'
    {
-     suggestKeywords(['TO']);
+     parser.suggestKeywords(['TO']);
    }
  ;
 
@@ -202,62 +202,62 @@ HiveSpecificOperations
 HiveSpecificOperations_EDIT
  : HiveArchiveOrUnArchive 'CURSOR'
    {
-     suggestKeywords(['PARTITION']);
+     parser.suggestKeywords(['PARTITION']);
    }
  | HiveArchiveOrUnArchive PartitionSpec_EDIT
  | ClusteredBy_EDIT
  | HiveExchange_EDIT
  | 'NOT' 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['SKEWED', 'STORED AS DIRECTORIES']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['SKEWED', 'STORED AS DIRECTORIES']);
      }
    }
  | 'NOT' '<hive>STORED' 'CURSOR'
    {
-     suggestKeywords(['AS DIRECTORIES']);
+     parser.suggestKeywords(['AS DIRECTORIES']);
    }
  | 'NOT' '<hive>STORED' '<hive>AS' 'CURSOR'
    {
-     suggestKeywords(['DIRECTORIES']);
+     parser.suggestKeywords(['DIRECTORIES']);
    }
  | PartitionSpec '<hive>RENAME' 'CURSOR'
    {
-     suggestKeywords(['TO PARTITION']);
+     parser.suggestKeywords(['TO PARTITION']);
    }
  | PartitionSpec '<hive>RENAME' 'TO' 'CURSOR'
    {
-     suggestKeywords(['PARTITION']);
+     parser.suggestKeywords(['PARTITION']);
    }
  | '<hive>RECOVER' 'CURSOR'
    {
-     suggestKeywords(['PARTITIONS']);
+     parser.suggestKeywords(['PARTITIONS']);
    }
  | 'SET' '<hive>SKEWED' 'CURSOR'
    {
-     suggestKeywords(['LOCATION']);
+     parser.suggestKeywords(['LOCATION']);
    }
  | 'SET' '<hive>SKEWED_LOCATION' ParenthesizedSkewedLocationList_EDIT
  | '<hive>SKEWED' 'CURSOR'
    {
-     suggestKeywords(['BY']);
+     parser.suggestKeywords(['BY']);
    }
  | '<hive>SKEWED' 'BY' ParenthesizedColumnList_EDIT
  | '<hive>SKEWED' 'BY' ParenthesizedColumnList_EDIT 'ON' ParenthesizedSkewedValueList OptionalStoredAsDirectories
  | '<hive>SKEWED' 'BY' ParenthesizedColumnList 'CURSOR'
    {
-     suggestKeywords(['ON']);
+     parser.suggestKeywords(['ON']);
    }
  | '<hive>SKEWED' 'BY' ParenthesizedColumnList 'ON' ParenthesizedSkewedValueList OptionalStoredAsDirectories 'CURSOR'
    {
      if (!$6) {
-       suggestKeywords(['STORED AS DIRECTORIES']);
+       parser.suggestKeywords(['STORED AS DIRECTORIES']);
      }
    }
  | '<hive>SKEWED' 'BY' ParenthesizedColumnList 'ON' ParenthesizedSkewedValueList OptionalStoredAsDirectories_EDIT
  | '<hive>TOUCH' 'CURSOR'
    {
-     suggestKeywords(['PARTITION']);
+     parser.suggestKeywords(['PARTITION']);
    }
  | '<hive>TOUCH' OptionalPartitionSpec_EDIT
  ;
@@ -281,41 +281,41 @@ OptionalPartitionOperations_EDIT
  : AddReplaceColumns_EDIT
  | AnyChange OptionalHiveColumn 'CURSOR'
    {
-     if (isHive() && !$2) {
-       suggestKeywords(['COLUMN']);
+     if (parser.isHive() && !$2) {
+       parser.suggestKeywords(['COLUMN']);
      }
-     suggestColumns();
+     parser.suggestColumns();
    }
  | AnyChange OptionalHiveColumn ColumnIdentifier ColumnSpecification_EDIT OptionalHiveFirstOrAfter OptionalHiveCascadeOrRestrict
  | AnyChange OptionalHiveColumn ColumnIdentifier ColumnSpecification OptionalHiveFirstOrAfter OptionalHiveCascadeOrRestrict 'CURSOR'
    {
-     if (isHive() && !$5 && !$6) {
+     if (parser.isHive() && !$5 && !$6) {
        if ($4.suggestKeywords) {
-         var keywords = createWeightedKeywords($4.suggestKeywords, 3);
+         var keywords = parser.createWeightedKeywords($4.suggestKeywords, 3);
          keywords = keywords.concat([{ value: 'AFTER', weight: 2 }, { value: 'FIRST', weight: 2 }, { value: 'CASCADE', weight: 1 }, { value: 'RESTRICT', weight: 1 }]);
-         suggestKeywords(keywords);
+         parser.suggestKeywords(keywords);
        } else {
-         suggestKeywords([{ value: 'AFTER', weight: 2 }, { value: 'FIRST', weight: 2 }, { value: 'CASCADE', weight: 1 }, { value: 'RESTRICT', weight: 1 }]);
+         parser.suggestKeywords([{ value: 'AFTER', weight: 2 }, { value: 'FIRST', weight: 2 }, { value: 'CASCADE', weight: 1 }, { value: 'RESTRICT', weight: 1 }]);
        }
-     } else if (isHive() && $5 && !$6) {
-       suggestKeywords(['CASCADE', 'RESTRICT']);
+     } else if (parser.isHive() && $5 && !$6) {
+       parser.suggestKeywords(['CASCADE', 'RESTRICT']);
      }
    }
  | AnyChange OptionalHiveColumn ColumnIdentifier ColumnSpecification OptionalHiveFirstOrAfter_EDIT OptionalHiveCascadeOrRestrict
  | HiveEnableOrDisable 'CURSOR'
    {
-     suggestKeywords(['NO_DROP', 'OFFLINE']);
+     parser.suggestKeywords(['NO_DROP', 'OFFLINE']);
    }
  | 'SET' AnyFileFormat 'CURSOR'
    {
-     suggestFileFormats();
+     parser.suggestFileFormats();
    }
  | 'SET' HdfsLocation_EDIT
  | 'SET' CachedIn_EDIT
  | 'SET' '<hive>SERDE' QuotedValue OptionalWithSerdeproperties 'CURSOR'
    {
      if (!$4) {
-       suggestKeywords(['WITH SERDEPROPERTIES']);
+       parser.suggestKeywords(['WITH SERDEPROPERTIES']);
      }
    }
  | 'SET' '<hive>SERDE' QuotedValue WithSerdeproperties_EDIT
@@ -329,8 +329,8 @@ AddReplaceColumns_EDIT
  : AddOrReplace AnyColumns ParenthesizedColumnSpecificationList_EDIT OptionalHiveCascadeOrRestrict
  | AddOrReplace AnyColumns ParenthesizedColumnSpecificationList OptionalHiveCascadeOrRestrict 'CURSOR'
    {
-     if (isHive() && !$4) {
-       suggestKeywords(['CASCADE', 'RESTRICT']);
+     if (parser.isHive() && !$4) {
+       parser.suggestKeywords(['CASCADE', 'RESTRICT']);
      }
    }
  ;
@@ -347,20 +347,20 @@ HiveExchange
 HiveExchange_EDIT
  : '<hive>EXCHANGE' 'CURSOR'
    {
-     suggestKeywords(['PARTITION']);
+     parser.suggestKeywords(['PARTITION']);
    }
  | '<hive>EXCHANGE' ExchangePartitionSpec 'CURSOR'
    {
-     suggestKeywords(['WITH TABLE']);
+     parser.suggestKeywords(['WITH TABLE']);
    }
  | '<hive>EXCHANGE' ExchangePartitionSpec 'WITH' 'CURSOR'
    {
-     suggestKeywords(['TABLE']);
+     parser.suggestKeywords(['TABLE']);
    }
  | '<hive>EXCHANGE' ExchangePartitionSpec 'WITH' '<hive>TABLE' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<hive>EXCHANGE' ExchangePartitionSpec 'WITH' '<hive>TABLE' RegularOrBackTickedSchemaQualifiedName_EDIT
  | '<hive>EXCHANGE' ExchangePartitionSpec_EDIT
@@ -395,43 +395,43 @@ DropOperations
 DropOperations
  : 'DROP' 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords([{ value: 'PARTITION', weight: 1}, { value: 'IF EXISTS', weight: 2 }]);
-     } else if (isImpala()) {
-       suggestKeywords(['COLUMN', 'PARTITION']);
-       suggestColumns();
+     if (parser.isHive()) {
+       parser.suggestKeywords([{ value: 'PARTITION', weight: 1}, { value: 'IF EXISTS', weight: 2 }]);
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords(['COLUMN', 'PARTITION']);
+       parser.suggestColumns();
      }
    }
  | 'DROP' OneOrMorePartitionSpecs_EDIT OptionalHivePurge
  | 'DROP' OneOrMorePartitionSpecs OptionalHivePurge 'CURSOR'
    {
-     if (isHive() && !$3) {
-       suggestKeywords(['PURGE']);
+     if (parser.isHive() && !$3) {
+       parser.suggestKeywords(['PURGE']);
      }
    }
  | 'DROP' 'IF' 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['EXISTS']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['EXISTS']);
      }
    }
  | 'DROP' 'IF' 'EXISTS' 'CURSOR'
     {
-      if (isHive()) {
-        suggestKeywords(['PARTITION']);
+      if (parser.isHive()) {
+        parser.suggestKeywords(['PARTITION']);
       }
     }
  | 'DROP' 'IF' 'EXISTS' OneOrMorePartitionSpecs_EDIT OptionalHivePurge
  | 'DROP' 'IF' 'EXISTS' OneOrMorePartitionSpecs OptionalHivePurge 'CURSOR'
    {
-     if (isHive() && !$3) {
-       suggestKeywords(['PURGE']);
+     if (parser.isHive() && !$3) {
+       parser.suggestKeywords(['PURGE']);
      }
    }
  | 'DROP' ColumnIdentifier_EDIT
  | 'DROP' '<impala>COLUMN' 'CURSOR'
    {
-     suggestColumns();
+     parser.suggestColumns();
    }
  | 'DROP' '<impala>COLUMN' ColumnIdentifier_EDIT
  ;
@@ -439,7 +439,7 @@ DropOperations
 AlterTableLeftSide
  : 'ALTER' AnyTable SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
@@ -452,8 +452,8 @@ AlterTableLeftSide_EDIT
    }
  | 'ALTER' AnyTable 'CURSOR'
    {
-     suggestTables({ onlyTables: true });
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables({ onlyTables: true });
+     parser.suggestDatabases({ appendDot: true });
    }
  ;
 
@@ -495,7 +495,7 @@ HiveAfterOrFirst
 OptionalHiveFirstOrAfter_EDIT
  : HiveAfterOrFirst 'CURSOR'
    {
-     suggestColumns();
+     parser.suggestColumns();
    }
  | HiveAfterOrFirst ColumnIdentifier_EDIT
  ;
@@ -539,20 +539,20 @@ OneOrMorePartitionSpecs_EDIT
  : PartitionSpec_EDIT
  | OneOrMorePartitionSpecs ',' AnyCursor
    {
-     if (isHive()) {
-       suggestKeywords(['PARTITION']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['PARTITION']);
      }
    }
  | OneOrMorePartitionSpecs ',' AnyCursor ',' OneOrMorePartitionSpecs
    {
-     if (isHive()) {
-       suggestKeywords(['PARTITION']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['PARTITION']);
      }
    }
  | AnyCursor ',' OneOrMorePartitionSpecs
    {
-     if (isHive()) {
-       suggestKeywords(['PARTITION']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['PARTITION']);
      }
    }
  | OneOrMorePartitionSpecs ',' PartitionSpec_EDIT
@@ -623,12 +623,12 @@ SkewedLocation
 SkewedLocation_EDIT
  : AnyCursor
    {
-     suggestColumns();
+     parser.suggestColumns();
    }
  | ColumnReference_EDIT
  | AnyCursor '=' QuotedValue
    {
-     suggestColumns();
+     parser.suggestColumns();
    }
  | ColumnReference_EDIT '=' QuotedValue
  | ColumnReferences '=' QuotedValue
@@ -642,11 +642,11 @@ OptionalStoredAsDirectories
 OptionalStoredAsDirectories_EDIT
  : '<hive>STORED' 'CURSOR'
    {
-     suggestKeywords(['AS DIRECTORIES']);
+     parser.suggestKeywords(['AS DIRECTORIES']);
    }
  | '<hive>STORED' '<hive>AS' 'CURSOR'
    {
-     suggestKeywords(['DIRECTORIES']);
+     parser.suggestKeywords(['DIRECTORIES']);
    }
  ;
 
@@ -667,32 +667,32 @@ AlterView_EDIT
  : AlterViewLeftSide_EDIT
  | AlterViewLeftSide 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['AS', 'SET TBLPROPERTIES']);
-     } else if (isImpala()) {
-       suggestKeywords(['AS', 'RENAME TO']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['AS', 'SET TBLPROPERTIES']);
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords(['AS', 'RENAME TO']);
      } else {
-       suggestKeywords(['AS']);
+       parser.suggestKeywords(['AS']);
      }
    }
  | AlterViewLeftSide 'SET' 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['TBLPROPERTIES']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['TBLPROPERTIES']);
      }
    }
  | AlterViewLeftSide AnyAs 'CURSOR'
    {
-     suggestKeywords(['SELECT']);
+     parser.suggestKeywords(['SELECT']);
    }
  | AlterViewLeftSide AnyAs QuerySpecification_EDIT
  | AlterViewLeftSide '<impala>RENAME' 'CURSOR'
    {
-     suggestKeywords(['TO']);
+     parser.suggestKeywords(['TO']);
    }
  | AlterViewLeftSide '<impala>RENAME' 'TO' 'CURSOR'
    {
-     suggestDatabases({ appendDot: true });
+     parser.suggestDatabases({ appendDot: true });
    }
  ;
 
@@ -700,7 +700,7 @@ AlterView_EDIT
 AlterViewLeftSide
  : 'ALTER' AnyView SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
@@ -713,31 +713,31 @@ AlterViewLeftSide_EDIT
    }
  | 'ALTER' AnyView 'CURSOR'
    {
-     suggestTables({ onlyViews: true });
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables({ onlyViews: true });
+     parser.suggestDatabases({ appendDot: true });
    }
  ;
 
 Msck
  : '<hive>MSCK' '<hive>REPAIR' '<hive>TABLE' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
 Msck_EDIT
  : '<hive>MSCK' 'CURSOR'
    {
-     suggestKeywords(['REPAIR TABLE']);
+     parser.suggestKeywords(['REPAIR TABLE']);
    }
  | '<hive>MSCK' '<hive>REPAIR' 'CURSOR'
    {
-     suggestKeywords(['TABLE']);
+     parser.suggestKeywords(['TABLE']);
    }
  | '<hive>MSCK' '<hive>REPAIR' '<hive>TABLE' 'CURSOR'
    {
-     suggestTables({ onlyTables: true });
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables({ onlyTables: true });
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<hive>MSCK' '<hive>REPAIR' '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT
    {
@@ -754,6 +754,6 @@ ReloadFunction
 ReloadFunction_EDIT
  : '<hive>RELOAD' 'CURSOR'
    {
-     suggestKeywords(['FUNCTION']);
+     parser.suggestKeywords(['FUNCTION']);
    }
  ;

+ 48 - 48
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_analyze.jison

@@ -31,19 +31,19 @@ DataDefinition_EDIT
 AnalyzeStatement
  : '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec '<hive>COMPUTE' '<hive>STATISTICS' OptionalForColumns OptionalCacheMetadata OptionalNoscan
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
 AnalyzeStatement_EDIT
  : '<hive>ANALYZE' 'CURSOR'
    {
-     suggestKeywords(['TABLE']);
+     parser.suggestKeywords(['TABLE']);
    }
  | '<hive>ANALYZE' '<hive>TABLE' 'CURSOR'
    {
-     suggestTables({ onlyTables: true });
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables({ onlyTables: true });
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec
    {
@@ -53,46 +53,46 @@ AnalyzeStatement_EDIT
    }
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
      if (!$4) {
-       suggestKeywords([{ value: 'PARTITION', weight: 2 }, { value: 'COMPUTE STATISTICS', weight: 1 }]);
+       parser.suggestKeywords([{ value: 'PARTITION', weight: 2 }, { value: 'COMPUTE STATISTICS', weight: 1 }]);
      } else {
-       suggestKeywords(['COMPUTE STATISTICS']);
+       parser.suggestKeywords(['COMPUTE STATISTICS']);
      }
    }
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec '<hive>COMPUTE' 'CURSOR'
    {
-     addTablePrimary($3);
-     suggestKeywords(['STATISTICS']);
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(['STATISTICS']);
    }
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec '<hive>COMPUTE' '<hive>STATISTICS' 'CURSOR' OptionalForColumns OptionalCacheMetadata OptionalNoscan
    {
-     addTablePrimary($3);
-     suggestKeywords(getKeywordsForOptionalsLR([$8, $9, $10], [{ value: 'FOR COLUMNS', weight: 3 }, { value: 'CACHE METADATA', weight: 2 }, { value: 'NOSCAN', weight: 1 }]));
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(parser.getKeywordsForOptionalsLR([$8, $9, $10], [{ value: 'FOR COLUMNS', weight: 3 }, { value: 'CACHE METADATA', weight: 2 }, { value: 'NOSCAN', weight: 1 }]));
    }
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec '<hive>COMPUTE' '<hive>STATISTICS' ForColumns 'CURSOR' OptionalCacheMetadata OptionalNoscan
    {
-     addTablePrimary($3);
-     suggestKeywords(getKeywordsForOptionalsLR([$9, $10], [{ value: 'CACHE METADATA', weight: 2 }, { value: 'NOSCAN', weight: 1 }]));
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(parser.getKeywordsForOptionalsLR([$9, $10], [{ value: 'CACHE METADATA', weight: 2 }, { value: 'NOSCAN', weight: 1 }]));
    }
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec '<hive>COMPUTE' '<hive>STATISTICS' OptionalForColumns CacheMetadata 'CURSOR' OptionalNoscan
    {
-     addTablePrimary($3);
-     suggestKeywords(getKeywordsForOptionalsLR([$10], [{ value: 'NOSCAN', weight: 1 }]));
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(parser.getKeywordsForOptionalsLR([$10], [{ value: 'NOSCAN', weight: 1 }]));
    }
  | '<hive>ANALYZE' 'CURSOR' SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     suggestKeywords(['TABLE']);
-     addTablePrimary($3);
+     parser.suggestKeywords(['TABLE']);
+     parser.addTablePrimary($3);
    }
  | '<hive>ANALYZE' 'CURSOR' SchemaQualifiedTableIdentifier OptionalPartitionSpec '<hive>COMPUTE' '<hive>STATISTICS' OptionalForColumns OptionalCacheMetadata OptionalNoscan
    {
-     suggestKeywords(['TABLE']);
-     addTablePrimary($3);
+     parser.suggestKeywords(['TABLE']);
+     parser.addTablePrimary($3);
    }
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec '<hive>COMPUTE' '<hive>STATISTICS' OptionalForColumns OptionalCacheMetadata OptionalNoscan
  | '<hive>ANALYZE' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT '<hive>COMPUTE' '<hive>STATISTICS' OptionalForColumns OptionalCacheMetadata OptionalNoscan
@@ -112,7 +112,7 @@ ForColumns
 ForColumns_EDIT
  : '<hive>FOR' 'CURSOR'
    {
-     suggestKeywords(['COLUMNS']);
+     parser.suggestKeywords(['COLUMNS']);
    }
  ;
 
@@ -128,7 +128,7 @@ CacheMetadata
 CacheMetadata_EDIT
  : '<hive>CACHE' 'CURSOR'
    {
-     suggestKeywords(['METADATA']);
+     parser.suggestKeywords(['METADATA']);
    }
  ;
 
@@ -140,15 +140,15 @@ OptionalNoscan
 RefreshStatement
  : '<impala>REFRESH' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($2);
+     parser.addTablePrimary($2);
    }
  ;
 
 RefreshStatement_EDIT
  : '<impala>REFRESH' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<impala>REFRESH' SchemaQualifiedTableIdentifier_EDIT
  ;
@@ -157,84 +157,84 @@ InvalidateStatement
  : '<impala>INVALIDATE' '<impala>METADATA'
  | '<impala>INVALIDATE' '<impala>METADATA' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
 InvalidateStatement_EDIT
  : '<impala>INVALIDATE' 'CURSOR'
    {
-     suggestKeywords(['METADATA']);
+     parser.suggestKeywords(['METADATA']);
    }
  | '<impala>INVALIDATE' '<impala>METADATA' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<impala>INVALIDATE' '<impala>METADATA' SchemaQualifiedTableIdentifier_EDIT
  | '<impala>INVALIDATE' 'CURSOR' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($3);
-     suggestKeywords(['METADATA']);
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(['METADATA']);
    }
  ;
 
 ComputeStatsStatement
  : '<impala>COMPUTE' '<impala>STATS' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | '<impala>COMPUTE' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
 ComputeStatsStatement_EDIT
  : '<impala>COMPUTE' 'CURSOR'
    {
-     suggestKeywords(['STATS', 'INCREMENTAL STATS']);
+     parser.suggestKeywords(['STATS', 'INCREMENTAL STATS']);
    }
  | '<impala>COMPUTE' '<impala>STATS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<impala>COMPUTE' '<impala>STATS' SchemaQualifiedTableIdentifier_EDIT
  | '<impala>COMPUTE' 'CURSOR' SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($3);
-     suggestKeywords(['STATS', 'INCREMENTAL STATS']);
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(['STATS', 'INCREMENTAL STATS']);
    }
  | '<impala>COMPUTE' 'CURSOR' '<impala>STATS' SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($4);
-     suggestKeywords(['INCREMENTAL']);
+     parser.addTablePrimary($4);
+     parser.suggestKeywords(['INCREMENTAL']);
    }
  | '<impala>COMPUTE' '<impala>INCREMENTAL' 'CURSOR'
    {
-     suggestKeywords(['STATS']);
+     parser.suggestKeywords(['STATS']);
    }
  | '<impala>COMPUTE' '<impala>INCREMENTAL' 'CURSOR' SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($4);
-     suggestKeywords(['STATS']);
+     parser.addTablePrimary($4);
+     parser.suggestKeywords(['STATS']);
    }
  | '<impala>COMPUTE' '<impala>INCREMENTAL' '<impala>STATS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<impala>COMPUTE' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec
  | '<impala>COMPUTE' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier 'CURSOR' OptionalPartitionSpec
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (!$6) {
-       suggestKeywords(['PARTITION']);
+       parser.suggestKeywords(['PARTITION']);
      }
    }
  | '<impala>COMPUTE' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;

文件差異過大導致無法顯示
+ 172 - 172
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_create.jison


+ 70 - 70
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_drop.jison

@@ -53,12 +53,12 @@ DropStatement_EDIT
  | TruncateTableStatement_EDIT
  | 'DROP' 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['DATABASE', 'FUNCTION', 'INDEX', 'ROLE', 'SCHEMA', 'TABLE', 'TEMPORARY FUNCTION', 'TEMPORARY MACRO', 'VIEW']);
-     } else if (isImpala()) {
-       suggestKeywords(['AGGREGATE FUNCTION', 'DATABASE', 'FUNCTION', 'INCREMENTAL STATS', 'ROLE', 'SCHEMA', 'STATS', 'TABLE', 'VIEW']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['DATABASE', 'FUNCTION', 'INDEX', 'ROLE', 'SCHEMA', 'TABLE', 'TEMPORARY FUNCTION', 'TEMPORARY MACRO', 'VIEW']);
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords(['AGGREGATE FUNCTION', 'DATABASE', 'FUNCTION', 'INCREMENTAL STATS', 'ROLE', 'SCHEMA', 'STATS', 'TABLE', 'VIEW']);
      } else {
-       suggestKeywords(['ROLE', 'SCHEMA', 'TABLE', 'VIEW']);
+       parser.suggestKeywords(['ROLE', 'SCHEMA', 'TABLE', 'VIEW']);
      }
    }
  ;
@@ -73,21 +73,21 @@ DropDatabaseStatement_EDIT
  | 'DROP' DatabaseOrSchema OptionalIfExists 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
-     suggestDatabases();
+     parser.suggestDatabases();
    }
  | 'DROP' DatabaseOrSchema OptionalIfExists RegularOrBacktickedIdentifier 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['CASCADE', 'RESTRICT']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['CASCADE', 'RESTRICT']);
      }
    }
  | 'DROP' DatabaseOrSchema OptionalIfExists_EDIT RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
  | 'DROP' DatabaseOrSchema OptionalIfExists 'CURSOR' RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
    {
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
    }
  ;
@@ -112,37 +112,37 @@ DropImpalaFunction_EDIT
  : 'DROP' '<impala>FUNCTION' OptionalIfExists 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
-     suggestDatabases({ appendDot: true });
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'DROP' '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfExists 'CURSOR'
    {
      if (!$4) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
-     suggestDatabases({ appendDot: true });
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'DROP' '<impala>FUNCTION' OptionalIfExists 'CURSOR' SchemaQualifiedIdentifier ParenthesizedImpalaArgumentList
    {
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
    }
  | 'DROP' '<impala>FUNCTION' OptionalIfExists_EDIT
  | 'DROP' 'CURSOR' '<impala>FUNCTION' OptionalIfExists SchemaQualifiedIdentifier ParenthesizedImpalaArgumentList
    {
-     suggestKeywords(['AGGREGATE']);
+     parser.suggestKeywords(['AGGREGATE']);
    }
  | 'DROP' '<impala>FUNCTION' OptionalIfExists SchemaQualifiedIdentifier ParenthesizedImpalaArgumentList_EDIT
  | 'DROP' '<impala>AGGREGATE' 'CURSOR'
    {
-     suggestKeywords(['FUNCTION']);
+     parser.suggestKeywords(['FUNCTION']);
    }
  | 'DROP' '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfExists 'CURSOR' SchemaQualifiedIdentifier ParenthesizedImpalaArgumentList
    {
      if (!$4) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
    }
  | 'DROP' '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfExists_EDIT
@@ -159,13 +159,13 @@ DropHiveFunction_EDIT
  : 'DROP' '<hive>FUNCTION' OptionalIfExists 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
    }
  | 'DROP' '<hive>FUNCTION' OptionalIfExists 'CURSOR' SchemaQualifiedIdentifier
    {
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
    }
  | 'DROP' '<hive>FUNCTION' OptionalIfExists_EDIT
@@ -180,57 +180,57 @@ DropRoleStatement
 DropStatsStatement
  : 'DROP' '<impala>STATS' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | 'DROP' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier PartitionSpec
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
 DropStatsStatement_EDIT
  : 'DROP' '<impala>STATS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'DROP' '<impala>STATS' SchemaQualifiedTableIdentifier_EDIT
  | 'DROP' 'CURSOR' '<impala>STATS' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($4);
-     suggestKeywords(['INCREMENTAL']);
+     parser.addTablePrimary($4);
+     parser.suggestKeywords(['INCREMENTAL']);
    }
  | 'DROP' 'CURSOR' '<impala>STATS' SchemaQualifiedTableIdentifier PartitionSpec
    {
-     addTablePrimary($4);
-     suggestKeywords(['INCREMENTAL']);
+     parser.addTablePrimary($4);
+     parser.suggestKeywords(['INCREMENTAL']);
    }
  | 'DROP' '<impala>INCREMENTAL' 'CURSOR'
    {
-     suggestKeywords(['STATS']);
+     parser.suggestKeywords(['STATS']);
    }
  | 'DROP' '<impala>INCREMENTAL' '<impala>STATS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'DROP' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier_EDIT
  | 'DROP' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier_EDIT PartitionSpec
  | 'DROP' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier 'CURSOR'
    {
-     addTablePrimary($4);
-     suggestKeywords(['PARTITION']);
+     parser.addTablePrimary($4);
+     parser.suggestKeywords(['PARTITION']);
    }
  | 'DROP' '<impala>INCREMENTAL' '<impala>STATS' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
 DropTableStatement
  : 'DROP' AnyTable OptionalIfExists SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
@@ -239,10 +239,10 @@ DropTableStatement_EDIT
  | 'DROP' AnyTable OptionalIfExists 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
-     suggestTables({ onlyTables: true });
-     suggestDatabases({
+     parser.suggestTables({ onlyTables: true });
+     parser.suggestDatabases({
        appendDot: true
      });
    }
@@ -255,9 +255,9 @@ DropTableStatement_EDIT
  | 'DROP' AnyTable OptionalIfExists_EDIT SchemaQualifiedTableIdentifier
  | 'DROP' AnyTable OptionalIfExists SchemaQualifiedTableIdentifier 'CURSOR'
    {
-     addTablePrimary($4);
-     if (isHive()) {
-       suggestKeywords(['PURGE']);
+     parser.addTablePrimary($4);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['PURGE']);
      }
    }
  ;
@@ -265,24 +265,24 @@ DropTableStatement_EDIT
 DropIndexStatement
  : 'DROP' '<hive>INDEX' OptionalIfExists RegularOrBacktickedIdentifier 'ON' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($6);
+     parser.addTablePrimary($6);
    }
  ;
 
 DropIndexStatement_EDIT
  : 'DROP' '<hive>INDEX' OptionalIfExists 'CURSOR'
    {
-     suggestKeywords(['IF EXISTS']);
+     parser.suggestKeywords(['IF EXISTS']);
    }
  | 'DROP' '<hive>INDEX' OptionalIfExists_EDIT
  | 'DROP' '<hive>INDEX' OptionalIfExists RegularOrBacktickedIdentifier 'CURSOR'
    {
-     suggestKeywords(['ON']);
+     parser.suggestKeywords(['ON']);
    }
  | 'DROP' '<hive>INDEX' OptionalIfExists RegularOrBacktickedIdentifier 'ON' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'DROP' '<hive>INDEX' OptionalIfExists RegularOrBacktickedIdentifier 'ON' SchemaQualifiedTableIdentifier_EDIT
  ;
@@ -294,12 +294,12 @@ DropMacroStatement
 DropMacroStatement_EDIT
  : 'DROP' '<hive>TEMPORARY' 'CURSOR'
    {
-     suggestKeywords(['MACRO']);
+     parser.suggestKeywords(['MACRO']);
    }
  | 'DROP' '<hive>TEMPORARY' '<hive>MACRO' OptionalIfExists 'CURSOR'
    {
      if (!$4) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
    }
  | 'DROP' '<hive>TEMPORARY' '<hive>MACRO' OptionalIfExists_EDIT
@@ -308,7 +308,7 @@ DropMacroStatement_EDIT
 DropViewStatement
  : 'DROP' AnyView OptionalIfExists SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
@@ -316,22 +316,22 @@ DropViewStatement_EDIT
  : 'DROP' AnyView OptionalIfExists 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
-     suggestTables({ onlyViews: true });
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables({ onlyViews: true });
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'DROP' AnyView OptionalIfExists 'CURSOR' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($5);
+     parser.addTablePrimary($5);
      if (!$3) {
-       suggestKeywords(['IF EXISTS']);
+       parser.suggestKeywords(['IF EXISTS']);
      }
    }
  | 'DROP' AnyView OptionalIfExists_EDIT
  | 'DROP' AnyView OptionalIfExists_EDIT SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  | 'DROP' AnyView OptionalIfExists SchemaQualifiedTableIdentifier_EDIT
    {
@@ -344,61 +344,61 @@ DropViewStatement_EDIT
 TruncateTableStatement
  : 'TRUNCATE' AnyTable SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
 TruncateTableStatement_EDIT
  : 'TRUNCATE' 'CURSOR'
    {
-     suggestKeywords(['TABLE']);
+     parser.suggestKeywords(['TABLE']);
    }
  | 'TRUNCATE' AnyTable 'CURSOR' OptionalPartitionSpec
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'TRUNCATE' AnyTable SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec
  | 'TRUNCATE' AnyTable SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
    {
-     addTablePrimary($3);
-     if (isHive() && !$4) {
-       suggestKeywords(['PARTITION']);
+     parser.addTablePrimary($3);
+     if (parser.isHive() && !$4) {
+       parser.suggestKeywords(['PARTITION']);
      }
    }
  | 'TRUNCATE' AnyTable SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
 DeleteStatement
  : '<hive>DELETE' 'FROM' SchemaQualifiedTableIdentifier OptionalWhereClause
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
 DeleteStatement_EDIT
  : '<hive>DELETE' 'CURSOR'
    {
-     suggestKeywords(['FROM']);
+     parser.suggestKeywords(['FROM']);
    }
  | '<hive>DELETE' 'FROM' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<hive>DELETE' 'FROM' SchemaQualifiedTableIdentifier 'CURSOR' OptionalWhereClause
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
      if (!$5) {
-       suggestKeywords(['WHERE']);
+       parser.suggestKeywords(['WHERE']);
      }
    }
  | '<hive>DELETE' 'FROM' SchemaQualifiedTableIdentifier_EDIT OptionalWhereClause
  | '<hive>DELETE' 'FROM' SchemaQualifiedTableIdentifier WhereClause_EDIT
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;

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

@@ -22,12 +22,12 @@ SqlStatements
 SqlStatement_EDIT
  : AnyCursor error
    {
-     if (isHive()) {
-       suggestDdlAndDmlKeywords(['EXPLAIN', 'FROM']);
-     } else if (isImpala()) {
-       suggestDdlAndDmlKeywords(['EXPLAIN']);
+     if (parser.isHive()) {
+       parser.suggestDdlAndDmlKeywords(['EXPLAIN', 'FROM']);
+     } else if (parser.isImpala()) {
+       parser.suggestDdlAndDmlKeywords(['EXPLAIN']);
      } else {
-       suggestDdlAndDmlKeywords();
+       parser.suggestDdlAndDmlKeywords();
      }
    }
  ;
@@ -40,7 +40,7 @@ SelectStatement
 SelectStatement_EDIT
  : 'SELECT' OptionalAllOrDistinct SelectList_ERROR_EDIT TableExpression
    {
-     selectListNoTableSuggest($3, $2);
+     parser.selectListNoTableSuggest($3, $2);
    }
  | 'SELECT' OptionalAllOrDistinct SelectList_ERROR TableExpression_EDIT
  ;
@@ -90,24 +90,24 @@ LateralView
 JoinType_EDIT
  : 'FULL' 'CURSOR' error
    {
-     suggestKeywords(['JOIN', 'OUTER JOIN']);
+     parser.suggestKeywords(['JOIN', 'OUTER JOIN']);
    }
  | 'LEFT' 'CURSOR' error
    {
-     if (isHive()) {
-       suggestKeywords(['JOIN', 'OUTER JOIN', 'SEMI JOIN']);
-     } else if (isImpala()) {
-       suggestKeywords(['ANTI JOIN', 'JOIN', 'OUTER JOIN', 'SEMI JOIN']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['JOIN', 'OUTER JOIN', 'SEMI JOIN']);
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords(['ANTI JOIN', 'JOIN', 'OUTER JOIN', 'SEMI JOIN']);
      } else {
-       suggestKeywords(['JOIN', 'OUTER JOIN']);
+       parser.suggestKeywords(['JOIN', 'OUTER JOIN']);
      }
    }
  | 'RIGHT' 'CURSOR' error
    {
-     if (isImpala()) {
-       suggestKeywords(['ANTI JOIN', 'JOIN', 'OUTER JOIN', 'SEMI JOIN']);
+     if (parser.isImpala()) {
+       parser.suggestKeywords(['ANTI JOIN', 'JOIN', 'OUTER JOIN', 'SEMI JOIN']);
      } else {
-       suggestKeywords(['JOIN', 'OUTER JOIN']);
+       parser.suggestKeywords(['JOIN', 'OUTER JOIN']);
      }
    }
  ;
@@ -116,42 +116,42 @@ OptionalSelectConditions_EDIT
  : WhereClause error 'CURSOR' OptionalGroupByClause OptionalHavingClause OptionalWindowClause OptionalOrderByClause OptionalClusterOrDistributeBy OptionalLimitClause OptionalOffsetClause
    {
      $$ = {
-       suggestKeywords: getKeywordsForOptionalsLR([$4, $5, $6, $7, $8, $9, $10], [{ value: 'GROUP BY', weight: 8 }, { value: 'HAVING', weight: 7 }, { value: 'WINDOW', weight: 6 }, { value: 'ORDER BY', weight: 5 }, [{ value: 'CLUSTER BY', weight: 4 }, { value: 'DISTRIBUTE BY', weight: 4 }, { value: 'SORT BY', weight: 4 }], { value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [true, true, isHive(), true, isHive(), true, isImpala()]),
+       suggestKeywords: parser.getKeywordsForOptionalsLR([$4, $5, $6, $7, $8, $9, $10], [{ value: 'GROUP BY', weight: 8 }, { value: 'HAVING', weight: 7 }, { value: 'WINDOW', weight: 6 }, { value: 'ORDER BY', weight: 5 }, [{ value: 'CLUSTER BY', weight: 4 }, { value: 'DISTRIBUTE BY', weight: 4 }, { value: 'SORT BY', weight: 4 }], { value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [true, true, parser.isHive(), true, parser.isHive(), true, parser.isImpala()]),
        cursorAtEnd: !$4 && !$5 && !$6 && !$7 && !$8 && !$9 && !$10
      };
    }
  | OptionalWhereClause OptionalGroupByClause HavingClause error 'CURSOR' OptionalWindowClause OptionalOrderByClause OptionalClusterOrDistributeBy OptionalLimitClause OptionalOffsetClause
    {
      $$ = {
-       suggestKeywords: getKeywordsForOptionalsLR([$6, $7, $8, $9, $10], [{ value: 'WINDOW', weight: 6 }, { value: 'ORDER BY', weight: 5 }, [{ value: 'CLUSTER BY', weight: 4 }, { value: 'DISTRIBUTE BY', weight: 4 }, { value: 'SORT BY', weight: 4 }], { value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [isHive(), true, isHive(), true, isImpala()]),
+       suggestKeywords: parser.getKeywordsForOptionalsLR([$6, $7, $8, $9, $10], [{ value: 'WINDOW', weight: 6 }, { value: 'ORDER BY', weight: 5 }, [{ value: 'CLUSTER BY', weight: 4 }, { value: 'DISTRIBUTE BY', weight: 4 }, { value: 'SORT BY', weight: 4 }], { value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [parser.isHive(), true, parser.isHive(), true, parser.isImpala()]),
        cursorAtEnd: !$6 && !$7 && !$8 && !$9 && !$10
      }
    }
  | OptionalWhereClause OptionalGroupByClause OptionalHavingClause WindowClause error 'CURSOR' OptionalOrderByClause OptionalClusterOrDistributeBy OptionalLimitClause OptionalOffsetClause
    {
      $$ = {
-       suggestKeywords: getKeywordsForOptionalsLR([$7, $8, $9, $10], [{ value: 'ORDER BY', weight: 5 }, [{ value: 'CLUSTER BY', weight: 4 }, { value: 'DISTRIBUTE BY', weight: 4 }, { value: 'SORT BY', weight: 4 }], { value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [true, isHive(), true, isImpala()]),
+       suggestKeywords: parser.getKeywordsForOptionalsLR([$7, $8, $9, $10], [{ value: 'ORDER BY', weight: 5 }, [{ value: 'CLUSTER BY', weight: 4 }, { value: 'DISTRIBUTE BY', weight: 4 }, { value: 'SORT BY', weight: 4 }], { value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [true, parser.isHive(), true, parser.isImpala()]),
        cursorAtEnd: !$7 && !$8 && !$9 && !$10
      }
    }
  | OptionalWhereClause OptionalGroupByClause OptionalHavingClause OptionalWindowClause OrderByClause error 'CURSOR' OptionalClusterOrDistributeBy OptionalLimitClause OptionalOffsetClause
    {
      $$ = {
-       suggestKeywords: getKeywordsForOptionalsLR([$8, $9, $10], [[{ value: 'CLUSTER BY', weight: 4 }, { value: 'DISTRIBUTE BY', weight: 4 }, { value: 'SORT BY', weight: 4 }], { value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [isHive(), true, isImpala()]),
+       suggestKeywords: parser.getKeywordsForOptionalsLR([$8, $9, $10], [[{ value: 'CLUSTER BY', weight: 4 }, { value: 'DISTRIBUTE BY', weight: 4 }, { value: 'SORT BY', weight: 4 }], { value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [parser.isHive(), true, parser.isImpala()]),
        cursorAtEnd: !$8 && !$9 && !$10
      }
    }
  | OptionalWhereClause OptionalGroupByClause OptionalHavingClause OptionalWindowClause OptionalOrderByClause ClusterOrDistributeBy error 'CURSOR' OptionalLimitClause OptionalOffsetClause
    {
      $$ = {
-       suggestKeywords: getKeywordsForOptionalsLR([$9, $10], [{ value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [true, isImpala()]),
+       suggestKeywords: parser.getKeywordsForOptionalsLR([$9, $10], [{ value: 'LIMIT', weight: 3 }, { value: 'OFFSET', weight: 2 }], [true, parser.isImpala()]),
        cursorAtEnd: !$9 && !$10
      }
    }
  | OptionalWhereClause OptionalGroupByClause OptionalHavingClause OptionalWindowClause OptionalOrderByClause OptionalClusterOrDistributeBy LimitClause error 'CURSOR' OptionalOffsetClause
    {
      $$ = {
-       suggestKeywords: getKeywordsForOptionalsLR([$10], [{ value: 'OFFSET', weight: 2 }], [isImpala()]),
+       suggestKeywords: parser.getKeywordsForOptionalsLR([$10], [{ value: 'OFFSET', weight: 2 }], [parser.isImpala()]),
        cursorAtEnd: !$10
      }
    }

+ 73 - 73
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_grant.jison

@@ -36,99 +36,99 @@ GrantStatement
 GrantStatement_EDIT
  : '<hive>GRANT' 'CURSOR'
    {
-     suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'ROLE', 'SELECT', 'UPDATE']);
+     parser.suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'ROLE', 'SELECT', 'UPDATE']);
    }
  | '<hive>GRANT' HivePrivilegeTypeList_EDIT OptionalOnSpecification
  | '<hive>GRANT' HivePrivilegeTypeList OnSpecification_EDIT
  | '<hive>GRANT' HivePrivilegeTypeList OptionalOnSpecification 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['ON', 'TO']);
+       parser.suggestKeywords(['ON', 'TO']);
      } else {
-       suggestKeywords(['TO']);
+       parser.suggestKeywords(['TO']);
      }
    }
  | '<hive>GRANT' HivePrivilegeTypeList OptionalOnSpecification 'TO' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>GRANT' HivePrivilegeTypeList OptionalOnSpecification 'TO' PrincipalSpecificationList_EDIT
  | '<hive>GRANT' HivePrivilegeTypeList OptionalOnSpecification 'TO' PrincipalSpecificationList OptionalWithGrantOption 'CURSOR'
    {
      if (!$6) {
-       suggestKeywords(['WITH GRANT OPTION']);
+       parser.suggestKeywords(['WITH GRANT OPTION']);
      }
    }
  | '<hive>GRANT' HivePrivilegeTypeList OptionalOnSpecification 'TO' PrincipalSpecificationList WithGrantOption_EDIT
  | '<hive>GRANT' UserOrRoleList 'CURSOR'
    {
-     suggestKeywords(['TO']);
+     parser.suggestKeywords(['TO']);
    }
  | '<hive>GRANT' UserOrRoleList 'TO' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>GRANT' UserOrRoleList 'TO' PrincipalSpecificationList_EDIT
  | '<hive>GRANT' UserOrRoleList 'TO' PrincipalSpecificationList OptionalWithAdminOption 'CURSOR'
    {
      if (!$5) {
-       suggestKeywords(['WITH ADMIN OPTION']);
+       parser.suggestKeywords(['WITH ADMIN OPTION']);
      }
    }
  | '<hive>GRANT' UserOrRoleList 'TO' PrincipalSpecificationList WithAdminOption_EDIT
  | '<hive>GRANT' '<hive>ROLE' UserOrRoleList 'TO' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>GRANT' '<hive>ROLE' UserOrRoleList 'TO' PrincipalSpecificationList_EDIT
  | '<hive>GRANT' '<hive>ROLE' UserOrRoleList 'TO' PrincipalSpecificationList OptionalWithAdminOption 'CURSOR'
    {
      if (!$6) {
-       suggestKeywords(['WITH ADMIN OPTION']);
+       parser.suggestKeywords(['WITH ADMIN OPTION']);
      }
    }
  | '<hive>GRANT' '<hive>ROLE' UserOrRoleList 'TO' PrincipalSpecificationList WithAdminOption_EDIT
  | '<impala>GRANT' 'CURSOR'
    {
-     suggestKeywords(['ALL', 'INSERT', 'ROLE', 'SELECT']);
+     parser.suggestKeywords(['ALL', 'INSERT', 'ROLE', 'SELECT']);
    }
  | '<impala>GRANT' '<impala>ROLE' RegularOrBacktickedIdentifier 'CURSOR'
    {
-     suggestKeywords(['TO GROUP']);
+     parser.suggestKeywords(['TO GROUP']);
    }
  | '<impala>GRANT' '<impala>ROLE' RegularOrBacktickedIdentifier 'TO' 'CURSOR'
    {
-     suggestKeywords(['GROUP']);
+     parser.suggestKeywords(['GROUP']);
    }
  | '<impala>GRANT' ImpalaPrivilegeType_EDIT
  | '<impala>GRANT' ImpalaPrivilegeType 'CURSOR'
    {
-     suggestKeywords(['ON DATABASE', 'ON SERVER', 'ON TABLE', 'ON URI']);
+     parser.suggestKeywords(['ON DATABASE', 'ON SERVER', 'ON TABLE', 'ON URI']);
    }
  | '<impala>GRANT' ImpalaPrivilegeType 'ON' 'CURSOR'
    {
-     suggestKeywords(['DATABASE', 'SERVER', 'TABLE', 'URI']);
+     parser.suggestKeywords(['DATABASE', 'SERVER', 'TABLE', 'URI']);
    }
  | '<impala>GRANT' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification_EDIT
  | '<impala>GRANT' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification 'CURSOR'
    {
-     suggestKeywords(['TO']);
+     parser.suggestKeywords(['TO']);
    }
  | '<impala>GRANT' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification 'TO' 'CURSOR'
    {
-     suggestKeywords(['ROLE']);
+     parser.suggestKeywords(['ROLE']);
    }
  | '<impala>GRANT' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification 'TO' RegularOrBacktickedIdentifier OptionalWithGrantOption 'CURSOR'
    {
      if (!$7) {
-       suggestKeywords(['WITH GRANT OPTION']);
+       parser.suggestKeywords(['WITH GRANT OPTION']);
      }
    }
  | '<impala>GRANT' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification 'TO' RegularOrBacktickedIdentifier WithGrantOption_EDIT
  | '<impala>GRANT' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification 'TO' '<impala>ROLE' RegularOrBacktickedIdentifier OptionalWithGrantOption 'CURSOR'
    {
      if (!$8) {
-       suggestKeywords(['WITH GRANT OPTION']);
+       parser.suggestKeywords(['WITH GRANT OPTION']);
      }
    }
  | '<impala>GRANT' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification 'TO' '<impala>ROLE' RegularOrBacktickedIdentifier WithGrantOption_EDIT
@@ -142,9 +142,9 @@ OptionalOnSpecification
 OnSpecification_EDIT
  : 'ON' 'CURSOR'
    {
-     suggestKeywords(['DATABASE', 'TABLE']);
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestKeywords(['DATABASE', 'TABLE']);
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'ON' HiveObjectSpecification_EDIT
  ;
@@ -153,23 +153,23 @@ HiveObjectSpecification
  : 'DATABASE' RegularOrBacktickedIdentifier
  | '<hive>TABLE' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($2);
+     parser.addTablePrimary($2);
    }
  | SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($1);
+     parser.addTablePrimary($1);
    }
  ;
 
 HiveObjectSpecification_EDIT
  : 'DATABASE' 'CURSOR'
    {
-     suggestDatabases();
+     parser.suggestDatabases();
    }
  | '<hive>TABLE' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT
  | SchemaQualifiedTableIdentifier_EDIT
@@ -179,7 +179,7 @@ ImpalaObjectSpecification
  : 'DATABASE' RegularOrBacktickedIdentifier
  | '<impala>TABLE' SchemaQualifiedTableIdentifier
    {
-     addTablePrimary($2);
+     parser.addTablePrimary($2);
    }
  | '<impala>SERVER' RegularOrBacktickedIdentifier
  | '<impala>URI' RegularOrBacktickedIdentifier
@@ -188,12 +188,12 @@ ImpalaObjectSpecification
 ImpalaObjectSpecification_EDIT
  : 'DATABASE' 'CURSOR'
    {
-     suggestDatabases();
+     parser.suggestDatabases();
    }
  | '<impala>TABLE' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<impala>TABLE' SchemaQualifiedTableIdentifier_EDIT
  ;
@@ -215,15 +215,15 @@ HivePrivilegeTypeList_EDIT
  | HivePrivilegeTypeList ',' HivePrivilegeTypeWithOptionalColumn_EDIT ',' HivePrivilegeTypeList
  | 'CURSOR' ',' HivePrivilegeTypeList
    {
-     suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'SELECT', 'SHOW_DATABASE', 'UPDATE']);
+     parser.suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'SELECT', 'SHOW_DATABASE', 'UPDATE']);
    }
  | HivePrivilegeTypeList ',' 'CURSOR'
    {
-     suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'SELECT', 'SHOW_DATABASE', 'UPDATE']);
+     parser.suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'SELECT', 'SHOW_DATABASE', 'UPDATE']);
    }
  | HivePrivilegeTypeList ',' 'CURSOR' ',' HivePrivilegeTypeList
    {
-     suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'SELECT', 'SHOW_DATABASE', 'UPDATE']);
+     parser.suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'SELECT', 'SHOW_DATABASE', 'UPDATE']);
    }
  ;
 
@@ -267,15 +267,15 @@ PrincipalSpecificationList
 PrincipalSpecificationList_EDIT
  : PrincipalSpecificationList ',' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | 'CURSOR' ',' PrincipalSpecificationList
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | PrincipalSpecificationList ',' 'CURSOR' ',' PrincipalSpecificationList
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  ;
 
@@ -299,15 +299,15 @@ OptionalWithGrantOption
 WithGrantOption_EDIT
  : 'WITH' 'CURSOR'
    {
-     suggestKeywords(['GRANT OPTION']);
+     parser.suggestKeywords(['GRANT OPTION']);
    }
  | 'WITH' '<hive>GRANT' 'CURSOR'
    {
-     suggestKeywords(['OPTION']);
+     parser.suggestKeywords(['OPTION']);
    }
  | 'WITH' '<impala>GRANT' 'CURSOR'
    {
-     suggestKeywords(['OPTION']);
+     parser.suggestKeywords(['OPTION']);
    }
  ;
 
@@ -319,11 +319,11 @@ OptionalWithAdminOption
 WithAdminOption_EDIT
  : 'WITH' 'CURSOR'
    {
-     suggestKeywords(['ADMIN OPTION']);
+     parser.suggestKeywords(['ADMIN OPTION']);
    }
  | 'WITH' '<hive>ADMIN' 'CURSOR'
    {
-     suggestKeywords(['OPTION']);
+     parser.suggestKeywords(['OPTION']);
    }
  ;
 
@@ -343,7 +343,7 @@ RevokeStatement
 RevokeStatement_EDIT
  : '<hive>REVOKE' 'CURSOR'
    {
-     suggestKeywords(['ADMIN OPTION FOR', 'ALL', 'ALL GRANT OPTION FROM', 'ALL PRIVILEGES FROM', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'GRANT OPTION FOR', 'INDEX', 'INSERT', 'LOCK', 'ROLE', 'SELECT', 'UPDATE']);
+     parser.suggestKeywords(['ADMIN OPTION FOR', 'ALL', 'ALL GRANT OPTION FROM', 'ALL PRIVILEGES FROM', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'GRANT OPTION FOR', 'INDEX', 'INSERT', 'LOCK', 'ROLE', 'SELECT', 'UPDATE']);
    }
  | '<hive>REVOKE' HivePrivilegeTypeList_EDIT
  | '<hive>REVOKE' HivePrivilegeTypeList OnSpecification_EDIT
@@ -351,129 +351,129 @@ RevokeStatement_EDIT
    {
      if (!$3) {
        if ($2.singleAll) {
-         suggestKeywords(['FROM', 'GRANT OPTION', 'ON', 'PRIVILEGES FROM']);
+         parser.suggestKeywords(['FROM', 'GRANT OPTION', 'ON', 'PRIVILEGES FROM']);
        } else {
-         suggestKeywords(['FROM', 'ON']);
+         parser.suggestKeywords(['FROM', 'ON']);
        }
      } else {
-       suggestKeywords(['FROM']);
+       parser.suggestKeywords(['FROM']);
      }
    }
  | '<hive>REVOKE' HivePrivilegeTypeList OptionalOnSpecification 'FROM' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>REVOKE' HivePrivilegeTypeList OptionalOnSpecification 'FROM' PrincipalSpecificationList_EDIT
  | '<hive>REVOKE' '<hive>GRANT' 'CURSOR'
    {
-     suggestKeywords(['OPTION FOR']);
+     parser.suggestKeywords(['OPTION FOR']);
    }
  | '<hive>REVOKE' '<hive>GRANT' 'OPTION' 'CURSOR'
    {
-     suggestKeywords(['FOR']);
+     parser.suggestKeywords(['FOR']);
    }
  | '<hive>REVOKE' '<hive>GRANT' 'OPTION' '<hive>FOR' 'CURSOR'
    {
-     suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'SELECT', 'SHOW_DATABASE', 'UPDATE']);
+     parser.suggestKeywords(['ALL', 'ALTER', 'CREATE', 'DELETE', 'DROP', 'INDEX', 'INSERT', 'LOCK', 'SELECT', 'SHOW_DATABASE', 'UPDATE']);
    }
  | '<hive>REVOKE' '<hive>GRANT' 'OPTION' '<hive>FOR' HivePrivilegeTypeList_EDIT
  | '<hive>REVOKE' '<hive>GRANT' 'OPTION' '<hive>FOR' HivePrivilegeTypeList OnSpecification_EDIT
  | '<hive>REVOKE' '<hive>GRANT' 'OPTION' '<hive>FOR' HivePrivilegeTypeList OptionalOnSpecification 'CURSOR'
    {
      if (!$6) {
-       suggestKeywords(['FROM', 'ON']);
+       parser.suggestKeywords(['FROM', 'ON']);
      } else {
-       suggestKeywords(['FROM']);
+       parser.suggestKeywords(['FROM']);
      }
    }
  | '<hive>REVOKE' '<hive>GRANT' 'OPTION' '<hive>FOR' HivePrivilegeTypeList OptionalOnSpecification 'FROM' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>REVOKE' '<hive>GRANT' 'OPTION' '<hive>FOR' HivePrivilegeTypeList OptionalOnSpecification 'FROM' PrincipalSpecificationList_EDIT
  | '<hive>REVOKE' UserOrRoleList 'CURSOR'
    {
      if ($2.toUpperCase() === 'ADMIN') {
-       suggestKeywords(['FROM', 'OPTION FOR']);
+       parser.suggestKeywords(['FROM', 'OPTION FOR']);
      } else {
-       suggestKeywords(['FROM']);
+       parser.suggestKeywords(['FROM']);
      }
    }
  | '<hive>REVOKE' UserOrRoleList 'FROM' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>REVOKE' UserOrRoleList 'FROM' PrincipalSpecificationList_EDIT
  | '<hive>REVOKE' '<hive>ROLE' UserOrRoleList 'CURSOR'
    {
-     suggestKeywords(['FROM']);
+     parser.suggestKeywords(['FROM']);
    }
  | '<hive>REVOKE' '<hive>ROLE' UserOrRoleList 'FROM' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>REVOKE' '<hive>ROLE' UserOrRoleList 'FROM' PrincipalSpecificationList_EDIT
 
  | '<hive>REVOKE' '<hive>ADMIN' 'OPTION' 'CURSOR'
    {
-     suggestKeywords(['FOR']);
+     parser.suggestKeywords(['FOR']);
    }
  | '<hive>REVOKE' '<hive>ADMIN' 'OPTION' '<hive>FOR' 'CURSOR'
    {
-     suggestKeywords(['ROLE']);
+     parser.suggestKeywords(['ROLE']);
    }
  | '<hive>REVOKE' '<hive>ADMIN' 'OPTION' '<hive>FOR' UserOrRoleList 'CURSOR'
    {
-     suggestKeywords(['FROM']);
+     parser.suggestKeywords(['FROM']);
    }
  | '<hive>REVOKE' '<hive>ADMIN' 'OPTION' '<hive>FOR' UserOrRoleList 'FROM' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>REVOKE' '<hive>ADMIN' 'OPTION' '<hive>FOR' UserOrRoleList 'FROM' PrincipalSpecificationList_EDIT
  | '<hive>REVOKE' '<hive>ADMIN' 'OPTION' '<hive>FOR' '<hive>ROLE' UserOrRoleList 'CURSOR'
    {
-     suggestKeywords(['FROM']);
+     parser.suggestKeywords(['FROM']);
    }
  | '<hive>REVOKE' '<hive>ADMIN' 'OPTION' '<hive>FOR' '<hive>ROLE' UserOrRoleList 'FROM' 'CURSOR'
    {
-     suggestKeywords(['GROUP', 'ROLE', 'USER']);
+     parser.suggestKeywords(['GROUP', 'ROLE', 'USER']);
    }
  | '<hive>REVOKE' '<hive>ADMIN' 'OPTION' '<hive>FOR' '<hive>ROLE' UserOrRoleList 'FROM' PrincipalSpecificationList_EDIT
  | '<hive>REVOKE' '<hive>ALL' PrivilegesOrGrantOption_EDIT
  | '<hive>REVOKE' '<hive>ALL' PrivilegesOrGrantOption 'CURSOR'
    {
-     suggestKeywords(['FROM']);
+     parser.suggestKeywords(['FROM']);
    }
  | '<impala>REVOKE' 'CURSOR'
    {
-     suggestKeywords(['ALL', 'INSERT', 'ROLE', 'SELECT']);
+     parser.suggestKeywords(['ALL', 'INSERT', 'ROLE', 'SELECT']);
    }
  | '<impala>REVOKE' '<impala>ROLE' RegularOrBacktickedIdentifier 'CURSOR'
    {
-     suggestKeywords(['FROM GROUP']);
+     parser.suggestKeywords(['FROM GROUP']);
    }
  | '<impala>REVOKE' '<impala>ROLE' RegularOrBacktickedIdentifier 'FROM' 'CURSOR'
    {
-     suggestKeywords(['GROUP']);
+     parser.suggestKeywords(['GROUP']);
    }
  | '<impala>REVOKE' ImpalaPrivilegeType_EDIT
  | '<impala>REVOKE' ImpalaPrivilegeType 'CURSOR'
    {
-     suggestKeywords(['ON DATABASE', 'ON SERVER', 'ON TABLE', 'ON URI']);
+     parser.suggestKeywords(['ON DATABASE', 'ON SERVER', 'ON TABLE', 'ON URI']);
    }
  | '<impala>REVOKE' ImpalaPrivilegeType 'ON' 'CURSOR'
    {
-     suggestKeywords(['DATABASE', 'SERVER', 'TABLE', 'URI']);
+     parser.suggestKeywords(['DATABASE', 'SERVER', 'TABLE', 'URI']);
    }
  | '<impala>REVOKE' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification_EDIT
  | '<impala>REVOKE' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification 'CURSOR'
    {
-     suggestKeywords(['FROM']);
+     parser.suggestKeywords(['FROM']);
    }
  | '<impala>REVOKE' ImpalaPrivilegeType 'ON' ImpalaObjectSpecification 'FROM' 'CURSOR'
    {
-     suggestKeywords(['ROLE']);
+     parser.suggestKeywords(['ROLE']);
    }
  ;
 
@@ -485,6 +485,6 @@ PrivilegesOrGrantOption
 PrivilegesOrGrantOption_EDIT
  : '<hive>GRANT' 'CURSOR'
    {
-     suggestKeywords(['OPTION']);
+     parser.suggestKeywords(['OPTION']);
    }
  ;

+ 56 - 56
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_insert.jison

@@ -32,12 +32,12 @@ DataManipulation_EDIT
  | ImpalaInsertStatement_EDIT
  | CommonTableExpression HiveInsertStatement_EDIT
    {
-     addCommonTableExpressions($1);
+     parser.addCommonTableExpressions($1);
    }
  | CommonTableExpression_EDIT HiveInsertStatement
  | CommonTableExpression ImpalaInsertStatement_EDIT
    {
-     addCommonTableExpressions($1);
+     parser.addCommonTableExpressions($1);
    }
  | CommonTableExpression_EDIT ImpalaInsertStatement
  ;
@@ -54,7 +54,7 @@ HiveInsertStatement_EDIT
    {
      var keywords = [];
      if ($1.suggestKeywords) {
-       keywords = createWeightedKeywords($1.suggestKeywords, 2).concat([{ value: 'SELECT', weight: 1}]);
+       keywords = parser.createWeightedKeywords($1.suggestKeywords, 2).concat([{ value: 'SELECT', weight: 1}]);
      } else {
        keywords = ['SELECT'];
      }
@@ -62,7 +62,7 @@ HiveInsertStatement_EDIT
        keywords.push({ weight: 1.1, value: 'VALUES' });
      }
      if (keywords.length > 0) {
-       suggestKeywords(keywords);
+       parser.suggestKeywords(keywords);
      }
    }
  | HiveInsertWithoutQuery_EDIT QuerySpecification
@@ -79,18 +79,18 @@ HiveInsertStatement_EDIT
  | FromClause_EDIT SelectWithoutTableExpression OptionalSelectConditions
  | FromClause 'CURSOR'
    {
-     suggestKeywords(['INSERT INTO', 'INSERT OVERWRITE', 'SELECT']);
+     parser.suggestKeywords(['INSERT INTO', 'INSERT OVERWRITE', 'SELECT']);
    }
  | FromClause SelectWithoutTableExpression_EDIT OptionalSelectConditions
    {
      if ($2.cursorAtEnd) {
-       checkForSelectListKeywords($2);
+       parser.checkForSelectListKeywords($2);
        var keywords = parser.yy.result.suggestKeywords || [];
        if ($3.suggestKeywords) {
          keywords = keywords.concat($3.suggestKeywords);
        }
        if (keywords.length > 0) {
-         suggestKeywords(keywords);
+         parser.suggestKeywords(keywords);
        }
      }
      delete parser.yy.result.suggestTables;
@@ -99,7 +99,7 @@ HiveInsertStatement_EDIT
  | FromClause SelectWithoutTableExpression OptionalSelectConditions_EDIT
    {
      if ($3.cursorAtStart) {
-       checkForSelectListKeywords($2.tableExpression);
+       parser.checkForSelectListKeywords($2.tableExpression);
      }
    }
  ;
@@ -108,7 +108,7 @@ HiveInsertWithoutQuery
  : '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalIfNotExists
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (!$5 && !$6) {
        $$ = { suggestKeywords: ['PARTITION'] }
      } else if (!$6) {
@@ -134,7 +134,7 @@ HiveInsertWithoutQuery
   | '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (!$5 && !$6) {
        $$ = { suggestKeywords: ['PARTITION'], addValues: true };
      } else if (!$6) {
@@ -146,15 +146,15 @@ HiveInsertWithoutQuery
 HiveInsertWithoutQuery_EDIT
  : '<hive>INSERT' 'CURSOR'
    {
-     suggestKeywords(['OVERWRITE', 'INTO']);
+     parser.suggestKeywords(['OVERWRITE', 'INTO']);
    }
  | '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['DIRECTORY', 'LOCAL DIRECTORY', 'TABLE']);
+       parser.suggestKeywords(['DIRECTORY', 'LOCAL DIRECTORY', 'TABLE']);
      }
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
      $$ = { keepTables: true }
    }
  | '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec OptionalParenthesizedColumnList
@@ -164,7 +164,7 @@ HiveInsertWithoutQuery_EDIT
  | '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT OptionalIfNotExists
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (parser.yy.result.suggestColumns) {
        parser.yy.result.suggestColumns.owner = 'insert';
      }
@@ -172,11 +172,11 @@ HiveInsertWithoutQuery_EDIT
  | '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalIfNotExists_EDIT
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  | '<hive>INSERT' '<hive>OVERWRITE' '<hive>LOCAL' 'CURSOR'
    {
-     suggestKeywords(['DIRECTORY']);
+     parser.suggestKeywords(['DIRECTORY']);
    }
  | '<hive>INSERT' '<hive>OVERWRITE' '<hive>LOCAL' '<hive>DIRECTORY' HdfsPath_EDIT OptionalInsertRowFormat OptionalStoredAs
  | '<hive>INSERT' '<hive>OVERWRITE' '<hive>LOCAL' '<hive>DIRECTORY' HdfsPath OptionalInsertRowFormat_EDIT OptionalStoredAs
@@ -187,10 +187,10 @@ HiveInsertWithoutQuery_EDIT
  | '<hive>INSERT' 'INTO' OptionalHiveTable 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['TABLE']);
+       parser.suggestKeywords(['TABLE']);
      }
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
      $$ = { keepTables: true }
    }
  | '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec OptionalParenthesizedColumnList
@@ -200,7 +200,7 @@ HiveInsertWithoutQuery_EDIT
  | '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT OptionalParenthesizedColumnList
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (parser.yy.result.suggestColumns) {
        parser.yy.result.suggestColumns.owner = 'insert';
      }
@@ -208,7 +208,7 @@ HiveInsertWithoutQuery_EDIT
  | '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList_EDIT
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (parser.yy.result.suggestColumns) {
        parser.yy.result.suggestColumns.owner = 'insert';
      }
@@ -238,21 +238,21 @@ HiveInsert_EDIT
  | HiveInsertWithoutQuery 'CURSOR'
    {
      if ($1.suggestKeywords) {
-       suggestKeywords(createWeightedKeywords($1.suggestKeywords, 2).concat([{ value: 'SELECT', weight: 1}]));
+       parser.suggestKeywords(parser.createWeightedKeywords($1.suggestKeywords, 2).concat([{ value: 'SELECT', weight: 1}]));
      } else {
-       suggestKeywords(['SELECT']);
+       parser.suggestKeywords(['SELECT']);
      }
    }
  | HiveInsertWithoutQuery SelectWithoutTableExpression_EDIT OptionalSelectConditions
    {
      if ($2.cursorAtEnd) {
-       checkForSelectListKeywords($2);
+       parser.checkForSelectListKeywords($2);
        var keywords = parser.yy.result.suggestKeywords || [];
        if ($3.suggestKeywords) {
          keywords = keywords.concat($3.suggestKeywords);
        }
        if (keywords.length > 0) {
-         suggestKeywords(keywords);
+         parser.suggestKeywords(keywords);
        }
      }
    }
@@ -263,34 +263,34 @@ InsertValuesStatement
  : '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec 'VALUES' InsertValuesList
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  | 'INSERT' 'INTO' OptionalTable SchemaQualifiedTableIdentifier 'VALUES' InsertValuesList
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
 InsertValuesStatement_EDIT
  : 'INSERT' 'CURSOR'
    {
-     suggestKeywords(['INTO']);
+     parser.suggestKeywords(['INTO']);
    }
  | 'INSERT' 'INTO' OptionalTable 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['TABLE']);
+       parser.suggestKeywords(['TABLE']);
      }
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | 'INSERT' 'INTO' OptionalTable SchemaQualifiedTableIdentifier_EDIT
  | 'INSERT' 'INTO' OptionalTable SchemaQualifiedTableIdentifier 'CURSOR'
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
-     suggestKeywords(['VALUES']);
+     parser.addTablePrimary($4);
+     parser.suggestKeywords(['VALUES']);
    }
  | 'INSERT' 'INTO' OptionalTable SchemaQualifiedTableIdentifier_EDIT 'VALUES' InsertValuesList
  ;
@@ -322,11 +322,11 @@ OptionalInsertRowFormat
 OptionalInsertRowFormat_EDIT
  : 'ROW' 'CURSOR'
    {
-     suggestKeywords(['FORMAT DELIMITED']);
+     parser.suggestKeywords(['FORMAT DELIMITED']);
    }
  | 'ROW' '<hive>FORMAT' 'CURSOR'
    {
-     suggestKeywords(['DELIMITED']);
+     parser.suggestKeywords(['DELIMITED']);
    }
  | 'ROW' '<hive>FORMAT' HiveDelimitedRowFormat_EDIT
  ;
@@ -343,7 +343,7 @@ SelectWithoutTableExpression_EDIT
    }
  | 'SELECT' OptionalAllOrDistinct SelectList_EDIT
    {
-     selectListNoTableSuggest($3, $2);
+     parser.selectListNoTableSuggest($3, $2);
    }
  | 'SELECT' OptionalAllOrDistinct 'CURSOR'
    {
@@ -351,20 +351,20 @@ SelectWithoutTableExpression_EDIT
      if ($2) {
        keywords = [{ value: '*', weight: 1000 }];
        if ($2 === 'ALL') {
-         suggestAggregateFunctions();
-         suggestAnalyticFunctions();
+         parser.suggestAggregateFunctions();
+         parser.suggestAnalyticFunctions();
        }
      } else {
        keywords = [{ value: '*', weight: 1000 }, 'ALL', 'DISTINCT'];
-       suggestAggregateFunctions();
-       suggestAnalyticFunctions();
+       parser.suggestAggregateFunctions();
+       parser.suggestAnalyticFunctions();
      }
-     if (isImpala()) {
+     if (parser.isImpala()) {
        keywords.push('STRAIGHT_JOIN');
      }
-     suggestKeywords(keywords);
-     suggestFunctions();
-     suggestColumns();
+     parser.suggestKeywords(keywords);
+     parser.suggestFunctions();
+     parser.suggestColumns();
    }
  ;
 
@@ -390,13 +390,13 @@ ImpalaInsertStatementWithoutCTE_EDIT
  : ImpalaInsertLeftPart_EDIT
  | ImpalaInsertLeftPart OptionalImpalaShuffleOrNoShuffle 'CURSOR'
    {
-     var keywords = $1.suggestKeywords && !$2 ? createWeightedKeywords($1.suggestKeywords, 2) : [];
+     var keywords = $1.suggestKeywords && !$2 ? parser.createWeightedKeywords($1.suggestKeywords, 2) : [];
      if (!$2) {
        keywords = keywords.concat(['[NOSHUFFLE]', '[SHUFFLE]', 'SELECT', 'VALUES'])
      } else {
        keywords = keywords.concat(['SELECT'])
      }
-     suggestKeywords(keywords);
+     parser.suggestKeywords(keywords);
    }
  | ImpalaInsertLeftPart_EDIT OptionalImpalaShuffleOrNoShuffle SelectStatement OptionalUnions
  | ImpalaInsertLeftPart OptionalImpalaShuffleOrNoShuffle SelectStatement_EDIT OptionalUnions
@@ -409,7 +409,7 @@ ImpalaInsertLeftPart
  : '<impala>INSERT' IntoOrOverwrite OptionalImpalaTable SchemaQualifiedTableIdentifier OptionalParenthesizedColumnList OptionalPartitionSpec
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (!$6) {
        $$ = { suggestKeywords: ['PARTITION'] };
      }
@@ -419,27 +419,27 @@ ImpalaInsertLeftPart
 ImpalaInsertLeftPart_EDIT
  : '<impala>INSERT' 'CURSOR'
    {
-     suggestKeywords(['INTO', 'OVERWRITE']);
+     parser.suggestKeywords(['INTO', 'OVERWRITE']);
    }
  | '<impala>INSERT' IntoOrOverwrite OptionalImpalaTable 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['TABLE']);
+       parser.suggestKeywords(['TABLE']);
      }
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<impala>INSERT' IntoOrOverwrite OptionalImpalaTable 'CURSOR' SchemaQualifiedTableIdentifier OptionalParenthesizedColumnList OptionalPartitionSpec
    {
      if (!$3) {
-       suggestKeywords(['TABLE']);
+       parser.suggestKeywords(['TABLE']);
      }
    }
  | '<impala>INSERT' IntoOrOverwrite OptionalImpalaTable SchemaQualifiedTableIdentifier_EDIT OptionalParenthesizedColumnList OptionalPartitionSpec
  | '<impala>INSERT' IntoOrOverwrite OptionalImpalaTable SchemaQualifiedTableIdentifier OptionalParenthesizedColumnList_EDIT OptionalPartitionSpec
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (parser.yy.result.suggestColumns) {
        parser.yy.result.suggestColumns.owner = 'insert';
      }
@@ -447,7 +447,7 @@ ImpalaInsertLeftPart_EDIT
  | '<impala>INSERT' IntoOrOverwrite OptionalImpalaTable SchemaQualifiedTableIdentifier OptionalParenthesizedColumnList OptionalPartitionSpec_EDIT
    {
      $4.owner = 'insert';
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
      if (parser.yy.result.suggestColumns) {
        parser.yy.result.suggestColumns.owner = 'insert';
      }
@@ -489,7 +489,7 @@ ParenthesizedImpalaRowValuesList
 ParenthesizedImpalaRowValuesList_EDIT
  : '(' AnyCursor RightParenthesisOrError
    {
-     suggestFunctions();
+     parser.suggestFunctions();
    }
  | '(' ValueExpressionList_EDIT RightParenthesisOrError
  ;

+ 55 - 55
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_load.jison

@@ -29,60 +29,60 @@ DataManipulation_EDIT
 LoadStatement
  : AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath OptionalOverwrite 'INTO' AnyTable SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($9);
+     parser.addTablePrimary($9);
    }
  ;
 
 LoadStatement_EDIT
  : AnyLoad 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['DATA LOCAL INPATH', 'DATA INPATH']);
-     } else if (isImpala()) {
-       suggestKeywords(['DATA INPATH']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['DATA LOCAL INPATH', 'DATA INPATH']);
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords(['DATA INPATH']);
      }
    }
  | AnyLoad AnyData OptionalHiveLocal 'CURSOR'
    {
-     if (isHive() && !$3) {
-       suggestKeywords(['INPATH', 'LOCAL INPATH']);
+     if (parser.isHive() && !$3) {
+       parser.suggestKeywords(['INPATH', 'LOCAL INPATH']);
      } else {
-       suggestKeywords(['INPATH']);
+       parser.suggestKeywords(['INPATH']);
      }
    }
  | AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath_EDIT OptionalOverwrite
  | AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath OptionalOverwrite 'CURSOR'
    {
      if (!$6) {
-       suggestKeywords(['OVERWRITE INTO TABLE', 'INTO TABLE']);
+       parser.suggestKeywords(['OVERWRITE INTO TABLE', 'INTO TABLE']);
      } else {
-       suggestKeywords(['INTO TABLE']);
+       parser.suggestKeywords(['INTO TABLE']);
      }
    }
  | AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath OptionalOverwrite 'INTO' 'CURSOR'
    {
-     suggestKeywords([ 'TABLE' ]);
+     parser.suggestKeywords([ 'TABLE' ]);
    }
  | AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath OptionalOverwrite 'INTO' AnyTable 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath OptionalOverwrite 'INTO' AnyTable SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec
  | AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath OptionalOverwrite 'INTO' AnyTable SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
    {
-     addTablePrimary($9);
+     parser.addTablePrimary($9);
      if (!$10) {
-       suggestKeywords(['PARTITION']);
+       parser.suggestKeywords(['PARTITION']);
      }
    }
  | AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath OptionalOverwrite 'INTO' AnyTable SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT
    {
-     addTablePrimary($9);
+     parser.addTablePrimary($9);
    }
  | AnyLoad AnyData OptionalHiveLocal AnyInpath HdfsPath_EDIT OptionalOverwrite 'INTO' AnyTable SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($9);
+     parser.addTablePrimary($9);
    }
  ;
 
@@ -120,17 +120,17 @@ ImportStatement_EDIT
  : '<hive>IMPORT' 'CURSOR' OptionalTableWithPartition
    {
      if (!$3) {
-       suggestKeywords(['EXTERNAL TABLE', 'FROM', 'TABLE']);
+       parser.suggestKeywords(['EXTERNAL TABLE', 'FROM', 'TABLE']);
      } else if (!$3.hasExternal) {
-       suggestKeywords(['EXTERNAL']);
+       parser.suggestKeywords(['EXTERNAL']);
      }
    }
  | '<hive>IMPORT' TableWithPartition 'CURSOR'
    {
      if ($2.suggestKeywords) {
-        suggestKeywords(createWeightedKeywords($2.suggestKeywords, 2).concat(['FROM']));
+        parser.suggestKeywords(parser.createWeightedKeywords($2.suggestKeywords, 2).concat(['FROM']));
       } else {
-        suggestKeywords(['FROM']);
+        parser.suggestKeywords(['FROM']);
       }
    }
  | '<hive>IMPORT' TableWithPartition_EDIT
@@ -139,22 +139,22 @@ ImportStatement_EDIT
  | '<hive>IMPORT' OptionalTableWithPartition PushHdfsLexerState 'FROM' HdfsPath OptionalHdfsLocation 'CURSOR'
    {
      if (!$6) {
-       suggestKeywords(['LOCATION']);
+       parser.suggestKeywords(['LOCATION']);
      }
    }
  | '<hive>IMPORT' 'CURSOR' OptionalTableWithPartition PushHdfsLexerState 'FROM' HdfsPath OptionalHdfsLocation
    {
      if (!$3) {
-       suggestKeywords(['EXTERNAL TABLE', 'TABLE']);
+       parser.suggestKeywords(['EXTERNAL TABLE', 'TABLE']);
      } else if (!$3.hasExternal) {
-       suggestKeywords(['EXTERNAL']);
+       parser.suggestKeywords(['EXTERNAL']);
      }
    }
 | '<hive>IMPORT' TableWithPartition_EDIT PushHdfsLexerState 'FROM' HdfsPath OptionalHdfsLocation
  | '<hive>IMPORT' TableWithPartition 'CURSOR' PushHdfsLexerState 'FROM' HdfsPath OptionalHdfsLocation
     {
       if ($2.suggestKeywords) {
-        suggestKeywords(createWeightedKeywords($2.suggestKeywords, 2).concat(['FROM']));
+        parser.suggestKeywords(parser.createWeightedKeywords($2.suggestKeywords, 2).concat(['FROM']));
       }
     }
  ;
@@ -167,7 +167,7 @@ OptionalTableWithPartition
 TableWithPartition
  : '<hive>EXTERNAL' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
      if (!$4) {
        $$ = { hasExternal: true, suggestKeywords: ['PARTITION'] };
      } else {
@@ -176,7 +176,7 @@ TableWithPartition
    }
  | '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec
    {
-     addTablePrimary($2);
+     parser.addTablePrimary($2);
      if (!$3) {
        $$ = { suggestKeywords: ['PARTITION'] };
      }
@@ -186,106 +186,106 @@ TableWithPartition
 TableWithPartition_EDIT
  : '<hive>EXTERNAL' 'CURSOR'
    {
-     suggestKeywords(['TABLE']);
+     parser.suggestKeywords(['TABLE']);
    }
  | '<hive>EXTERNAL' '<hive>TABLE' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<hive>EXTERNAL' '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec
  | '<hive>EXTERNAL' '<hive>TABLE' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | '<hive>TABLE' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
 
  | '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec
  | '<hive>TABLE' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
 ExportStatement
  : '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec PushHdfsLexerState 'TO' HdfsPath
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec PushHdfsLexerState 'TO' HdfsPath '<hive>FOR' '<hive>REPLICATION' '(' QuotedValue ')'
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
 ExportStatement_EDIT
  : '<hive>EXPORT' 'CURSOR'
    {
-     suggestKeywords(['TABLE']);
+     parser.suggestKeywords(['TABLE']);
    }
  | '<hive>EXPORT' '<hive>TABLE' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
      if (!$4) {
-       suggestKeywords([{ weight: 2, value: 'PARTITION' }, { weight: 1, value: 'TO' }]);
+       parser.suggestKeywords([{ weight: 2, value: 'PARTITION' }, { weight: 1, value: 'TO' }]);
      } else {
-       suggestKeywords([ 'TO' ]);
+       parser.suggestKeywords([ 'TO' ]);
      }
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec PushHdfsLexerState 'TO' HdfsPath_EDIT
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec PushHdfsLexerState 'TO' HdfsPath 'CURSOR'
    {
-     addTablePrimary($3);
-     suggestKeywords(['FOR replication()']);
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(['FOR replication()']);
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec PushHdfsLexerState 'TO' HdfsPath '<hive>FOR' 'CURSOR'
    {
-     addTablePrimary($3);
-     suggestKeywords(['replication()']);
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(['replication()']);
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec PushHdfsLexerState 'TO' HdfsPath
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec PushHdfsLexerState 'TO' HdfsPath '<hive>FOR' '<hive>REPLICATION' '(' QuotedValue ')'
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR' PushHdfsLexerState 'TO' HdfsPath
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
      if (!$4) {
-       suggestKeywords(['PARTITION']);
+       parser.suggestKeywords(['PARTITION']);
      }
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR' PushHdfsLexerState 'TO' HdfsPath '<hive>FOR' '<hive>REPLICATION' '(' QuotedValue ')'
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
      if (!$4) {
-       suggestKeywords(['PARTITION']);
+       parser.suggestKeywords(['PARTITION']);
      }
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier PartitionSpec_EDIT PushHdfsLexerState 'TO' HdfsPath
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier PartitionSpec_EDIT PushHdfsLexerState 'TO' HdfsPath '<hive>FOR' '<hive>REPLICATION' '(' QuotedValue ')'
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | '<hive>EXPORT' '<hive>TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec PushHdfsLexerState 'TO' HdfsPath_EDIT '<hive>FOR' '<hive>REPLICATION' '(' QuotedValue ')'
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;

文件差異過大導致無法顯示
+ 193 - 193
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_main.jison


+ 3 - 3
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_set.jison

@@ -22,8 +22,8 @@ DataDefinition_EDIT
  : SetRoleStatement_EDIT
  | 'SET' 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['ROLE']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['ROLE']);
      }
    }
  ;
@@ -37,6 +37,6 @@ SetRoleStatement
 SetRoleStatement_EDIT
  : 'SET' '<hive>ROLE' 'CURSOR'
    {
-     suggestKeywords(['ALL', 'NONE']);
+     parser.suggestKeywords(['ALL', 'NONE']);
    }
  ;

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

@@ -51,33 +51,33 @@ AnyShow
 ShowStatement_EDIT
  : AnyShow 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['COLUMNS', 'COMPACTIONS', 'CONF', 'CREATE TABLE', 'CURRENT ROLES', 'DATABASES', 'FORMATTED', 'FUNCTIONS', 'GRANT', 'INDEX', 'INDEXES', 'LOCKS', 'PARTITIONS', 'PRINCIPALS', 'ROLE GRANT', 'ROLES', 'SCHEMAS', 'TABLE EXTENDED', 'TABLES', 'TBLPROPERTIES', 'TRANSACTIONS']);
-     } else if (isImpala()) {
-       suggestKeywords(['AGGREGATE FUNCTIONS', 'ANALYTIC FUNCTIONS', 'COLUMN STATS', 'CREATE TABLE', 'CURRENT ROLES', 'DATABASES', 'FUNCTIONS', 'GRANT ROLE', 'PARTITIONS', 'ROLE GRANT GROUP', 'ROLES', 'SCHEMAS', 'TABLE STATS', 'TABLES']);
+     if (parser.isHive()) {
+       parser.suggestKeywords(['COLUMNS', 'COMPACTIONS', 'CONF', 'CREATE TABLE', 'CURRENT ROLES', 'DATABASES', 'FORMATTED', 'FUNCTIONS', 'GRANT', 'INDEX', 'INDEXES', 'LOCKS', 'PARTITIONS', 'PRINCIPALS', 'ROLE GRANT', 'ROLES', 'SCHEMAS', 'TABLE EXTENDED', 'TABLES', 'TBLPROPERTIES', 'TRANSACTIONS']);
+     } else if (parser.isImpala()) {
+       parser.suggestKeywords(['AGGREGATE FUNCTIONS', 'ANALYTIC FUNCTIONS', 'COLUMN STATS', 'CREATE TABLE', 'CURRENT ROLES', 'DATABASES', 'FUNCTIONS', 'GRANT ROLE', 'PARTITIONS', 'ROLE GRANT GROUP', 'ROLES', 'SCHEMAS', 'TABLE STATS', 'TABLES']);
      } else {
-       suggestKeywords(['COLUMNS', 'DATABASES', 'TABLES']);
+       parser.suggestKeywords(['COLUMNS', 'DATABASES', 'TABLES']);
      }
    }
  | AnyShow 'CURSOR' RegularOrBackTickedSchemaQualifiedName
    {
      // ROLES is considered a non-reserved keywords so we can't match it in ShowCurrentRolesStatement_EDIT
      if ($3.identifierChain && $3.identifierChain.length === 1 && $3.identifierChain[0].name.toLowerCase() === 'roles') {
-       suggestKeywords(['CURRENT']);
+       parser.suggestKeywords(['CURRENT']);
        parser.yy.locations.pop();
      } else {
-       addTablePrimary($3);
-       if (isImpala()) {
-         suggestKeywords(['COLUMN STATS', 'CREATE TABLE', 'PARTITIONS', 'TABLE STATS']);
+       parser.addTablePrimary($3);
+       if (parser.isImpala()) {
+         parser.suggestKeywords(['COLUMN STATS', 'CREATE TABLE', 'PARTITIONS', 'TABLE STATS']);
        }
      }
    }
  | AnyShow 'CURSOR' LIKE SingleQuotedValue
    {
-     if (isImpala()) {
-       suggestKeywords(['AGGREGATE FUNCTIONS', 'ANALYTIC FUNCTIONS', 'DATABASES', 'FUNCTIONS', 'SCHEMAS', 'TABLES']);
-     } else if (isHive()) {
-       suggestKeywords(['DATABASES', 'SCHEMAS', 'TABLE EXTENDED']);
+     if (parser.isImpala()) {
+       parser.suggestKeywords(['AGGREGATE FUNCTIONS', 'ANALYTIC FUNCTIONS', 'DATABASES', 'FUNCTIONS', 'SCHEMAS', 'TABLES']);
+     } else if (parser.isHive()) {
+       parser.suggestKeywords(['DATABASES', 'SCHEMAS', 'TABLE EXTENDED']);
      }
    }
  | ShowColumnStatsStatement_EDIT
@@ -99,19 +99,19 @@ ShowStatement_EDIT
 ShowColumnStatsStatement
  : AnyShow '<impala>COLUMN' '<impala>STATS' RegularOrBackTickedSchemaQualifiedName
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
 ShowColumnStatsStatement_EDIT
  : AnyShow '<impala>COLUMN' 'CURSOR'
    {
-     suggestKeywords(['STATS']);
+     parser.suggestKeywords(['STATS']);
    }
  | AnyShow '<impala>COLUMN' '<impala>STATS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({
+     parser.suggestTables();
+     parser.suggestDatabases({
        appendDot: true
      });
    }
@@ -126,35 +126,35 @@ ShowColumnsStatement
 ShowColumnsStatement_EDIT
  : AnyShow '<hive>COLUMNS' 'CURSOR'
    {
-     suggestKeywords(['FROM', 'IN']);
+     parser.suggestKeywords(['FROM', 'IN']);
    }
  | AnyShow '<hive>COLUMNS' 'CURSOR' RegularOrBacktickedIdentifier
    {
-     suggestKeywords(['FROM', 'IN']);
+     parser.suggestKeywords(['FROM', 'IN']);
    }
  | AnyShow '<hive>COLUMNS' AnyFromOrIn 'CURSOR'
    {
-     suggestTables();
+     parser.suggestTables();
    }
  | AnyShow '<hive>COLUMNS' AnyFromOrIn 'CURSOR' AnyFromOrIn
    {
-     suggestTables();
+     parser.suggestTables();
    }
  | AnyShow '<hive>COLUMNS' AnyFromOrIn 'CURSOR' AnyFromOrIn RegularOrBacktickedIdentifier
    {
-     suggestTables();
+     parser.suggestTables();
    }
  | AnyShow '<hive>COLUMNS' AnyFromOrIn RegularOrBacktickedIdentifier 'CURSOR'
    {
-     suggestKeywords(['FROM', 'IN']);
+     parser.suggestKeywords(['FROM', 'IN']);
    }
  | AnyShow '<hive>COLUMNS' AnyFromOrIn RegularOrBacktickedIdentifier 'CURSOR' RegularOrBacktickedIdentifier
    {
-     suggestKeywords(['FROM', 'IN']);
+     parser.suggestKeywords(['FROM', 'IN']);
    }
  | AnyShow '<hive>COLUMNS' AnyFromOrIn RegularOrBacktickedIdentifier AnyFromOrIn 'CURSOR'
    {
-     suggestDatabases();
+     parser.suggestDatabases();
    }
  ;
 
@@ -169,27 +169,27 @@ ShowConfStatement
 ShowCreateTableStatement
  : AnyShow HiveOrImpalaCreate AnyTable RegularOrBackTickedSchemaQualifiedName
    {
-     addTablePrimary($4);
+     parser.addTablePrimary($4);
    }
  ;
 
 ShowCreateTableStatement_EDIT
  : AnyShow HiveOrImpalaCreate 'CURSOR'
    {
-     suggestKeywords(['TABLE']);
+     parser.suggestKeywords(['TABLE']);
    }
  | AnyShow HiveOrImpalaCreate AnyTable 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({
+     parser.suggestTables();
+     parser.suggestDatabases({
        appendDot: true
      });
    }
  | AnyShow HiveOrImpalaCreate AnyTable RegularOrBackTickedSchemaQualifiedName_EDIT
  | AnyShow HiveOrImpalaCreate 'CURSOR' RegularOrBackTickedSchemaQualifiedName
    {
-     addTablePrimary($4);
-     suggestKeywords(['TABLE']);
+     parser.addTablePrimary($4);
+     parser.suggestKeywords(['TABLE']);
    }
  ;
 
@@ -201,11 +201,11 @@ ShowCurrentRolesStatement
 ShowCurrentRolesStatement_EDIT
  : AnyShow '<hive>CURRENT' 'CURSOR'
    {
-     suggestKeywords([ 'ROLES' ]);
+     parser.suggestKeywords([ 'ROLES' ]);
    }
  | AnyShow '<impala>CURRENT' 'CURSOR'
    {
-     suggestKeywords([ 'ROLES' ]);
+     parser.suggestKeywords([ 'ROLES' ]);
    }
  ;
 
@@ -217,7 +217,7 @@ ShowDatabasesStatement
 ShowDatabasesStatement_EDIT
  : AnyShow HiveOrImpalaDatabasesOrSchemas 'CURSOR'
    {
-     suggestKeywords(['LIKE']);
+     parser.suggestKeywords(['LIKE']);
    }
  ;
 
@@ -231,34 +231,34 @@ ShowFunctionsStatement
 ShowFunctionsStatement_EDIT
  : AnyShow AggregateOrAnalytic 'CURSOR'
    {
-     suggestKeywords(['FUNCTIONS']);
+     parser.suggestKeywords(['FUNCTIONS']);
    }
  | AnyShow 'CURSOR' '<impala>FUNCTIONS' OptionalInDatabase
    {
-     suggestKeywords(['AGGREGATE', 'ANALYTICAL']);
+     parser.suggestKeywords(['AGGREGATE', 'ANALYTICAL']);
    }
  | AnyShow OptionalAggregateOrAnalytic '<impala>FUNCTIONS' OptionalInDatabase 'CURSOR'
    {
      if (!$4) {
-       suggestKeywords(['IN', 'LIKE']);
+       parser.suggestKeywords(['IN', 'LIKE']);
      } else {
-       suggestKeywords(['LIKE']);
+       parser.suggestKeywords(['LIKE']);
      }
    }
  | AnyShow AggregateOrAnalytic 'CURSOR' OptionalInDatabase 'LIKE' SingleQuoteValue
    {
-     suggestKeywords(['FUNCTIONS']);
+     parser.suggestKeywords(['FUNCTIONS']);
    }
  | AnyShow 'CURSOR' '<impala>FUNCTIONS' OptionalInDatabase 'LIKE' SingleQuoteValue
    {
-     suggestKeywords(['AGGREGATE', 'ANALYTICAL']);
+     parser.suggestKeywords(['AGGREGATE', 'ANALYTICAL']);
    }
  | AnyShow OptionalAggregateOrAnalytic '<impala>FUNCTIONS' OptionalInDatabase 'CURSOR' SingleQuoteValue
    {
      if (!$4) {
-       suggestKeywords([{ value: 'IN', weight: 2 }, { value: 'LIKE', weight: 1 }]);
+       parser.suggestKeywords([{ value: 'IN', weight: 2 }, { value: 'LIKE', weight: 1 }]);
      } else {
-       suggestKeywords(['LIKE']);
+       parser.suggestKeywords(['LIKE']);
      }
    }
  ;
@@ -273,25 +273,25 @@ ShowGrantStatement
 ShowGrantStatement_EDIT
  : AnyShow '<hive>GRANT' OptionalPrincipalName_EDIT
    {
-     suggestKeywords(['ON']);
+     parser.suggestKeywords(['ON']);
    }
  | AnyShow '<hive>GRANT' OptionalPrincipalName_EDIT 'ON' '<hive>ALL'
  | AnyShow '<hive>GRANT' OptionalPrincipalName 'ON' 'CURSOR'
    {
-     suggestKeywords(['ALL', 'TABLE']);
-     suggestTables();
+     parser.suggestKeywords(['ALL', 'TABLE']);
+     parser.suggestTables();
    }
  | AnyShow  '<hive>GRANT' OptionalPrincipalName 'ON' AnyTable 'CURSOR'
    {
-     suggestTables();
+     parser.suggestTables();
    }
  | AnyShow '<hive>GRANT' OptionalPrincipalName 'ON' 'CURSOR' RegularOrBacktickedIdentifier
    {
-     suggestKeywords(['TABLE']);
+     parser.suggestKeywords(['TABLE']);
    }
  | AnyShow '<impala>GRANT' 'CURSOR'
    {
-     suggestKeywords(['ROLE']);
+     parser.suggestKeywords(['ROLE']);
    }
  ;
 
@@ -317,50 +317,50 @@ ShowIndexStatement_EDIT
  | AnyShow OptionallyFormattedIndex_EDIT 'ON' RegularOrBacktickedIdentifier AnyFromOrIn RegularOrBacktickedIdentifier
  | AnyShow OptionallyFormattedIndex 'CURSOR'
    {
-     suggestKeywords(['ON']);
+     parser.suggestKeywords(['ON']);
    }
  | AnyShow OptionallyFormattedIndex 'ON' 'CURSOR'
    {
-     suggestTables();
+     parser.suggestTables();
    }
  | AnyShow OptionallyFormattedIndex 'CURSOR' RegularOrBacktickedIdentifier
    {
-     suggestKeywords(['ON']);
+     parser.suggestKeywords(['ON']);
    }
  | AnyShow OptionallyFormattedIndex 'ON' RegularOrBacktickedIdentifier 'CURSOR'
    {
-     suggestKeywords(['FROM', 'IN']);
+     parser.suggestKeywords(['FROM', 'IN']);
    }
  | AnyShow OptionallyFormattedIndex 'ON' RegularOrBacktickedIdentifier 'CURSOR' RegularOrBacktickedIdentifier
    {
-     suggestKeywords(['FROM', 'IN']);
+     parser.suggestKeywords(['FROM', 'IN']);
    }
  | AnyShow OptionallyFormattedIndex 'ON' RegularOrBacktickedIdentifier AnyFromOrIn 'CURSOR'
    {
-     suggestDatabases();
+     parser.suggestDatabases();
    }
  | AnyShow OptionallyFormattedIndex 'ON' 'CURSOR' AnyFromOrIn RegularOrBacktickedIdentifier
    {
-     suggestTables({identifierChain: [{name: $6}]});
+     parser.suggestTables({identifierChain: [{name: $6}]});
    }
  ;
 
 ShowLocksStatement
  : AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName '<hive>EXTENDED'
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName PartitionSpec
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName PartitionSpec '<hive>EXTENDED'
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | AnyShow '<hive>LOCKS' DatabaseOrSchema RegularOrBacktickedIdentifier
  ;
@@ -368,66 +368,66 @@ ShowLocksStatement
 ShowLocksStatement_EDIT
  : AnyShow '<hive>LOCKS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({
+     parser.suggestTables();
+     parser.suggestDatabases({
        appendDot: true
      });
-     suggestKeywords(['DATABASE', 'SCHEMA']);
+     parser.suggestKeywords(['DATABASE', 'SCHEMA']);
    }
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName 'CURSOR'
     {
-      addTablePrimary($3);
-      suggestKeywords(['EXTENDED', 'PARTITION']);
+      parser.addTablePrimary($3);
+      parser.suggestKeywords(['EXTENDED', 'PARTITION']);
     }
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT '<hive>EXTENDED'
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT PartitionSpec
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName PartitionSpec 'CURSOR'
    {
-     addTablePrimary($3);
-     suggestKeywords(['EXTENDED']);
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(['EXTENDED']);
    }
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT PartitionSpec '<hive>EXTENDED'
  | AnyShow '<hive>LOCKS' DatabaseOrSchema 'CURSOR'
    {
-     suggestDatabases();
+     parser.suggestDatabases();
    }
  ;
 
 ShowPartitionsStatement
  : AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName PartitionSpec
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  | AnyShow '<impala>PARTITIONS' RegularOrBackTickedSchemaQualifiedName
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
 ShowPartitionsStatement_EDIT
  : AnyShow '<hive>PARTITIONS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({
+     parser.suggestTables();
+     parser.suggestDatabases({
        appendDot: true
      });
    }
  | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName_EDIT
  | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName 'CURSOR'
    {
-     addTablePrimary($3);
-     suggestKeywords(['PARTITION']);
+     parser.addTablePrimary($3);
+     parser.suggestKeywords(['PARTITION']);
    }
  | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName_EDIT PartitionSpec
  | AnyShow '<impala>PARTITIONS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({
+     parser.suggestTables();
+     parser.suggestDatabases({
        appendDot: true
      });
    }
@@ -442,31 +442,31 @@ ShowRoleStatement
 ShowRoleStatement_EDIT
  : AnyShow '<hive>ROLE' 'CURSOR'
    {
-     suggestKeywords(['GRANT']);
+     parser.suggestKeywords(['GRANT']);
    }
  | AnyShow '<impala>ROLE' 'CURSOR'
    {
-     suggestKeywords(['GRANT']);
+     parser.suggestKeywords(['GRANT']);
    }
  | AnyShow '<hive>ROLE' 'CURSOR' HiveRoleOrUser RegularIdentifier
    {
-     suggestKeywords(['GRANT']);
+     parser.suggestKeywords(['GRANT']);
    }
  | AnyShow '<hive>ROLE' '<hive>GRANT' 'CURSOR'
    {
-     suggestKeywords(['ROLE', 'USER']);
+     parser.suggestKeywords(['ROLE', 'USER']);
    }
  | AnyShow '<hive>ROLE' '<hive>GRANT' 'CURSOR' RegularIdentifier
    {
-     suggestKeywords(['ROLE', 'USER']);
+     parser.suggestKeywords(['ROLE', 'USER']);
    }
  | AnyShow '<impala>ROLE' '<impala>GRANT' 'CURSOR'
    {
-     suggestKeywords(['GROUP']);
+     parser.suggestKeywords(['GROUP']);
    }
  | AnyShow '<impala>ROLE' '<impala>GRANT' 'CURSOR' RegularIdentifier
    {
-     suggestKeywords(['GROUP']);
+     parser.suggestKeywords(['GROUP']);
    }
  ;
 
@@ -483,60 +483,60 @@ ShowTableStatement
 ShowTableStatement_EDIT
  : AnyShow '<hive>TABLE' 'CURSOR'
    {
-     suggestKeywords(['EXTENDED']);
+     parser.suggestKeywords(['EXTENDED']);
    }
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase_EDIT
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'CURSOR'
     {
       if ($4) {
-        suggestKeywords(['LIKE']);
+        parser.suggestKeywords(['LIKE']);
       } else {
-        suggestKeywords(['FROM', 'IN', 'LIKE']);
+        parser.suggestKeywords(['FROM', 'IN', 'LIKE']);
       }
     }
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase_EDIT 'LIKE' SingleQuotedValue
  | AnyShow '<hive>TABLE' 'CURSOR' OptionalFromDatabase 'LIKE' SingleQuotedValue
     {
-      if (isHive()) {
-        suggestKeywords(['EXTENDED']);
+      if (parser.isHive()) {
+        parser.suggestKeywords(['EXTENDED']);
       }
     }
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'CURSOR' SingleQuotedValue
     {
-      suggestKeywords(['LIKE']);
+      parser.suggestKeywords(['LIKE']);
     }
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue 'CURSOR'
     {
-      suggestKeywords(['PARTITION']);
+      parser.suggestKeywords(['PARTITION']);
     }
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase_EDIT 'LIKE' SingleQuotedValue PartitionSpec
  | AnyShow '<hive>TABLE' 'CURSOR' OptionalFromDatabase 'LIKE' SingleQuotedValue PartitionSpec
    {
-     suggestKeywords(['EXTENDED']);
+     parser.suggestKeywords(['EXTENDED']);
    }
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'CURSOR' SingleQuotedValue PartitionSpec
    {
-     suggestKeywords(['LIKE']);
+     parser.suggestKeywords(['LIKE']);
    }
  | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue 'CURSOR' PartitionSpecList
    {
-     suggestKeywords(['PARTITION']);
+     parser.suggestKeywords(['PARTITION']);
    }
  | AnyShow '<impala>TABLE' 'CURSOR'
    {
-     suggestKeywords(['STATS']);
+     parser.suggestKeywords(['STATS']);
    }
  | AnyShow '<impala>TABLE' '<impala>STATS' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({
+     parser.suggestTables();
+     parser.suggestDatabases({
        appendDot: true
      });
    }
  | AnyShow '<impala>TABLE' '<impala>STATS' RegularOrBackTickedSchemaQualifiedName
     {
-      addTablePrimary($4);
+      parser.addTablePrimary($4);
     }
  | AnyShow '<impala>TABLE' '<impala>STATS' RegularOrBackTickedSchemaQualifiedName_EDIT
  ;
@@ -551,9 +551,9 @@ ShowTablesStatement_EDIT
  : AnyShow HiveOrImpalaTables OptionalInDatabase 'CURSOR'
    {
      if (!$3) {
-       suggestKeywords(['IN', 'LIKE']);
+       parser.suggestKeywords(['IN', 'LIKE']);
      } else {
-       suggestKeywords(['LIKE']);
+       parser.suggestKeywords(['LIKE']);
      }
    }
  ;
@@ -561,7 +561,7 @@ ShowTablesStatement_EDIT
 ShowTblPropertiesStatement
  : AnyShow '<hive>TBLPROPERTIES' RegularOrBackTickedSchemaQualifiedName
    {
-     addTablePrimary($3);
+     parser.addTablePrimary($3);
    }
  ;
 
@@ -569,8 +569,8 @@ ShowTblPropertiesStatement_EDIT
  : AnyShow '<hive>TBLPROPERTIES' RegularOrBackTickedSchemaQualifiedName_EDIT
  | AnyShow '<hive>TBLPROPERTIES' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ prependDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ prependDot: true });
    }
  ;
 

+ 7 - 7
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_update.jison

@@ -33,19 +33,19 @@ UpdateStatement_EDIT
  | 'UPDATE' TargetTable 'SET' SetClauseList OptionalWhereClause 'CURSOR'
    {
      if (!$5) {
-       suggestKeywords([ 'WHERE' ]);
+       parser.suggestKeywords([ 'WHERE' ]);
      }
    }
  | 'UPDATE' TargetTable 'CURSOR'
    {
-     suggestKeywords([ 'SET' ]);
+     parser.suggestKeywords([ 'SET' ]);
    }
  | 'UPDATE' TargetTable_EDIT
  | 'UPDATE' TargetTable
  | 'UPDATE' 'CURSOR'
    {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
    }
  ;
 
@@ -60,7 +60,7 @@ TargetTable_EDIT
 TableName
  : LocalOrSchemaQualifiedName
    {
-     addTablePrimary($1);
+     parser.addTablePrimary($1);
    }
  ;
 
@@ -88,11 +88,11 @@ SetClause_EDIT
  : SetTarget '=' UpdateSource_EDIT
  | SetTarget 'CURSOR'
    {
-     suggestKeywords([ '=' ]);
+     parser.suggestKeywords([ '=' ]);
    }
  | 'CURSOR'
    {
-     suggestColumns();
+     parser.suggestColumns();
    }
  ;
 

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

@@ -39,7 +39,7 @@ UseStatement
 UseStatement_EDIT
  : AnyUse 'CURSOR'
    {
-     suggestDatabases();
+     parser.suggestDatabases();
    }
  ;
 

+ 148 - 148
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_valueExpression.jison

@@ -39,51 +39,51 @@ ValueExpression_EDIT
  : 'NOT' ValueExpression_EDIT                           -> { types: [ 'BOOLEAN' ] }
  | 'NOT' 'CURSOR'
    {
-     suggestFunctions();
-     suggestColumns();
-     suggestKeywords(['EXISTS']);
+     parser.suggestFunctions();
+     parser.suggestColumns();
+     parser.suggestKeywords(['EXISTS']);
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | '!' ValueExpression_EDIT                             -> { types: [ 'BOOLEAN' ] }
  | '!' AnyCursor
    {
-     suggestFunctions({ types: [ 'BOOLEAN' ] });
-     suggestColumns({ types: [ 'BOOLEAN' ] });
+     parser.suggestFunctions({ types: [ 'BOOLEAN' ] });
+     parser.suggestColumns({ types: [ 'BOOLEAN' ] });
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | '~' ValueExpression_EDIT                             -> { types: [ 'T' ] }
  | '~' 'PARTIAL_CURSOR'
    {
-     suggestFunctions();
-     suggestColumns();
+     parser.suggestFunctions();
+     parser.suggestColumns();
      $$ = { types: [ 'T' ] };
    }
  | '-' ValueExpression_EDIT %prec NEGATION
    {
      if (!$2.typeSet) {
-       applyTypeToSuggestions('NUMBER');
+       parser.applyTypeToSuggestions('NUMBER');
      }
      $$ = { types: [ 'NUMBER' ] };
    }
  | '-' 'PARTIAL_CURSOR' %prec NEGATION
    {
-     suggestFunctions({ types: [ 'NUMBER' ] });
-     suggestColumns({ types: [ 'NUMBER' ] });
+     parser.suggestFunctions({ types: [ 'NUMBER' ] });
+     parser.suggestColumns({ types: [ 'NUMBER' ] });
      $$ = { types: [ 'NUMBER' ] };
    }
  | ValueExpression 'IS' 'NOT' 'CURSOR'
     {
-      suggestKeywords(['NULL']);
+      parser.suggestKeywords(['NULL']);
       $$ = { types: [ 'BOOLEAN' ] };
     }
  | ValueExpression 'IS' 'CURSOR'
    {
-     suggestKeywords(['NOT NULL', 'NULL']);
+     parser.suggestKeywords(['NOT NULL', 'NULL']);
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'IS' 'CURSOR' 'NULL'
    {
-     suggestKeywords(['NOT']);
+     parser.suggestKeywords(['NOT']);
      $$ = { types: [ 'BOOLEAN' ] };
    }
  ;
@@ -107,7 +107,7 @@ ValueExpression_EDIT
    }
  | '(' 'CURSOR' RightParenthesisOrError
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { types: ['T'], typeSet: true };
    }
  ;
@@ -124,113 +124,113 @@ ValueExpression
 ValueExpression_EDIT
  : 'CURSOR' '=' ValueExpression
    {
-     valueExpressionSuggest($3, $2);
-     applyTypeToSuggestions($3.types);
+     parser.valueExpressionSuggest($3, $2);
+     parser.applyTypeToSuggestions($3.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true };
    }
  | 'CURSOR' '<' ValueExpression
    {
-     valueExpressionSuggest($3, $2);
-     applyTypeToSuggestions($3.types);
+     parser.valueExpressionSuggest($3, $2);
+     parser.applyTypeToSuggestions($3.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | 'CURSOR' '>' ValueExpression
    {
-     valueExpressionSuggest($3, $2);
-     applyTypeToSuggestions($3.types);
+     parser.valueExpressionSuggest($3, $2);
+     parser.applyTypeToSuggestions($3.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | 'CURSOR' 'COMPARISON_OPERATOR' ValueExpression
    {
-     valueExpressionSuggest($3, $2);
-     applyTypeToSuggestions($3.types);
+     parser.valueExpressionSuggest($3, $2);
+     parser.applyTypeToSuggestions($3.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression_EDIT '=' ValueExpression
    {
      if (!$1.typeSet) {
-       applyTypeToSuggestions($3.types);
-       addColRefIfExists($3);
+       parser.applyTypeToSuggestions($3.types);
+       parser.addColRefIfExists($3);
      }
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression_EDIT '<' ValueExpression
    {
      if (!$1.typeSet) {
-       applyTypeToSuggestions($3.types);
-       addColRefIfExists($3);
+       parser.applyTypeToSuggestions($3.types);
+       parser.addColRefIfExists($3);
      }
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression_EDIT '>' ValueExpression
    {
      if (!$1.typeSet) {
-       applyTypeToSuggestions($3.types);
-       addColRefIfExists($3);
+       parser.applyTypeToSuggestions($3.types);
+       parser.addColRefIfExists($3);
      }
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression_EDIT 'COMPARISON_OPERATOR' ValueExpression
    {
      if (!$1.typeSet) {
-       applyTypeToSuggestions($3.types);
-       addColRefIfExists($3);
+       parser.applyTypeToSuggestions($3.types);
+       parser.addColRefIfExists($3);
      }
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression '=' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest($1, $2);
-     applyTypeToSuggestions($1.types);
+     parser.valueExpressionSuggest($1, $2);
+     parser.applyTypeToSuggestions($1.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression '<' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest($1, $2);
-     applyTypeToSuggestions($1.types);
+     parser.valueExpressionSuggest($1, $2);
+     parser.applyTypeToSuggestions($1.types);
      $$ = { types: [ 'BOOLEAN' ] , typeSet: true, endsWithLessThanOrEqual: true };
    }
  | ValueExpression '>' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest($1, $2);
-     applyTypeToSuggestions($1.types);
+     parser.valueExpressionSuggest($1, $2);
+     parser.applyTypeToSuggestions($1.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression 'COMPARISON_OPERATOR' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest($1, $2);
-     applyTypeToSuggestions($1.types);
+     parser.valueExpressionSuggest($1, $2);
+     parser.applyTypeToSuggestions($1.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true, endsWithLessThanOrEqual: $2 === '<='  };
    }
  | ValueExpression '=' ValueExpression_EDIT
    {
      if (!$3.typeSet) {
-       applyTypeToSuggestions($1.types);
-       addColRefIfExists($1);
+       parser.applyTypeToSuggestions($1.types);
+       parser.addColRefIfExists($1);
      }
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression '<' ValueExpression_EDIT
    {
      if (!$3.typeSet) {
-       applyTypeToSuggestions($1.types);
-       addColRefIfExists($1);
+       parser.applyTypeToSuggestions($1.types);
+       parser.addColRefIfExists($1);
      }
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression '>' ValueExpression_EDIT
    {
      if (!$3.typeSet) {
-       applyTypeToSuggestions($1.types);
-       addColRefIfExists($1);
+       parser.applyTypeToSuggestions($1.types);
+       parser.addColRefIfExists($1);
      }
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression 'COMPARISON_OPERATOR' ValueExpression_EDIT
    {
      if (!$3.typeSet) {
-       applyTypeToSuggestions($1.types);
-       addColRefIfExists($1);
+       parser.applyTypeToSuggestions($1.types);
+       parser.addColRefIfExists($1);
      }
      $$ = { types: [ 'BOOLEAN' ] }
    }
@@ -250,22 +250,22 @@ ValueExpression_EDIT
  : ValueExpression 'NOT' 'IN' ValueExpressionInSecondPart_EDIT
    {
      if ($4.inValueEdit) {
-       valueExpressionSuggest($1, $2 + ' ' + $3);
-       applyTypeToSuggestions($1.types);
+       parser.valueExpressionSuggest($1, $2 + ' ' + $3);
+       parser.applyTypeToSuggestions($1.types);
      }
      if ($4.cursorAtStart) {
-       suggestKeywords(['SELECT']);
+       parser.suggestKeywords(['SELECT']);
      }
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression 'IN' ValueExpressionInSecondPart_EDIT
    {
      if ($3.inValueEdit) {
-       valueExpressionSuggest($1, $2);
-       applyTypeToSuggestions($1.types);
+       parser.valueExpressionSuggest($1, $2);
+       parser.applyTypeToSuggestions($1.types);
      }
      if ($3.cursorAtStart) {
-       suggestKeywords(['SELECT']);
+       parser.suggestKeywords(['SELECT']);
      }
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
@@ -292,75 +292,75 @@ ValueExpression_EDIT
  : ValueExpression_EDIT 'NOT' 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression
    {
      if ($4.types[0] === $6.types[0] && !$1.typeSet) {
-       applyTypeToSuggestions($4.types);
+       parser.applyTypeToSuggestions($4.types);
      }
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'NOT' 'BETWEEN' ValueExpression_EDIT 'BETWEEN_AND' ValueExpression
    {
      if ($1.types[0] === $6.types[0] && !$4.typeSet) {
-       applyTypeToSuggestions($1.types);
+       parser.applyTypeToSuggestions($1.types);
      }
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'NOT' 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression_EDIT
    {
      if ($1.types[0] === $4.types[0] && !$6.typeSet) {
-       applyTypeToSuggestions($1.types);
+       parser.applyTypeToSuggestions($1.types);
      }
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'NOT' 'BETWEEN' ValueExpression 'BETWEEN_AND' 'CURSOR'
    {
-     valueExpressionSuggest($1, $5);
+     parser.valueExpressionSuggest($1, $5);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression 'NOT' 'BETWEEN' ValueExpression 'CURSOR'
    {
-     suggestValueExpressionKeywords($4, ['AND']);
+     parser.suggestValueExpressionKeywords($4, ['AND']);
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'NOT' 'BETWEEN' 'CURSOR'
    {
-     valueExpressionSuggest($1, $2 + ' ' + $3);
+     parser.valueExpressionSuggest($1, $2 + ' ' + $3);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression_EDIT 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression
    {
      if ($1.types[0] === $3.types[0] && !$1.typeSet) {
-       applyTypeToSuggestions($1.types)
+       parser.applyTypeToSuggestions($1.types)
      }
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'BETWEEN' ValueExpression_EDIT 'BETWEEN_AND' ValueExpression
    {
      if ($1.types[0] === $3.types[0] && !$3.typeSet) {
-       applyTypeToSuggestions($1.types)
+       parser.applyTypeToSuggestions($1.types)
      }
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression_EDIT
    {
      if ($1.types[0] === $3.types[0] && !$5.typeSet) {
-       applyTypeToSuggestions($1.types)
+       parser.applyTypeToSuggestions($1.types)
      }
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'BETWEEN' ValueExpression 'BETWEEN_AND' 'CURSOR'
    {
-     valueExpressionSuggest($1, $4);
-     applyTypeToSuggestions($1.types);
+     parser.valueExpressionSuggest($1, $4);
+     parser.applyTypeToSuggestions($1.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression 'BETWEEN' ValueExpression 'CURSOR'
    {
-     suggestValueExpressionKeywords($3, ['AND']);
+     parser.suggestValueExpressionKeywords($3, ['AND']);
      $$ = { types: [ 'BOOLEAN' ] };
    }
  | ValueExpression 'BETWEEN' 'CURSOR'
    {
-     valueExpressionSuggest($1, $2);
-     applyTypeToSuggestions($1.types);
+     parser.valueExpressionSuggest($1, $2);
+     parser.applyTypeToSuggestions($1.types);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true };
    }
  ;
@@ -385,42 +385,42 @@ ValueExpression
 ValueExpression_EDIT
  : 'CURSOR' 'OR' ValueExpression
    {
-     valueExpressionSuggest(undefined, $2);
+     parser.valueExpressionSuggest(undefined, $2);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression_EDIT 'OR' ValueExpression
    {
-     addColRefIfExists($3);
+     parser.addColRefIfExists($3);
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression 'OR' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest(undefined, $2);
+     parser.valueExpressionSuggest(undefined, $2);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression 'OR' ValueExpression_EDIT
    {
-     addColRefIfExists($1);
+     parser.addColRefIfExists($1);
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | 'CURSOR' 'AND' ValueExpression
    {
-     valueExpressionSuggest(undefined, $2);
+     parser.valueExpressionSuggest(undefined, $2);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true };
    }
  | ValueExpression_EDIT 'AND' ValueExpression
    {
-     addColRefIfExists($3);
+     parser.addColRefIfExists($3);
      $$ = { types: [ 'BOOLEAN' ] }
    }
  | ValueExpression 'AND' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest(undefined, $2);
+     parser.valueExpressionSuggest(undefined, $2);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true  };
    }
  | ValueExpression 'AND' ValueExpression_EDIT
    {
-     addColRefIfExists($1);
+     parser.addColRefIfExists($1);
      $$ = { types: [ 'BOOLEAN' ] }
    }
  ;
@@ -451,79 +451,79 @@ ValueExpression
 ValueExpression_EDIT
  : 'CURSOR' '*' ValueExpression
    {
-     valueExpressionSuggest(undefined, $2);
-     applyTypeToSuggestions([ 'NUMBER' ]);
+     parser.valueExpressionSuggest(undefined, $2);
+     parser.applyTypeToSuggestions([ 'NUMBER' ]);
      $$ = { types: [ 'NUMBER' ], typeSet: true };
    }
  | 'CURSOR' 'ARITHMETIC_OPERATOR' ValueExpression
    {
-     valueExpressionSuggest(undefined, $2);
-     applyTypeToSuggestions([ 'NUMBER' ]);
+     parser.valueExpressionSuggest(undefined, $2);
+     parser.applyTypeToSuggestions([ 'NUMBER' ]);
      $$ = { types: [ 'NUMBER' ], typeSet: true };
    }
  | ValueExpression_EDIT '-' ValueExpression
    {
      if (!$1.typeSet) {
-       applyTypeToSuggestions(['NUMBER']);
-       addColRefIfExists($3);
+       parser.applyTypeToSuggestions(['NUMBER']);
+       parser.addColRefIfExists($3);
      }
      $$ = { types: [ 'NUMBER' ] }
    }
  | ValueExpression_EDIT '*' ValueExpression
    {
      if (!$1.typeSet) {
-       applyTypeToSuggestions(['NUMBER']);
-       addColRefIfExists($3);
+       parser.applyTypeToSuggestions(['NUMBER']);
+       parser.addColRefIfExists($3);
      }
      $$ = { types: [ 'NUMBER' ] }
    }
  | ValueExpression_EDIT 'ARITHMETIC_OPERATOR' ValueExpression
    {
      if (!$1.typeSet) {
-       applyTypeToSuggestions(['NUMBER']);
-       addColRefIfExists($3);
+       parser.applyTypeToSuggestions(['NUMBER']);
+       parser.addColRefIfExists($3);
      }
      $$ = { types: [ 'NUMBER' ] }
    }
  | ValueExpression '-' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest(undefined, $2);
-     applyTypeToSuggestions(['NUMBER']);
+     parser.valueExpressionSuggest(undefined, $2);
+     parser.applyTypeToSuggestions(['NUMBER']);
      $$ = { types: [ 'NUMBER' ], typeSet: true };
    }
  | ValueExpression '*' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest(undefined, $2);
-     applyTypeToSuggestions(['NUMBER']);
+     parser.valueExpressionSuggest(undefined, $2);
+     parser.applyTypeToSuggestions(['NUMBER']);
      $$ = { types: [ 'NUMBER' ], typeSet: true };
    }
  | ValueExpression 'ARITHMETIC_OPERATOR' PartialBacktickedOrAnyCursor
    {
-     valueExpressionSuggest(undefined, $2);
-     applyTypeToSuggestions(['NUMBER']);
+     parser.valueExpressionSuggest(undefined, $2);
+     parser.applyTypeToSuggestions(['NUMBER']);
      $$ = { types: [ 'NUMBER' ], typeSet: true };
    }
  | ValueExpression '-' ValueExpression_EDIT
    {
      if (!$3.typeSet) {
-       applyTypeToSuggestions(['NUMBER']);
-       addColRefIfExists($1);
+       parser.applyTypeToSuggestions(['NUMBER']);
+       parser.addColRefIfExists($1);
      }
      $$ = { types: [ 'NUMBER' ] };
    }
  | ValueExpression '*' ValueExpression_EDIT
    {
      if (!$3.typeSet) {
-       applyTypeToSuggestions(['NUMBER']);
-       addColRefIfExists($1);
+       parser.applyTypeToSuggestions(['NUMBER']);
+       parser.addColRefIfExists($1);
      }
      $$ = { types: [ 'NUMBER' ] };
    }
  | ValueExpression 'ARITHMETIC_OPERATOR' ValueExpression_EDIT
    {
      if (!$3.typeSet) {
-       applyTypeToSuggestions(['NUMBER']);
-       addColRefIfExists($1);
+       parser.applyTypeToSuggestions(['NUMBER']);
+       parser.addColRefIfExists($1);
      }
      $$ = { types: [ 'NUMBER' ] };
    }
@@ -548,20 +548,20 @@ LikeRightPart_EDIT
  | 'REGEXP' ValueExpression_EDIT
  | 'LIKE' PartialBacktickedOrCursor
    {
-     suggestFunctions({ types: [ 'STRING' ] });
-     suggestColumns({ types: [ 'STRING' ] });
+     parser.suggestFunctions({ types: [ 'STRING' ] });
+     parser.suggestColumns({ types: [ 'STRING' ] });
      $$ = { types: ['BOOLEAN'] }
    }
  | 'RLIKE' PartialBacktickedOrCursor
    {
-     suggestFunctions({ types: [ 'STRING' ] });
-     suggestColumns({ types: [ 'STRING' ] });
+     parser.suggestFunctions({ types: [ 'STRING' ] });
+     parser.suggestColumns({ types: [ 'STRING' ] });
      $$ = { types: ['BOOLEAN'] }
    }
  | 'REGEXP' PartialBacktickedOrCursor
    {
-     suggestFunctions({ types: [ 'STRING' ] });
-     suggestColumns({ types: [ 'STRING' ] });
+     parser.suggestFunctions({ types: [ 'STRING' ] });
+     parser.suggestColumns({ types: [ 'STRING' ] });
      $$ = { types: ['BOOLEAN'] }
    }
  ;
@@ -573,14 +573,14 @@ ValueExpression_EDIT
  | ValueExpression 'NOT' LikeRightPart_EDIT         -> { types: [ 'BOOLEAN' ] }
  | 'CURSOR' LikeRightPart
    {
-     valueExpressionSuggest(undefined, $2);
-     applyTypeToSuggestions([ 'STRING' ]);
+     parser.valueExpressionSuggest(undefined, $2);
+     parser.applyTypeToSuggestions([ 'STRING' ]);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true };
    }
  | 'CURSOR' 'NOT' LikeRightPart
    {
-     valueExpressionSuggest(undefined, $2 + ' ' + $3);
-     applyTypeToSuggestions([ 'STRING' ]);
+     parser.valueExpressionSuggest(undefined, $2 + ' ' + $3);
+     parser.applyTypeToSuggestions([ 'STRING' ]);
      $$ = { types: [ 'BOOLEAN' ], typeSet: true };
    }
  ;
@@ -596,14 +596,14 @@ ValueExpression_EDIT
  : 'CASE' CaseRightPart_EDIT                         -> $2
  | 'CASE' 'CURSOR' EndOrError
    {
-     valueExpressionSuggest();
-     suggestKeywords(['WHEN']);
+     parser.valueExpressionSuggest();
+     parser.suggestKeywords(['WHEN']);
      $$ = { types: [ 'T' ], typeSet: true };
    }
  | 'CASE' ValueExpression CaseRightPart_EDIT         -> $3
  | 'CASE' ValueExpression 'CURSOR' EndOrError
    {
-     suggestValueExpressionKeywords($2, ['WHEN']);
+     parser.suggestValueExpressionKeywords($2, ['WHEN']);
      $$ = { types: [ 'T' ], typeSet: true };
    }
  | 'CASE' ValueExpression_EDIT CaseRightPart         -> $3
@@ -612,71 +612,71 @@ ValueExpression_EDIT
  ;
 
 CaseRightPart
- : CaseWhenThenList 'END'                         -> findCaseType($1)
+ : CaseWhenThenList 'END'                         -> parser.findCaseType($1)
  | CaseWhenThenList 'ELSE' ValueExpression 'END'
    {
      $1.caseTypes.push($3);
-     $$ = findCaseType($1);
+     $$ = parser.findCaseType($1);
    }
  ;
 
 CaseRightPart_EDIT
- : CaseWhenThenList_EDIT EndOrError                            -> findCaseType($1)
+ : CaseWhenThenList_EDIT EndOrError                            -> parser.findCaseType($1)
  | CaseWhenThenList 'ELSE' ValueExpression 'CURSOR'
    {
-     suggestValueExpressionKeywords($3, ['END']);
+     parser.suggestValueExpressionKeywords($3, ['END']);
      $1.caseTypes.push($3);
-     $$ = findCaseType($1);
+     $$ = parser.findCaseType($1);
    }
  | CaseWhenThenList_EDIT 'ELSE' ValueExpression EndOrError
    {
      $1.caseTypes.push($3);
-     $$ = findCaseType($1);
+     $$ = parser.findCaseType($1);
    }
- | CaseWhenThenList_EDIT 'ELSE' EndOrError                      -> findCaseType($1)
+ | CaseWhenThenList_EDIT 'ELSE' EndOrError                      -> parser.findCaseType($1)
  | CaseWhenThenList 'CURSOR' ValueExpression EndOrError
    {
      if ($4.toLowerCase() !== 'end') {
-       suggestValueExpressionKeywords($1, [{ value: 'END', weight: 3 }, { value: 'ELSE', weight: 2 }, { value: 'WHEN', weight: 1 }]);
+       parser.suggestValueExpressionKeywords($1, [{ value: 'END', weight: 3 }, { value: 'ELSE', weight: 2 }, { value: 'WHEN', weight: 1 }]);
      } else {
-       suggestValueExpressionKeywords($1, [{ value: 'ELSE', weight: 2 }, { value: 'WHEN', weight: 1 }]);
+       parser.suggestValueExpressionKeywords($1, [{ value: 'ELSE', weight: 2 }, { value: 'WHEN', weight: 1 }]);
      }
-     $$ = findCaseType($1);
+     $$ = parser.findCaseType($1);
    }
  | CaseWhenThenList 'CURSOR' EndOrError
    {
      if ($3.toLowerCase() !== 'end') {
-       suggestValueExpressionKeywords($1, [{ value: 'END', weight: 3 }, { value: 'ELSE', weight: 2 }, { value: 'WHEN', weight: 1 }]);
+       parser.suggestValueExpressionKeywords($1, [{ value: 'END', weight: 3 }, { value: 'ELSE', weight: 2 }, { value: 'WHEN', weight: 1 }]);
      } else {
-       suggestValueExpressionKeywords($1, [{ value: 'ELSE', weight: 2 }, { value: 'WHEN', weight: 1 }]);
+       parser.suggestValueExpressionKeywords($1, [{ value: 'ELSE', weight: 2 }, { value: 'WHEN', weight: 1 }]);
      }
-     $$ = findCaseType($1);
+     $$ = parser.findCaseType($1);
    }
  | CaseWhenThenList 'ELSE' ValueExpression_EDIT EndOrError
    {
      $1.caseTypes.push($3);
-     $$ = findCaseType($1);
+     $$ = parser.findCaseType($1);
    }
  | CaseWhenThenList 'ELSE' 'CURSOR' EndOrError
    {
-     valueExpressionSuggest();
-     $$ = findCaseType($1);
+     parser.valueExpressionSuggest();
+     $$ = parser.findCaseType($1);
    }
  | 'ELSE' 'CURSOR' EndOrError
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { types: [ 'T' ], typeSet: true };
    }
  | 'CURSOR' 'ELSE' ValueExpression EndOrError
    {
-     valueExpressionSuggest();
-     suggestKeywords(['WHEN']);
+     parser.valueExpressionSuggest();
+     parser.suggestKeywords(['WHEN']);
      $$ = $3;
    }
  | 'CURSOR' 'ELSE' EndOrError
    {
-     valueExpressionSuggest();
-     suggestKeywords(['WHEN']);
+     parser.valueExpressionSuggest();
+     parser.suggestKeywords(['WHEN']);
      $$ = { types: [ 'T' ] };
    }
  ;
@@ -701,7 +701,7 @@ CaseWhenThenList_EDIT
  | CaseWhenThenList CaseWhenThenListPartTwo_EDIT CaseWhenThenList
  | CaseWhenThenList 'CURSOR' CaseWhenThenList
    {
-     suggestValueExpressionKeywords($1, ['WHEN']);
+     parser.suggestValueExpressionKeywords($1, ['WHEN']);
    }
  | CaseWhenThenListPartTwo_EDIT CaseWhenThenList                   -> $2
  ;
@@ -718,75 +718,75 @@ CaseWhenThenListPartTwo_EDIT
  | 'WHEN' 'THEN' ValueExpression_EDIT                  -> { caseTypes: [$3] }
  | 'CURSOR' ValueExpression 'THEN'
    {
-     suggestKeywords(['WHEN']);
+     parser.suggestKeywords(['WHEN']);
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'CURSOR' ValueExpression 'THEN' ValueExpression
    {
-     suggestKeywords(['WHEN']);
+     parser.suggestKeywords(['WHEN']);
      $$ = { caseTypes: [$4] };
    }
  | 'CURSOR' 'THEN'
    {
-     valueExpressionSuggest();
-     suggestKeywords(['WHEN']);
+     parser.valueExpressionSuggest();
+     parser.suggestKeywords(['WHEN']);
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'CURSOR' 'THEN' ValueExpression
     {
-      valueExpressionSuggest();
-      suggestKeywords(['WHEN']);
+      parser.valueExpressionSuggest();
+      parser.suggestKeywords(['WHEN']);
       $$ = { caseTypes: [{ types: ['T'] }] };
     }
  | 'WHEN' 'CURSOR'
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'WHEN' 'CURSOR' ValueExpression
    {
-     valueExpressionSuggest();
-     suggestKeywords(['THEN']);
+     parser.valueExpressionSuggest();
+     parser.suggestKeywords(['THEN']);
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'WHEN' 'CURSOR' 'THEN'
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'WHEN' 'CURSOR' 'THEN' ValueExpression
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { caseTypes: [$4] };
    }
  | 'WHEN' ValueExpression 'CURSOR'
    {
-     suggestValueExpressionKeywords($2, ['THEN']);
+     parser.suggestValueExpressionKeywords($2, ['THEN']);
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'WHEN' ValueExpression 'CURSOR' ValueExpression
    {
-     suggestValueExpressionKeywords($2, ['THEN']);
+     parser.suggestValueExpressionKeywords($2, ['THEN']);
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'WHEN' ValueExpression 'THEN' 'CURSOR'
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'WHEN' ValueExpression 'THEN' 'CURSOR' ValueExpression
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'WHEN' 'THEN' 'CURSOR' ValueExpression
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  | 'WHEN' 'THEN' 'CURSOR'
    {
-     valueExpressionSuggest();
+     parser.valueExpressionSuggest();
      $$ = { caseTypes: [{ types: ['T'] }] };
    }
  ;

文件差異過大導致無法顯示
+ 182 - 182
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_valueExpression_dev.jison


文件差異過大導致無法顯示
+ 199 - 199
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js


+ 1453 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlParseSupport.js

@@ -0,0 +1,1453 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var SqlParseSupport = (function() {
+
+  var initSqlParser = function (parser) {
+
+    var SIMPLE_TABLE_REF_SUGGESTIONS = ['suggestJoinConditions', 'suggestAggregateFunctions', 'suggestFilters', 'suggestGroupBys', 'suggestOrderBys'];
+
+    parser.prepareNewStatement = function () {
+      linkTablePrimaries();
+      parser.commitLocations();
+
+      delete parser.yy.lateralViews;
+      delete parser.yy.latestCommonTableExpressions;
+      delete parser.yy.correlatedSubQuery;
+      parser.yy.subQueries = [];
+      parser.yy.selectListAliases = [];
+      parser.yy.latestTablePrimaries = [];
+
+      parser.parseError = function (message, error) {
+        parser.yy.errors.push(error);
+        return message;
+      };
+    };
+
+    parser.addCommonTableExpressions = function (identifiers) {
+      parser.yy.result.commonTableExpressions = identifiers;
+      parser.yy.latestCommonTableExpressions = identifiers;
+    };
+
+    parser.pushQueryState = function () {
+      parser.yy.resultStack.push(parser.yy.result);
+      parser.yy.locationsStack.push(parser.yy.locations);
+      parser.yy.lateralViewsStack.push(parser.yy.lateralViews);
+      parser.yy.selectListAliasesStack.push(parser.yy.selectListAliases);
+      parser.yy.primariesStack.push(parser.yy.latestTablePrimaries);
+      parser.yy.subQueriesStack.push(parser.yy.subQueries);
+
+      parser.yy.result = {};
+      parser.yy.locations = [];
+      parser.yy.selectListAliases = []; // Not allowed in correlated sub-queries
+      parser.yy.lateralViews = []; // Not allowed in correlated sub-queries
+
+      if (parser.yy.correlatedSubQuery) {
+        parser.yy.latestTablePrimaries = parser.yy.latestTablePrimaries.concat();
+        parser.yy.subQueries = parser.yy.subQueries.concat();
+      } else {
+        parser.yy.latestTablePrimaries = [];
+        parser.yy.subQueries = [];
+      }
+    };
+
+    parser.popQueryState = function (subQuery) {
+      linkTablePrimaries();
+      parser.commitLocations();
+
+      if (Object.keys(parser.yy.result).length === 0) {
+        parser.yy.result = parser.yy.resultStack.pop();
+      } else {
+        parser.yy.resultStack.pop();
+      }
+      var oldSubQueries = parser.yy.subQueries;
+      parser.yy.subQueries = parser.yy.subQueriesStack.pop();
+      if (subQuery) {
+        if (oldSubQueries.length > 0) {
+          subQuery.subQueries = oldSubQueries;
+        }
+        parser.yy.subQueries.push(subQuery);
+      }
+
+      parser.yy.lateralViews = parser.yy.lateralViewsStack.pop();
+      parser.yy.latestTablePrimaries = parser.yy.primariesStack.pop();
+      parser.yy.locations = parser.yy.locationsStack.pop();
+      parser.yy.selectListAliases = parser.yy.selectListAliasesStack.pop();
+    };
+
+    parser.suggestSelectListAliases = function () {
+      if (parser.yy.selectListAliases && parser.yy.selectListAliases.length > 0 && parser.yy.result.suggestColumns
+        && (typeof parser.yy.result.suggestColumns.identifierChain === 'undefined' || parser.yy.result.suggestColumns.identifierChain.length === 0)) {
+        parser.yy.result.suggestColumnAliases = parser.yy.selectListAliases;
+      }
+    };
+
+    parser.isHive = function () {
+      return parser.yy.activeDialect === 'hive';
+    };
+
+    parser.isImpala = function () {
+      return parser.yy.activeDialect === 'impala';
+    };
+
+    parser.mergeSuggestKeywords = function () {
+      var result = [];
+      Array.prototype.slice.call(arguments).forEach(function (suggestion) {
+        if (typeof suggestion !== 'undefined' && typeof suggestion.suggestKeywords !== 'undefined') {
+          result = result.concat(suggestion.suggestKeywords);
+        }
+      });
+      if (result.length > 0) {
+        return {suggestKeywords: result};
+      }
+      return {};
+    };
+
+    parser.suggestValueExpressionKeywords = function (valueExpression, extras) {
+      var expressionKeywords = parser.getValueExpressionKeywords(valueExpression, extras);
+      parser.suggestKeywords(expressionKeywords.suggestKeywords);
+      if (expressionKeywords.suggestColRefKeywords) {
+        parser.suggestColRefKeywords(expressionKeywords.suggestColRefKeywords);
+      }
+      if (valueExpression.lastType) {
+        parser.addColRefIfExists(valueExpression.lastType);
+      } else {
+        parser.addColRefIfExists(valueExpression);
+      }
+    };
+
+    parser.getValueExpressionKeywords = function (valueExpression, extras) {
+      var types = valueExpression.lastType ? valueExpression.lastType.types : valueExpression.types;
+      // We could have valueExpression.columnReference to suggest based on column type
+      var keywords = ['<', '<=', '<>', '=', '>', '>=', 'BETWEEN', 'IN', 'IS NOT NULL', 'IS NULL', 'NOT BETWEEN', 'NOT IN'];
+      if (parser.isHive()) {
+        keywords.push('<=>');
+      }
+      if (extras) {
+        keywords = keywords.concat(extras);
+      }
+      if (valueExpression.suggestKeywords) {
+        keywords = keywords.concat(valueExpression.suggestKeywords);
+      }
+      if (types.length === 1 && types[0] === 'COLREF') {
+        return {
+          suggestKeywords: keywords,
+          suggestColRefKeywords: {
+            BOOLEAN: ['AND', 'OR'],
+            NUMBER: ['+', '-', '*', '/', '%'],
+            STRING: ['LIKE', 'NOT LIKE', 'REGEX', 'RLIKE']
+          }
+        }
+      }
+      if (SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
+        keywords = keywords.concat(['AND', 'OR']);
+      }
+      if (SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
+        keywords = keywords.concat(['+', '-', '*', '/', '%']);
+      }
+      if (SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)) {
+        keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEX', 'RLIKE']);
+      }
+      return {suggestKeywords: keywords};
+    };
+
+    parser.getTypeKeywords = function () {
+      if (parser.isHive()) {
+        return ['BIGINT', 'BINARY', 'BOOLEAN', 'CHAR', 'DATE', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
+      }
+      if (parser.isImpala()) {
+        return ['BIGINT', 'BOOLEAN', 'CHAR', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'REAL', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
+      }
+      return ['BIGINT', 'BOOLEAN', 'CHAR', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
+    };
+
+    parser.getColumnDataTypeKeywords = function () {
+      if (parser.isHive()) {
+        return parser.getTypeKeywords().concat(['ARRAY<>', 'MAP<>', 'STRUCT<>', 'UNIONTYPE<>']);
+      }
+      return parser.getTypeKeywords();
+    };
+
+    parser.addColRefIfExists = function (valueExpression) {
+      if (valueExpression.columnReference) {
+        parser.yy.result.colRef = {identifierChain: valueExpression.columnReference};
+      }
+    };
+
+    parser.selectListNoTableSuggest = function (selectListEdit, hasDistinctOrAll) {
+      if (selectListEdit.cursorAtStart) {
+        var keywords = [];
+        if (hasDistinctOrAll) {
+          keywords = [{ value: '*', weight: 1000 }];
+        } else {
+          keywords = [{ value: '*', weight: 1000 }, 'ALL', 'DISTINCT'];
+        }
+        if (parser.isImpala()) {
+          keywords.push('STRAIGHT_JOIN');
+        }
+        parser.suggestKeywords(keywords);
+      } else {
+        parser.checkForKeywords(selectListEdit);
+      }
+      if (selectListEdit.suggestFunctions) {
+        parser.suggestFunctions();
+      }
+      if (selectListEdit.suggestColumns) {
+        parser.suggestColumns();
+      }
+      if (selectListEdit.suggestAggregateFunctions && (!hasDistinctOrAll || hasDistinctOrAll === 'ALL')) {
+        parser.suggestAggregateFunctions();
+        parser.suggestAnalyticFunctions();
+      }
+    };
+
+    parser.suggestJoinConditions = 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();
+      }
+    };
+
+    parser.suggestJoins = function (details) {
+      parser.yy.result.suggestJoins = details || {};
+    };
+
+    parser.valueExpressionSuggest = function (oppositeValueExpression, operator) {
+      if (oppositeValueExpression && oppositeValueExpression.columnReference) {
+        parser.suggestValues();
+        parser.yy.result.colRef = {identifierChain: oppositeValueExpression.columnReference};
+      }
+      parser.suggestColumns();
+      parser.suggestFunctions();
+      var keywords = ['CASE'];
+      if (parser.isHive() || typeof oppositeValueExpression === 'undefined' || typeof operator === 'undefined') {
+        keywords = keywords.concat(['EXISTS', 'NOT']);
+      }
+      if (oppositeValueExpression && oppositeValueExpression.types[0] === 'NUMBER') {
+        parser.applyTypeToSuggestions(['NUMBER']);
+      } else if (parser.isImpala() && (typeof operator === 'undefined' || operator === '-' || operator === '+')) {
+        keywords.push('INTERVAL');
+      }
+      parser.suggestKeywords(keywords);
+    };
+
+    parser.applyTypeToSuggestions = function (types) {
+      if (types[0] === 'BOOLEAN') {
+        return;
+      }
+      if (parser.yy.result.suggestFunctions && !parser.yy.result.suggestFunctions.types) {
+        parser.yy.result.suggestFunctions.types = types;
+      }
+      if (parser.yy.result.suggestColumns && !parser.yy.result.suggestColumns.types) {
+        parser.yy.result.suggestColumns.types = types;
+      }
+    };
+
+    parser.findCaseType = function (whenThenList) {
+      var types = {};
+      whenThenList.caseTypes.forEach(function (valueExpression) {
+        valueExpression.types.forEach(function (type) {
+          types[type] = true;
+        });
+      });
+      if (Object.keys(types).length === 1) {
+        return {types: [Object.keys(types)[0]]};
+      }
+      return {types: ['T']};
+    };
+
+    parser.findReturnTypes = function (functionName) {
+      return SqlFunctions.getReturnTypes(parser.yy.activeDialect, functionName.toLowerCase());
+    };
+
+    parser.applyArgumentTypesToSuggestions = function (functionName, position) {
+      var foundArguments = SqlFunctions.getArgumentTypes(parser.yy.activeDialect, functionName.toLowerCase(), position);
+      if (foundArguments.length == 0 && parser.yy.result.suggestColumns) {
+        delete parser.yy.result.suggestColumns;
+        delete parser.yy.result.suggestKeyValues;
+        delete parser.yy.result.suggestValues;
+        delete parser.yy.result.suggestFunctions;
+        delete parser.yy.result.suggestIdentifiers;
+        delete parser.yy.result.suggestKeywords;
+      } else {
+        parser.applyTypeToSuggestions(foundArguments);
+      }
+    };
+
+    parser.commitLocations = function () {
+      var i = parser.yy.locations.length;
+      while (i--) {
+        var location = parser.yy.locations[i];
+
+        // Impala can have references to previous tables after FROM, i.e. FROM testTable t, t.testArray
+        // In this testArray would be marked a type table so we need to switch it to column.
+        if (location.type === 'table' && typeof location.identifierChain !== 'undefined' && location.identifierChain.length > 1 && parser.yy.latestTablePrimaries) {
+          var found = parser.yy.latestTablePrimaries.filter(function (primary) {
+            return primary.alias === location.identifierChain[0].name;
+          });
+          if (found.length > 0) {
+            location.type = 'column';
+          }
+        }
+
+        if (location.type === 'database' && parser.yy.latestTablePrimaries) {
+          var foundAlias = parser.yy.latestTablePrimaries.filter(function (primary) {
+            return primary.alias === location.identifierChain[0].name;
+          });
+          if (foundAlias.length > 0) {
+            // Impala complex reference in FROM clause, i.e. FROM testTable t, t.testMap tm
+            location.type = 'table';
+            parser.expandIdentifierChain(location, true);
+          }
+        }
+
+        if (location.type === 'unknown') {
+          if (typeof location.identifierChain !== 'undefined' && location.identifierChain.length <= 2 && parser.yy.latestTablePrimaries) {
+            var found = parser.yy.latestTablePrimaries.filter(function (primary) {
+              return primary.alias === location.identifierChain[0].name || (primary.identifierChain && primary.identifierChain[0].name === location.identifierChain[0].name);
+            });
+            if (found.length > 0) {
+              if (found[0].identifierChain.length > 1 && location.identifierChain.length === 1 && found[0].identifierChain[0].name === location.identifierChain[0].name) {
+                location.type = 'database';
+              } else {
+                location.type = 'table';
+                parser.expandIdentifierChain(location, true);
+              }
+            } else {
+              if (parser.yy.subQueries) {
+                found = parser.yy.subQueries.filter(function (subQuery) {
+                  return subQuery.alias === location.identifierChain[0].name;
+                });
+                if (found.length > 0) {
+                  location.type = 'subQuery';
+                  location.identifierChain = [{ subQuery: found[0].alias }];
+                }
+              }
+            }
+          }
+        }
+
+        if (location.type === 'asterisk' && !location.linked) {
+          if (parser.yy.latestTablePrimaries && parser.yy.latestTablePrimaries.length > 0) {
+            location.tables = [];
+            location.linked = false;
+            parser.expandIdentifierChain(location, true);
+            if (location.tables.length === 0) {
+              parser.yy.locations.splice(i, 1);
+            }
+          } else {
+            parser.yy.locations.splice(i, 1);
+          }
+        }
+
+        if (location.type === 'unknown') {
+          location.type = 'column';
+        }
+        if (location.type === 'column') {
+          if (parser.isHive() && !location.linked) {
+            location.identifierChain = parser.expandLateralViews(parser.yy.lateralViews, location.identifierChain);
+          }
+          parser.expandIdentifierChain(location, true);
+        }
+
+        if (location.type === 'table' && (typeof location.identifierChain === 'undefined' || location.identifierChain.length === 0)) {
+          parser.yy.locations.splice(i, 1);
+        }
+        if (location.type === 'column') {
+          if (typeof location.identifierChain === 'undefined') {
+            parser.yy.locations.splice(i, 1);
+          } else if (location.identifierChain.length < 2) {
+            location.tables = [];
+            location.linked = false;
+            parser.expandIdentifierChain(location, true);
+            if (location.tables.length === 0) {
+              parser.yy.locations.splice(i, 1);
+            }
+          }
+        }
+      }
+      if (parser.yy.locations.length > 0) {
+        parser.yy.allLocations = parser.yy.allLocations.concat(parser.yy.locations);
+        parser.yy.locations = [];
+      }
+    };
+
+    var prioritizeSuggestions = function () {
+      parser.yy.result.lowerCase = parser.yy.lowerCase || false;
+
+      var cteIndex = {};
+
+      if (typeof parser.yy.latestCommonTableExpressions !== 'undefined') {
+        parser.yy.latestCommonTableExpressions.forEach(function (cte) {
+          cteIndex[cte.alias.toLowerCase()] = cte;
+        })
+      }
+
+      SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) {
+        if (suggestionType !== 'suggestAggregateFunctions' && typeof parser.yy.result[suggestionType] !== 'undefined' && parser.yy.result[suggestionType].tables.length === 0) {
+          delete parser.yy.result[suggestionType];
+        } else if (typeof parser.yy.result[suggestionType] !== 'undefined' && typeof parser.yy.result[suggestionType].tables !== 'undefined') {
+          for (var i = parser.yy.result[suggestionType].tables.length - 1; i >= 0; i--) {
+            var table = parser.yy.result[suggestionType].tables[i];
+            if (table.identifierChain.length === 1 && typeof table.identifierChain[0].name !== 'undefined' && typeof cteIndex[table.identifierChain[0].name] !== 'undefined') {
+              parser.yy.result[suggestionType].tables.splice(i, 1);
+            }
+          }
+        }
+      });
+
+      if (typeof parser.yy.result.colRef !== 'undefined') {
+        if (!parser.yy.result.colRef.linked || typeof parser.yy.result.colRef.identifierChain === 'undefined' || parser.yy.result.colRef.identifierChain.length === 0) {
+          delete parser.yy.result.colRef;
+          if (typeof parser.yy.result.suggestColRefKeywords !== 'undefined') {
+            Object.keys(parser.yy.result.suggestColRefKeywords).forEach(function (type) {
+              parser.yy.result.suggestKeywords = parser.yy.result.suggestKeywords.concat(parser.createWeightedKeywords(parser.yy.result.suggestColRefKeywords[type], -1));
+            });
+            delete parser.yy.result.suggestColRefKeywords;
+          }
+          if (parser.yy.result.suggestColumns && parser.yy.result.suggestColumns.types.length === 1 && parser.yy.result.suggestColumns.types[0] === 'COLREF') {
+            parser.yy.result.suggestColumns.types = ['T'];
+          }
+          delete parser.yy.result.suggestValues;
+        }
+      }
+
+      if (typeof parser.yy.result.colRef !== 'undefined') {
+        if (!parser.yy.result.suggestValues && !parser.yy.result.suggestColRefKeywords &&
+          (!parser.yy.result.suggestColumns ||
+          parser.yy.result.suggestColumns.types[0] !== 'COLREF')) {
+          delete parser.yy.result.colRef;
+        }
+      }
+      if (typeof parser.yy.result.suggestIdentifiers !== 'undefined' && parser.yy.result.suggestIdentifiers.length > 0) {
+        delete parser.yy.result.suggestTables;
+        delete parser.yy.result.suggestDatabases;
+      }
+      if (typeof parser.yy.result.suggestColumns !== 'undefined') {
+        var suggestColumns = parser.yy.result.suggestColumns;
+        if (typeof suggestColumns.tables === 'undefined' || suggestColumns.tables.length === 0) {
+          // Impala supports statements like SELECT * FROM tbl1, tbl2 WHERE db.tbl1.col = tbl2.bla
+          if (parser.yy.result.suggestColumns.linked && parser.isImpala() && typeof suggestColumns.identifierChain !== 'undefined' && suggestColumns.identifierChain.length > 0) {
+            if (suggestColumns.identifierChain.length === 1) {
+              parser.yy.result.suggestTables = suggestColumns;
+              delete parser.yy.result.suggestColumns
+            } else {
+              suggestColumns.tables = [{ identifierChain: suggestColumns.identifierChain }];
+              delete suggestColumns.identifierChain;
+            }
+          } else {
+            delete parser.yy.result.suggestColumns;
+            delete parser.yy.result.subQueries;
+          }
+        } else {
+          delete parser.yy.result.suggestTables;
+          delete parser.yy.result.suggestDatabases;
+
+          suggestColumns.tables.forEach(function (table) {
+            if (typeof table.identifierChain !== 'undefined' && table.identifierChain.length === 1 && typeof table.identifierChain[0].name !== 'undefined') {
+              var cte = cteIndex[table.identifierChain[0].name.toLowerCase()];
+              if (typeof cte !== 'undefined') {
+                delete table.identifierChain[0].name;
+                table.identifierChain[0].cte = cte.alias;
+              }
+            }
+          });
+
+          if (typeof suggestColumns.identifierChain !== 'undefined') {
+            delete suggestColumns.identifierChain;
+          }
+        }
+      } else {
+        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 (cte) {
+          var suggestion = { name: cte.alias };
+          if (parser.yy.result.suggestTables.prependFrom) {
+            suggestion.prependFrom = true
+          }
+          if (parser.yy.result.suggestTables.prependQuestionMark) {
+            suggestion.prependQuestionMark = true;
+          }
+          ctes.push(suggestion);
+        });
+        if (ctes.length > 0) {
+          parser.yy.result.suggestCommonTableExpressions = ctes;
+        }
+      }
+    };
+
+    /**
+     * Impala supports referencing maps and arrays in the the table reference list i.e.
+     *
+     *  SELECT m['foo'].bar.| FROM someDb.someTable t, t.someMap m;
+     *
+     * From this the tablePrimaries would look like:
+     *
+     * [ { alias: 't', identifierChain: [ { name: 'someDb' }, { name: 'someTable' } ] },
+     *   { alias: 'm', identifierChain: [ { name: 't' }, { name: 'someMap' } ] } ]
+     *
+     * with an identifierChain from the select list:
+     *
+     * [ { name: 'm', keySet: true }, { name: 'bar' } ]
+     *
+     * Calling this would return an expanded identifierChain, given the above it would be:
+     *
+     * [ { name: 't' }, { name: 'someMap', keySet: true }, { name: 'bar' } ]
+     */
+    parser.expandImpalaIdentifierChain = function (tablePrimaries, identifierChain) {
+      var expandedChain = identifierChain.concat(); // Clone in case it's called multiple times.
+      if (typeof expandedChain === 'undefined' || expandedChain.length === 0) {
+        return identifierChain;
+      }
+      var expand = function (identifier, expandedChain) {
+        var foundPrimary = tablePrimaries.filter(function (tablePrimary) {
+          return tablePrimary.alias === identifier;
+        });
+
+        if (foundPrimary.length === 1 && foundPrimary[0].identifierChain) {
+          var parentPrimary = tablePrimaries.filter(function (tablePrimary) {
+            return tablePrimary.alias === foundPrimary[0].identifierChain[0].name;
+          });
+          if (parentPrimary.length === 1) {
+            var keySet = expandedChain[0].keySet;
+            var secondPart = expandedChain.slice(1);
+            var firstPart = [];
+            // Clone to make sure we don't add keySet to the primaries
+            foundPrimary[0].identifierChain.forEach(function (identifier) {
+              firstPart.push({name: identifier.name});
+            });
+            if (keySet && firstPart.length > 0) {
+              firstPart[firstPart.length - 1].keySet = true;
+            }
+
+            if (firstPart.length === 0 || typeof secondPart === 'undefined' || secondPart.length === 0) {
+              return firstPart;
+            }
+            var result = firstPart.concat(secondPart);
+            if (result.length > 0) {
+              return expand(firstPart[0].name, result);
+            } else {
+              return result;
+            }
+          }
+        }
+        return expandedChain;
+      };
+      return expand(expandedChain[0].name, expandedChain);
+    };
+
+    parser.identifyPartials = function (beforeCursor, afterCursor) {
+      var beforeMatch = beforeCursor.match(/[0-9a-zA-Z_]*$/);
+      var afterMatch = afterCursor.match(/^[0-9a-zA-Z_]*(?:\((?:[^)]*\))?)?/);
+      return {left: beforeMatch ? beforeMatch[0].length : 0, right: afterMatch ? afterMatch[0].length : 0};
+    };
+
+    parser.expandLateralViews = function (lateralViews, originalIdentifierChain, columnSuggestion) {
+      var identifierChain = originalIdentifierChain.concat(); // Clone in case it's re-used
+      var firstIdentifier = identifierChain[0];
+      if (typeof lateralViews !== 'undefined') {
+        lateralViews.concat().reverse().forEach(function (lateralView) {
+          if (!lateralView.udtf.expression.columnReference) {
+            return;
+          }
+          if (firstIdentifier.name === lateralView.tableAlias && identifierChain.length > 1) {
+            identifierChain.shift();
+            firstIdentifier = identifierChain[0];
+            if (columnSuggestion) {
+              delete parser.yy.result.suggestKeywords;
+            }
+          } else if (firstIdentifier.name === lateralView.tableAlias && identifierChain.length === 1 && typeof parser.yy.result.suggestColumns !== 'undefined') {
+            if (columnSuggestion) {
+              if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
+                parser.yy.result.suggestIdentifiers = [];
+              }
+              lateralView.columnAliases.forEach(function (columnAlias) {
+                parser.yy.result.suggestIdentifiers.push({name: columnAlias, type: 'alias'});
+              });
+              delete parser.yy.result.suggestColumns;
+              delete parser.yy.result.suggestKeywords;
+            }
+            return identifierChain;
+          }
+          if (lateralView.columnAliases.indexOf(firstIdentifier.name) !== -1) {
+            if (lateralView.columnAliases.length === 2 && lateralView.udtf.function.toLowerCase() === 'explode' && firstIdentifier.name === lateralView.columnAliases[0]) {
+              identifierChain[0] = {name: 'key'};
+            } else if (lateralView.columnAliases.length === 2 && lateralView.udtf.function.toLowerCase() === 'explode' && firstIdentifier.name === lateralView.columnAliases[1]) {
+              identifierChain[0] = {name: 'value'};
+            } else {
+              identifierChain[0] = {name: 'item'};
+            }
+            identifierChain = lateralView.udtf.expression.columnReference.concat(identifierChain);
+            firstIdentifier = identifierChain[0];
+          }
+        });
+      }
+      return identifierChain;
+    };
+
+    var addCleanTablePrimary = function (tables, tablePrimary) {
+      if (tablePrimary.alias) {
+        tables.push({ alias: tablePrimary.alias, identifierChain: tablePrimary.identifierChain });
+      } else {
+        tables.push({ identifierChain: tablePrimary.identifierChain });
+      }
+    };
+
+    parser.expandIdentifierChain = function (wrapper, anyOwner) {
+      if (typeof wrapper.identifierChain === 'undefined' || typeof parser.yy.latestTablePrimaries === 'undefined') {
+        return;
+      }
+
+      var identifierChain = wrapper.identifierChain.concat();
+      var tablePrimaries = parser.yy.latestTablePrimaries;
+
+      if (tablePrimaries.length === 0) {
+        delete wrapper.identifierChain;
+        return;
+      }
+
+      if (identifierChain.length > 0 && identifierChain[identifierChain.length - 1].asterisk) {
+        var tables = [];
+        tablePrimaries.forEach(function (tablePrimary) {
+          if (identifierChain.length > 1 && !tablePrimary.subQueryAlias) {
+            if (identifierChain.length === 2 && tablePrimary.alias === identifierChain[0].name) {
+              addCleanTablePrimary(tables, tablePrimary);
+            } else if (identifierChain.length === 2 && tablePrimary.identifierChain[0].name === identifierChain[0].name) {
+              addCleanTablePrimary(tables, tablePrimary);
+            } else if (identifierChain.length === 3 && tablePrimary.identifierChain.length > 1 &&
+              tablePrimary.identifierChain[0].name === identifierChain[0].name &&
+              tablePrimary.identifierChain[1].name === identifierChain[1].name) {
+              addCleanTablePrimary(tables, tablePrimary);
+            }
+          } else {
+            if (tablePrimary.subQueryAlias) {
+              tables.push({ identifierChain: [{ subQuery: tablePrimary.subQueryAlias }]});
+            } else {
+              addCleanTablePrimary(tables, tablePrimary);
+            }
+          }
+        });
+        // Possible Joins
+        if (tables.length > 0) {
+          wrapper.tables = tables;
+          delete wrapper.identifierChain;
+          return;
+        }
+      }
+
+      if (!anyOwner) {
+        tablePrimaries = filterTablePrimariesForOwner(wrapper.owner);
+      }
+      // Impala can have references to maps or array, i.e. FROM table t, t.map m
+      // We need to replace those in the identifierChain
+      if (parser.isImpala()) {
+        var lengthBefore = identifierChain.length;
+        identifierChain = parser.expandImpalaIdentifierChain(tablePrimaries, identifierChain);
+        // Change type of any locations marked as table
+        if (wrapper.type === 'table' && identifierChain.length > lengthBefore) {
+          wrapper.type = 'column';
+        }
+        wrapper.identifierChain = identifierChain;
+      }
+      // Expand exploded views in the identifier chain
+      if (parser.isHive() && identifierChain.length > 0) {
+        identifierChain = parser.expandLateralViews(parser.yy.lateralViews, identifierChain);
+        wrapper.identifierChain = identifierChain;
+      }
+
+      // IdentifierChain contains a possibly started identifier or empty, example: a.b.c = ['a', 'b', 'c']
+      // Reduce the tablePrimaries to the one that matches the first identifier if found
+      var foundPrimary;
+      var doubleMatch = false;
+      if (identifierChain.length > 0) {
+        for (var i = 0; i < tablePrimaries.length; i++) {
+          if (tablePrimaries[i].subQueryAlias) {
+            if (tablePrimaries[i].subQueryAlias === identifierChain[0].name) {
+              foundPrimary = tablePrimaries[i];
+            }
+          } else if (tablePrimaries[i].alias === identifierChain[0].name) {
+            foundPrimary = tablePrimaries[i];
+            break;
+          } else if (tablePrimaries[i].identifierChain.length > 1 && identifierChain.length > 1 &&
+            tablePrimaries[i].identifierChain[0].name === identifierChain[0].name &&
+            tablePrimaries[i].identifierChain[1].name === identifierChain[1].name) {
+            foundPrimary = tablePrimaries[i];
+            doubleMatch = true;
+            break;
+          } else if (!foundPrimary && tablePrimaries[i].identifierChain[0].name === identifierChain[0].name) {
+            foundPrimary = tablePrimaries[i];
+            // No break as first two can still match.
+          } else if (!foundPrimary && tablePrimaries[i].identifierChain.length > 1
+            && tablePrimaries[i].identifierChain[tablePrimaries[i].identifierChain.length - 1].name === identifierChain[0].name) {
+            // This is for the case SELECT baa. FROM bla.baa, blo.boo;
+            foundPrimary = tablePrimaries[i];
+            break;
+          }
+        }
+      }
+
+      if (foundPrimary) {
+        identifierChain.shift();
+        if (doubleMatch) {
+          identifierChain.shift();
+        }
+      } else if (tablePrimaries.length === 1) {
+        foundPrimary = tablePrimaries[0];
+      }
+
+      if (foundPrimary) {
+        if (foundPrimary.subQueryAlias) {
+          identifierChain.unshift({ subQuery: foundPrimary.subQueryAlias });
+        } else {
+          identifierChain = foundPrimary.identifierChain.concat(identifierChain);
+        }
+        if (wrapper.tables) {
+          wrapper.tables.push({ identifierChain: identifierChain });
+          delete wrapper.identifierChain;
+        } else {
+          wrapper.identifierChain = identifierChain;
+        }
+      } else {
+        tablePrimaries.forEach(function (tablePrimary) {
+          var targetTable = { identifierChain: tablePrimary.identifierChain };
+          if (tablePrimary.alias) {
+            targetTable.alias = tablePrimary.alias;
+          }
+          if (wrapper.tables) {
+            wrapper.tables.push(targetTable)
+          }
+        });
+      }
+
+      delete wrapper.owner;
+      wrapper.linked = true;
+    };
+
+    var suggestLateralViewAliasesAsIdentifiers = function () {
+      if (typeof parser.yy.lateralViews === 'undefined' || parser.yy.lateralViews.length === 0) {
+        return;
+      }
+      if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
+        parser.yy.result.suggestIdentifiers = [];
+      }
+      parser.yy.lateralViews.forEach(function (lateralView) {
+        if (typeof lateralView.tableAlias !== 'undefined') {
+          parser.yy.result.suggestIdentifiers.push({name: lateralView.tableAlias + '.', type: 'alias'});
+        }
+        lateralView.columnAliases.forEach(function (columnAlias) {
+          parser.yy.result.suggestIdentifiers.push({name: columnAlias, type: 'alias'});
+        });
+      });
+      if (parser.yy.result.suggestIdentifiers.length === 0) {
+        delete parser.yy.result.suggestIdentifiers;
+      }
+    };
+
+    var filterTablePrimariesForOwner = function (owner) {
+      var result = [];
+      parser.yy.latestTablePrimaries.forEach(function (primary) {
+        if (typeof owner === 'undefined' && typeof primary.owner === 'undefined') {
+          result.push(primary);
+        } else if (owner === primary.owner) {
+          result.push(primary);
+        }
+      });
+      return result;
+    };
+
+    var convertTablePrimariesToSuggestions = function (tablePrimaries) {
+      var tables = [];
+      var identifiers = [];
+      tablePrimaries.forEach(function (tablePrimary) {
+        if (tablePrimary.identifierChain && tablePrimary.identifierChain.length > 0) {
+          var table = { identifierChain: tablePrimary.identifierChain };
+          if (tablePrimary.alias) {
+            table.alias = tablePrimary.alias;
+            identifiers.push({ name: table.alias + '.', type: 'alias' });
+            if (parser.isImpala()) {
+              var testForImpalaAlias = [{ name: table.alias }];
+              var result = parser.expandImpalaIdentifierChain(tablePrimaries, testForImpalaAlias);
+              if (result.length > 1) {
+                // Continue if it's a reference to a complex type
+                return;
+              }
+            }
+          } else {
+            var lastIdentifier = tablePrimary.identifierChain[tablePrimary.identifierChain.length - 1];
+            if (typeof lastIdentifier.name !== 'undefined') {
+              identifiers.push({ name: lastIdentifier.name + '.', type: 'table' });
+            } else if (typeof lastIdentifier.subQuery !== 'undefined') {
+              identifiers.push({ name: lastIdentifier.subQuery + '.', type: 'sub-query' });
+            }
+          }
+          tables.push(table);
+        } else if (tablePrimary.subQueryAlias) {
+          identifiers.push({ name: tablePrimary.subQueryAlias + '.', type: 'sub-query' });
+          tables.push({ identifierChain: [{ subQuery: tablePrimary.subQueryAlias }] });
+        }
+      });
+      if (identifiers.length > 0) {
+        if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
+          parser.yy.result.suggestIdentifiers = identifiers;
+        } else {
+          parser.yy.result.suggestIdentifiers = identifiers.concat(parser.yy.result.suggestIdentifiers);
+        }
+      }
+      parser.yy.result.suggestColumns.tables = tables;
+      if (parser.yy.result.suggestColumns.identifierChain && parser.yy.result.suggestColumns.identifierChain.length == 0) {
+        delete parser.yy.result.suggestColumns.identifierChain;
+      }
+      parser.yy.result.suggestColumns.linked = true;
+    };
+
+    var linkTablePrimaries = function () {
+      if (!parser.yy.cursorFound || typeof parser.yy.latestTablePrimaries === 'undefined') {
+        return;
+      }
+
+      SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) {
+        if (typeof parser.yy.result[suggestionType] !== 'undefined' && parser.yy.result[suggestionType].tablePrimaries && !parser.yy.result[suggestionType].linked) {
+          parser.yy.result[suggestionType].tables = [];
+          parser.yy.result[suggestionType].tablePrimaries.forEach(function (tablePrimary) {
+            if (!tablePrimary.subQueryAlias) {
+              parser.yy.result[suggestionType].tables.push(tablePrimary.alias ? { identifierChain: tablePrimary.identifierChain.concat(), alias: tablePrimary.alias } : { identifierChain: tablePrimary.identifierChain.concat() });
+            }
+          });
+          delete parser.yy.result[suggestionType].tablePrimaries;
+          parser.yy.result[suggestionType].linked = true;
+        }
+      });
+
+      if (typeof parser.yy.result.suggestColumns !== 'undefined' && !parser.yy.result.suggestColumns.linked) {
+        var tablePrimaries = filterTablePrimariesForOwner(parser.yy.result.suggestColumns.owner);
+        if (!parser.yy.result.suggestColumns.tables) {
+          parser.yy.result.suggestColumns.tables = [];
+        }
+        if (parser.yy.subQueries.length > 0) {
+          parser.yy.result.subQueries = parser.yy.subQueries;
+        }
+        if (typeof parser.yy.result.suggestColumns.identifierChain === 'undefined' || parser.yy.result.suggestColumns.identifierChain.length === 0) {
+          if (tablePrimaries.length > 1) {
+            convertTablePrimariesToSuggestions(tablePrimaries);
+          } else {
+            suggestLateralViewAliasesAsIdentifiers();
+            if (tablePrimaries.length == 1 && (tablePrimaries[0].alias || tablePrimaries[0].subQueryAlias)) {
+              convertTablePrimariesToSuggestions(tablePrimaries);
+            }
+            parser.expandIdentifierChain(parser.yy.result.suggestColumns);
+          }
+        } else {
+          // Expand exploded views in the identifier chain
+          if (parser.isHive() && !parser.yy.result.suggestColumns.linked) {
+            var originalLength = parser.yy.result.suggestColumns.identifierChain.length;
+            parser.yy.result.suggestColumns.identifierChain = parser.expandLateralViews(parser.yy.lateralViews, parser.yy.result.suggestColumns.identifierChain, true);
+            // Drop '*' keyword for lateral views
+            if (typeof parser.yy.result.suggestColumns !== 'undefined') {
+              if (parser.yy.result.suggestColumns.identifierChain.length > originalLength &&
+                typeof parser.yy.result.suggestKeywords !== 'undefined' &&
+                parser.yy.result.suggestKeywords.length === 1 &&
+                parser.yy.result.suggestKeywords[0].value === '*') {
+                delete parser.yy.result.suggestKeywords;
+              }
+              parser.expandIdentifierChain(parser.yy.result.suggestColumns);
+            }
+          } else {
+            parser.expandIdentifierChain(parser.yy.result.suggestColumns);
+          }
+        }
+      }
+
+      if (typeof parser.yy.result.colRef !== 'undefined' && !parser.yy.result.colRef.linked) {
+        parser.expandIdentifierChain(parser.yy.result.colRef);
+
+        var primaries = filterTablePrimariesForOwner();
+        if (primaries.length === 0 || (primaries.length > 1 && parser.yy.result.colRef.identifierChain.length === 1)) {
+          parser.yy.result.colRef.identifierChain = [];
+        }
+      }
+      if (typeof parser.yy.result.suggestKeyValues !== 'undefined' && !parser.yy.result.suggestKeyValues.linked) {
+        parser.expandIdentifierChain(parser.yy.result.suggestKeyValues);
+      }
+    };
+
+    parser.getSubQuery = function (cols) {
+      var columns = [];
+      cols.selectList.forEach(function (col) {
+        var result = {};
+        if (col.alias) {
+          result.alias = col.alias;
+        }
+        if (col.valueExpression && col.valueExpression.columnReference) {
+          result.identifierChain = col.valueExpression.columnReference
+        } else if (col.asterisk) {
+          result.identifierChain = [{asterisk: true}];
+        }
+        if (col.valueExpression && col.valueExpression.types && col.valueExpression.types.length === 1) {
+          result.type = col.valueExpression.types[0];
+        }
+
+        columns.push(result);
+      });
+
+      return {
+        columns: columns
+      };
+    };
+
+    parser.addTablePrimary = function (ref) {
+      if (typeof parser.yy.latestTablePrimaries === 'undefined') {
+        parser.yy.latestTablePrimaries = [];
+      }
+      parser.yy.latestTablePrimaries.push(ref);
+    };
+
+    parser.suggestFileFormats = function () {
+      if (parser.isHive()) {
+        parser.suggestKeywords(['AVRO', 'INPUTFORMAT', 'ORC', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
+      } else {
+        parser.suggestKeywords(['AVRO', 'KUDU', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
+      }
+    };
+
+    parser.getKeywordsForOptionalsLR = function (optionals, keywords, override) {
+      var result = [];
+
+      for (var i = 0; i < optionals.length; i++) {
+        if (!optionals[i] && (typeof override === 'undefined' || override[i])) {
+          if (keywords[i] instanceof Array) {
+            result = result.concat(keywords[i]);
+          } else {
+            result.push(keywords[i]);
+          }
+        } else if (optionals[i]) {
+          break;
+        }
+      }
+      return result;
+    };
+
+    parser.suggestDdlAndDmlKeywords = function (extraKeywords) {
+      var keywords = ['ALTER', 'CREATE', 'DESCRIBE', 'DROP', 'GRANT', 'INSERT', 'REVOKE', 'SELECT', 'SET', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE', 'WITH'];
+
+      if (extraKeywords) {
+        keywords = keywords.concat(extraKeywords);
+      }
+
+      if (parser.isHive()) {
+        keywords = keywords.concat(['ANALYZE TABLE', 'DELETE', 'EXPORT', 'IMPORT', 'LOAD', 'MSCK', 'RELOAD FUNCTION', 'RESET']);
+      }
+
+      if (parser.isImpala()) {
+        keywords = keywords.concat(['COMPUTE', 'INVALIDATE METADATA', 'LOAD', 'REFRESH']);
+      }
+
+      parser.suggestKeywords(keywords);
+    };
+
+    parser.checkForSelectListKeywords = function (selectList) {
+      if (selectList.length === 0) {
+        return;
+      }
+      var last = selectList[selectList.length - 1];
+      if (!last || !last.valueExpression) {
+        return;
+      }
+      var valueExpressionKeywords = parser.getValueExpressionKeywords(last.valueExpression);
+      var keywords = [];
+      if (last.suggestKeywords) {
+        keywords = keywords.concat(last.suggestKeywords);
+      }
+      if (valueExpressionKeywords.suggestKeywords) {
+        keywords = keywords.concat(valueExpressionKeywords.suggestKeywords);
+      }
+      if (valueExpressionKeywords.suggestColRefKeywords) {
+        parser.suggestColRefKeywords(valueExpressionKeywords.suggestColRefKeywords);
+        parser.addColRefIfExists(last.valueExpression);
+      }
+      if (!last.alias) {
+        keywords.push('AS');
+      }
+      if (keywords.length > 0) {
+        parser.suggestKeywords(keywords);
+      }
+    };
+
+    parser.checkForKeywords = function (expression) {
+      if (expression) {
+        if (expression.suggestKeywords && expression.suggestKeywords.length > 0) {
+          parser.suggestKeywords(expression.suggestKeywords);
+        }
+        if (expression.suggestColRefKeywords) {
+          parser.suggestColRefKeywords(expression.suggestColRefKeywords);
+          parser.addColRefIfExists(expression);
+        }
+      }
+    };
+
+    parser.createWeightedKeywords = function (keywords, weight) {
+      var result = [];
+      keywords.forEach(function (keyword) {
+        if (typeof keyword.weight !== 'undefined') {
+          keyword.weight = weight + (keyword.weight / 10);
+          result.push(keyword);
+        } else {
+          result.push({value: keyword, weight: weight });
+        }
+      });
+      return result;
+    };
+
+    parser.suggestKeywords = function (keywords) {
+      var weightedKeywords = [];
+      if (keywords.length == 0) {
+        return;
+      }
+      keywords.forEach(function (keyword) {
+        if (typeof keyword.weight !== 'undefined') {
+          weightedKeywords.push(keyword);
+        } else {
+          weightedKeywords.push({ value: keyword, weight: -1 })
+        }
+      });
+      weightedKeywords.sort(function (a, b) {
+        if (a.weight !== b.weight) {
+          return b.weight - a.weight;
+        }
+        return a.value.localeCompare(b.value);
+      });
+      parser.yy.result.suggestKeywords = weightedKeywords;
+    };
+
+    parser.suggestColRefKeywords = function (colRefKeywords) {
+      parser.yy.result.suggestColRefKeywords = colRefKeywords;
+    };
+
+    parser.suggestTablesOrColumns = function (identifier) {
+      if (typeof parser.yy.latestTablePrimaries == 'undefined') {
+        parser.suggestTables({ identifierChain: [{ name: identifier }] });
+        return;
+      }
+      var tableRef = parser.yy.latestTablePrimaries.filter(function (tablePrimary) {
+        return tablePrimary.alias === identifier;
+      });
+      if (tableRef.length > 0) {
+        parser.suggestColumns({identifierChain: [{ name: identifier }]});
+      } else {
+        parser.suggestTables({ identifierChain: [{ name: identifier }] });
+      }
+    };
+
+    parser.suggestFunctions = function (details) {
+      parser.yy.result.suggestFunctions = details || {};
+    };
+
+    parser.suggestAggregateFunctions = function () {
+      var primaries = [];
+      var aliases = {};
+      parser.yy.latestTablePrimaries.forEach(function (primary) {
+        if (typeof primary.alias !== 'undefined') {
+          aliases[primary.alias] = true;
+        }
+        // Drop if the first one refers to a table alias (...FROM tbl t, t.map tm ...)
+        if (typeof primary.identifierChain !== 'undefined' && !aliases[primary.identifierChain[0].name] && typeof primary.owner === 'undefined') {
+          primaries.push(primary);
+        }
+      });
+      parser.yy.result.suggestAggregateFunctions = { tablePrimaries: primaries };
+    };
+
+    parser.suggestAnalyticFunctions = function () {
+      parser.yy.result.suggestAnalyticFunctions = true;
+    };
+
+    parser.suggestColumns = function (details) {
+      if (typeof details === 'undefined') {
+        details = {identifierChain: []};
+      } else if (typeof details.identifierChain === 'undefined') {
+        details.identifierChain = [];
+      }
+      parser.yy.result.suggestColumns = details;
+    };
+
+    parser.suggestGroupBys = function (details) {
+      parser.yy.result.suggestGroupBys = details || {};
+    };
+
+    parser.suggestOrderBys = function (details) {
+      parser.yy.result.suggestOrderBys = details || {};
+    };
+
+    parser.suggestFilters = function (details) {
+      parser.yy.result.suggestFilters = details || {};
+    };
+
+    parser.suggestKeyValues = function (details) {
+      parser.yy.result.suggestKeyValues = details || {};
+    };
+
+    parser.suggestTables = function (details) {
+      parser.yy.result.suggestTables = details || {};
+    };
+
+    var adjustLocationForCursor = function (location) {
+      // columns are 0-based and lines not, so add 1 to cols
+      var newLocation = {
+        first_line: location.first_line,
+        last_line: location.last_line,
+        first_column: location.first_column + 1,
+        last_column: location.last_column + 1
+      };
+      if (parser.yy.cursorFound) {
+        if (parser.yy.cursorFound.first_line === newLocation.first_line && parser.yy.cursorFound.last_column <= newLocation.first_column) {
+          var additionalSpace = parser.yy.partialLengths.left + parser.yy.partialLengths.right;
+          additionalSpace -= parser.yy.partialCursor ? 1 : 3; // For some reason the normal cursor eats 3 positions.
+          newLocation.first_column = newLocation.first_column + additionalSpace;
+          newLocation.last_column = newLocation.last_column + additionalSpace;
+        }
+      }
+      return newLocation;
+    };
+
+    parser.addFunctionLocation = function (location, functionName) {
+      // Remove trailing '(' from location
+      var adjustedLocation = {
+        first_line: location.first_line,
+        last_line: location.last_line,
+        first_column: location.first_column,
+        last_column: location.last_column - 1
+      };
+      parser.yy.locations.push({
+        type: 'function',
+        location: adjustLocationForCursor(adjustedLocation),
+        function: functionName.toLowerCase()
+      });
+    };
+
+    parser.addStatementLocation = function (location) {
+      // Don't report lonely cursor as a statement
+      if (location.first_line === location.last_line && Math.abs(location.last_column - location.first_column) === 1) {
+        return;
+      }
+      var adjustedLocation;
+      if (parser.yy.cursorFound && parser.yy.cursorFound.last_line === location.last_line &&
+        parser.yy.cursorFound.first_column >= location.first_column && parser.yy.cursorFound.last_column <= location.last_column) {
+        var additionalSpace = parser.yy.partialLengths.left + parser.yy.partialLengths.right;
+        adjustedLocation = {
+          first_line: location.first_line,
+          last_line: location.last_line,
+          first_column: location.first_column + 1,
+          last_column: location.last_column + additionalSpace - (parser.yy.partialCursor ? 0 : 2)
+        }
+      } else {
+        adjustedLocation = {
+          first_line: location.first_line,
+          last_line: location.last_line,
+          first_column: location.first_column + 1,
+          last_column: location.last_column + 1
+        }
+      }
+
+      parser.yy.locations.push({
+        type: 'statement',
+        location: adjustedLocation
+      });
+    };
+
+    parser.addHdfsLocation = function (location, path) {
+      parser.yy.locations.push({
+        type: 'hdfs',
+        location: adjustLocationForCursor(location),
+        path: path
+      });
+    };
+
+    parser.addDatabaseLocation = function (location, identifierChain) {
+      parser.yy.locations.push({
+        type: 'database',
+        location: adjustLocationForCursor(location),
+        identifierChain: identifierChain
+      });
+    };
+
+    parser.addTableLocation = function (location, identifierChain) {
+      parser.yy.locations.push({
+        type: 'table',
+        location: adjustLocationForCursor(location),
+        identifierChain: identifierChain
+      });
+    };
+
+    parser.addAsteriskLocation = function (location, identifierChain) {
+      parser.yy.locations.push({
+        type: 'asterisk',
+        location: adjustLocationForCursor(location),
+        identifierChain: identifierChain
+      });
+    };
+
+    parser.addColumnLocation = function (location, identifierChain) {
+      parser.yy.locations.push({
+        type: 'column',
+        location: adjustLocationForCursor(location),
+        identifierChain: identifierChain
+      });
+    };
+
+    parser.addUnknownLocation = function (location, identifierChain) {
+      parser.yy.locations.push({
+        type: 'unknown',
+        location: adjustLocationForCursor(location),
+        identifierChain: identifierChain
+      });
+    };
+
+    parser.suggestDatabases = function (details) {
+      parser.yy.result.suggestDatabases = details || {};
+    };
+
+    parser.suggestHdfs = function (details) {
+      parser.yy.result.suggestHdfs = details || {};
+    };
+
+    parser.suggestValues = function (details) {
+      parser.yy.result.suggestValues = details || {};
+    };
+
+    parser.determineCase = function (text) {
+      if (!parser.yy.caseDetermined) {
+        parser.yy.lowerCase = text.toLowerCase() === text;
+        parser.yy.caseDetermined = true;
+      }
+    };
+
+    parser.handleQuotedValueWithCursor = function(lexer, yytext, yylloc, quoteChar) {
+      if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) {
+        parser.yy.partialCursor = yytext.indexOf('\u2021') !== -1;
+        var cursorIndex = parser.yy.partialCursor ? yytext.indexOf('\u2021') : yytext.indexOf('\u2020');
+        parser.yy.cursorFound = {
+          first_line: yylloc.first_line,
+          last_line: yylloc.last_line,
+          first_column: yylloc.first_column + cursorIndex,
+          last_column: yylloc.first_column + cursorIndex + 1
+        };
+        var remainder = yytext.substring(cursorIndex + 1);
+        var remainingQuotes = (lexer.upcomingInput().match(new RegExp(quoteChar, 'g')) || []).length;
+        if (remainingQuotes > 0 && remainingQuotes & 1  != 0) {
+          parser.yy.missingEndQuote = false;
+          lexer.input();
+        } else {
+          parser.yy.missingEndQuote = true;
+          lexer.unput(remainder);
+        }
+        lexer.popState();
+        return true;
+      }
+      return false;
+    };
+
+    var lexerModified = false;
+
+    /**
+     * Main parser function
+     */
+    parser.parseSql = function (beforeCursor, afterCursor, dialect, debug) {
+      // Jison counts CRLF as two lines in the locations
+      beforeCursor = beforeCursor.replace(/\r\n|\n\r/gm, '\n');
+      afterCursor = afterCursor.replace(/\r\n|\n\r/gm, '\n');
+      parser.yy.result = {locations: []};
+      parser.yy.lowerCase = false;
+      parser.yy.locations = [];
+      parser.yy.allLocations = [];
+      parser.yy.subQueries = [];
+      parser.yy.errors = [];
+      parser.yy.selectListAliases = [];
+
+      parser.yy.locationsStack = [];
+      parser.yy.primariesStack = [];
+      parser.yy.lateralViewsStack = [];
+      parser.yy.subQueriesStack = [];
+      parser.yy.resultStack = [];
+      parser.yy.selectListAliasesStack = [];
+
+      delete parser.yy.caseDetermined;
+      delete parser.yy.cursorFound;
+      delete parser.yy.partialCursor;
+
+      parser.prepareNewStatement();
+
+      var REASONABLE_SURROUNDING_LENGTH = 150000; // About 3000 lines before and after
+
+      if (beforeCursor.length > REASONABLE_SURROUNDING_LENGTH) {
+        if ((beforeCursor.length - beforeCursor.lastIndexOf(';')) > REASONABLE_SURROUNDING_LENGTH) {
+          // Bail out if the last complete statement is more than 150000 chars before
+          return {};
+        }
+        // Cut it at the first statement found within 150000 chars before
+        var lastReasonableChunk = beforeCursor.substring(beforeCursor.length - REASONABLE_SURROUNDING_LENGTH);
+        beforeCursor = lastReasonableChunk.substring(lastReasonableChunk.indexOf(';') + 1);
+      }
+
+      if (afterCursor.length > REASONABLE_SURROUNDING_LENGTH) {
+        if ((afterCursor.length - afterCursor.indexOf(';')) > REASONABLE_SURROUNDING_LENGTH) {
+          // No need to bail out for what's comes after, we can still get keyword completion
+          afterCursor = '';
+        } else {
+          // Cut it at the last statement found within 150000 chars after
+          var firstReasonableChunk = afterCursor.substring(0, REASONABLE_SURROUNDING_LENGTH);
+          afterCursor = firstReasonableChunk.substring(0, firstReasonableChunk.lastIndexOf(';'));
+        }
+      }
+
+      parser.yy.partialLengths = parser.identifyPartials(beforeCursor, afterCursor);
+
+      if (parser.yy.partialLengths.left > 0) {
+        beforeCursor = beforeCursor.substring(0, beforeCursor.length - parser.yy.partialLengths.left);
+      }
+
+      if (parser.yy.partialLengths.right > 0) {
+        afterCursor = afterCursor.substring(parser.yy.partialLengths.right);
+      }
+
+      parser.yy.activeDialect = (dialect !== 'hive' && dialect !== 'impala') ? undefined : dialect;
+
+      // Hack to set the inital state of the lexer without first having to hit a token
+      // has to be done as the first token found can be dependant on dialect
+      if (!lexerModified) {
+        var originalSetInput = parser.lexer.setInput;
+        parser.lexer.setInput = function (input, yy) {
+          var lexer = originalSetInput.bind(parser.lexer)(input, yy);
+          if (typeof parser.yy.activeDialect !== 'undefined') {
+            lexer.begin(parser.yy.activeDialect);
+          }
+          return lexer;
+        };
+        lexerModified = true;
+      }
+
+      var result;
+      try {
+        // Add |CURSOR| or |PARTIAL_CURSOR| to represent the different cursor states in the lexer
+        result = parser.parse(beforeCursor + (beforeCursor.length == 0 || /[\s\(]$$/.test(beforeCursor) ? ' \u2020 ' : '\u2021') + afterCursor);
+      } catch (err) {
+        // On any error try to at least return any existing result
+        if (typeof parser.yy.result === 'undefined') {
+          throw err;
+        }
+        if (debug) {
+          console.log(err);
+          console.error(err.stack);
+        }
+        result = parser.yy.result;
+      }
+      if (parser.yy.errors.length > 0) {
+        parser.yy.result.errors = parser.yy.errors;
+        if (debug) {
+          console.log(parser.yy.errors);
+        }
+      }
+      try {
+        linkTablePrimaries();
+        parser.commitLocations();
+        // Clean up and prioritize
+        prioritizeSuggestions();
+      } catch (err) {
+        if (debug) {
+          console.log(err);
+          console.error(err.stack);
+        }
+      }
+
+
+      parser.yy.allLocations.sort(function (a, b) {
+        if (a.location.first_line !== b.location.first_line) {
+          return a.location.first_line - b.location.first_line;
+        }
+        return a.location.first_column - b.location.first_column;
+      });
+      parser.yy.result.locations = parser.yy.allLocations;
+
+      parser.yy.result.locations.forEach(function (location) {
+        delete location.linked;
+      });
+      if (typeof parser.yy.result.suggestColumns !== 'undefined') {
+        delete parser.yy.result.suggestColumns.linked;
+      }
+
+      SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) {
+        if (typeof parser.yy.result[suggestionType] !== 'undefined') {
+          delete parser.yy.result[suggestionType].linked;
+        }
+      });
+
+      if (typeof parser.yy.result.colRef !== 'undefined') {
+        delete parser.yy.result.colRef.linked;
+      }
+      if (typeof parser.yy.result.suggestKeyValues !== 'undefined') {
+        delete parser.yy.result.suggestKeyValues.linked;
+      }
+
+      if (typeof result.error !== 'undefined' && typeof result.error.expected !== 'undefined') {
+        // Remove any expected tokens from other dialects, jison doesn't remove tokens from other lexer states.
+        var actualExpected = {};
+        result.error.expected.forEach(function (expected) {
+          var match = expected.match(/\<([a-z]+)\>(.*)/);
+          if (match !== null) {
+            if (typeof parser.yy.activeDialect !== 'undefined' && parser.yy.activeDialect === match[1]) {
+              actualExpected[("'" + match[2])] = true;
+            }
+          } else if (expected.indexOf('CURSOR') == -1) {
+            actualExpected[expected] = true;
+          }
+        });
+        result.error.expected = Object.keys(actualExpected);
+      }
+
+      if (typeof result.error !== 'undefined' && result.error.recoverable) {
+        delete result.error;
+      }
+
+      // Adjust all the statement locations to include white space surrounding them
+      var lastStatementLocation = null;
+      result.locations.forEach(function (location) {
+        if (location.type === 'statement') {
+          if (lastStatementLocation === null) {
+            location.location.first_line = 1;
+            location.location.first_column = 1;
+          } else {
+            location.location.first_line = lastStatementLocation.location.last_line;
+            location.location.first_column = lastStatementLocation.location.last_column + 1;
+          }
+          lastStatementLocation = location;
+        }
+      });
+
+      return result;
+    };
+  };
+
+  return {
+    initSqlParser: initSqlParser
+  };
+})();

+ 18 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sql_end.jison

@@ -1 +1,19 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 %%
+
+SqlParseSupport.initSqlParser(parser);

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

@@ -1,1447 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-var SIMPLE_TABLE_REF_SUGGESTIONS = ['suggestJoinConditions', 'suggestAggregateFunctions', 'suggestFilters', 'suggestGroupBys', 'suggestOrderBys'];
-
-var prepareNewStatement = function () {
-  linkTablePrimaries();
-  commitLocations();
-
-  delete parser.yy.lateralViews;
-  delete parser.yy.latestCommonTableExpressions;
-  delete parser.yy.correlatedSubQuery;
-  parser.yy.subQueries = [];
-  parser.yy.selectListAliases = [];
-  parser.yy.latestTablePrimaries = [];
-
-  parser.parseError = function (message, error) {
-    parser.yy.errors.push(error);
-    return message;
-  };
-};
-
-var addCommonTableExpressions = function (identifiers) {
-  parser.yy.result.commonTableExpressions = identifiers;
-  parser.yy.latestCommonTableExpressions = identifiers;
-};
-
-var pushQueryState = function () {
-  parser.yy.resultStack.push(parser.yy.result);
-  parser.yy.locationsStack.push(parser.yy.locations);
-  parser.yy.lateralViewsStack.push(parser.yy.lateralViews);
-  parser.yy.selectListAliasesStack.push(parser.yy.selectListAliases);
-  parser.yy.primariesStack.push(parser.yy.latestTablePrimaries);
-  parser.yy.subQueriesStack.push(parser.yy.subQueries);
-
-  parser.yy.result = {};
-  parser.yy.locations = [];
-  parser.yy.selectListAliases = []; // Not allowed in correlated sub-queries
-  parser.yy.lateralViews = []; // Not allowed in correlated sub-queries
-
-  if (parser.yy.correlatedSubQuery) {
-    parser.yy.latestTablePrimaries = parser.yy.latestTablePrimaries.concat();
-    parser.yy.subQueries = parser.yy.subQueries.concat();
-  } else {
-    parser.yy.latestTablePrimaries = [];
-    parser.yy.subQueries = [];
-  }
-};
-
-var popQueryState = function (subQuery) {
-  linkTablePrimaries();
-  commitLocations();
-
-  if (Object.keys(parser.yy.result).length === 0) {
-    parser.yy.result = parser.yy.resultStack.pop();
-  } else {
-    parser.yy.resultStack.pop();
-  }
-  var oldSubQueries = parser.yy.subQueries;
-  parser.yy.subQueries = parser.yy.subQueriesStack.pop();
-  if (subQuery) {
-    if (oldSubQueries.length > 0) {
-      subQuery.subQueries = oldSubQueries;
-    }
-    parser.yy.subQueries.push(subQuery);
-  }
-
-  parser.yy.lateralViews = parser.yy.lateralViewsStack.pop();
-  parser.yy.latestTablePrimaries = parser.yy.primariesStack.pop();
-  parser.yy.locations = parser.yy.locationsStack.pop();
-  parser.yy.selectListAliases = parser.yy.selectListAliasesStack.pop();
-};
-
-var suggestSelectListAliases = function () {
-  if (parser.yy.selectListAliases && parser.yy.selectListAliases.length > 0 && parser.yy.result.suggestColumns
-      && (typeof parser.yy.result.suggestColumns.identifierChain === 'undefined' || parser.yy.result.suggestColumns.identifierChain.length === 0)) {
-    parser.yy.result.suggestColumnAliases = parser.yy.selectListAliases;
-  }
-};
-
-var isHive = function () {
-  return parser.yy.activeDialect === 'hive';
-};
-
-var isImpala = function () {
-  return parser.yy.activeDialect === 'impala';
-};
-
-var mergeSuggestKeywords = function () {
-  var result = [];
-  Array.prototype.slice.call(arguments).forEach(function (suggestion) {
-    if (typeof suggestion !== 'undefined' && typeof suggestion.suggestKeywords !== 'undefined') {
-      result = result.concat(suggestion.suggestKeywords);
-    }
-  });
-  if (result.length > 0) {
-    return {suggestKeywords: result};
-  }
-  return {};
-};
-
-var suggestValueExpressionKeywords = function (valueExpression, extras) {
-  var expressionKeywords = getValueExpressionKeywords(valueExpression, extras);
-  suggestKeywords(expressionKeywords.suggestKeywords);
-  if (expressionKeywords.suggestColRefKeywords) {
-    suggestColRefKeywords(expressionKeywords.suggestColRefKeywords);
-  }
-  if (valueExpression.lastType) {
-    addColRefIfExists(valueExpression.lastType);
-  } else {
-    addColRefIfExists(valueExpression);
-  }
-};
-
-var getValueExpressionKeywords = function (valueExpression, extras) {
-  var types = valueExpression.lastType ? valueExpression.lastType.types : valueExpression.types;
-  // We could have valueExpression.columnReference to suggest based on column type
-  var keywords = ['<', '<=', '<>', '=', '>', '>=', 'BETWEEN', 'IN', 'IS NOT NULL', 'IS NULL', 'NOT BETWEEN', 'NOT IN'];
-  if (isHive()) {
-    keywords.push('<=>');
-  }
-  if (extras) {
-    keywords = keywords.concat(extras);
-  }
-  if (valueExpression.suggestKeywords) {
-    keywords = keywords.concat(valueExpression.suggestKeywords);
-  }
-  if (types.length === 1 && types[0] === 'COLREF') {
-    return {
-      suggestKeywords: keywords,
-      suggestColRefKeywords: {
-        BOOLEAN: ['AND', 'OR'],
-        NUMBER: ['+', '-', '*', '/', '%'],
-        STRING: ['LIKE', 'NOT LIKE', 'REGEX', 'RLIKE']
-      }
-    }
-  }
-  if (SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
-    keywords = keywords.concat(['AND', 'OR']);
-  }
-  if (SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
-    keywords = keywords.concat(['+', '-', '*', '/', '%']);
-  }
-  if (SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)) {
-    keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEX', 'RLIKE']);
-  }
-  return {suggestKeywords: keywords};
-};
-
-var getTypeKeywords = function () {
-  if (isHive()) {
-    return ['BIGINT', 'BINARY', 'BOOLEAN', 'CHAR', 'DATE', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
-  }
-  if (isImpala()) {
-    return ['BIGINT', 'BOOLEAN', 'CHAR', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'REAL', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
-  }
-  return ['BIGINT', 'BOOLEAN', 'CHAR', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
-};
-
-var getColumnDataTypeKeywords = function () {
-  if (isHive()) {
-    return getTypeKeywords().concat(['ARRAY<>', 'MAP<>', 'STRUCT<>', 'UNIONTYPE<>']);
-  }
-  return getTypeKeywords();
-};
-
-var addColRefIfExists = function (valueExpression) {
-  if (valueExpression.columnReference) {
-    parser.yy.result.colRef = {identifierChain: valueExpression.columnReference};
-  }
-};
-
-var selectListNoTableSuggest = function (selectListEdit, hasDistinctOrAll) {
-  if (selectListEdit.cursorAtStart) {
-    var keywords = [];
-    if (hasDistinctOrAll) {
-      keywords = [{ value: '*', weight: 1000 }];
-    } else {
-      keywords = [{ value: '*', weight: 1000 }, 'ALL', 'DISTINCT'];
-    }
-    if (isImpala()) {
-      keywords.push('STRAIGHT_JOIN');
-    }
-    suggestKeywords(keywords);
-  } else {
-    checkForKeywords(selectListEdit);
-  }
-  if (selectListEdit.suggestFunctions) {
-    suggestFunctions();
-  }
-  if (selectListEdit.suggestColumns) {
-    suggestColumns();
-  }
-  if (selectListEdit.suggestAggregateFunctions && (!hasDistinctOrAll || hasDistinctOrAll === 'ALL')) {
-    suggestAggregateFunctions();
-    suggestAnalyticFunctions();
-  }
-};
-
-var suggestJoinConditions = 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 suggestJoins = function (details) {
-  parser.yy.result.suggestJoins = details || {};
-};
-
-var valueExpressionSuggest = function (oppositeValueExpression, operator) {
-  if (oppositeValueExpression && oppositeValueExpression.columnReference) {
-    suggestValues();
-    parser.yy.result.colRef = {identifierChain: oppositeValueExpression.columnReference};
-  }
-  suggestColumns();
-  suggestFunctions();
-  var keywords = ['CASE'];
-  if (isHive() || typeof oppositeValueExpression === 'undefined' || typeof operator === 'undefined') {
-    keywords = keywords.concat(['EXISTS', 'NOT']);
-  }
-  if (oppositeValueExpression && oppositeValueExpression.types[0] === 'NUMBER') {
-    applyTypeToSuggestions(['NUMBER']);
-  } else if (isImpala() && (typeof operator === 'undefined' || operator === '-' || operator === '+')) {
-    keywords.push('INTERVAL');
-  }
-  suggestKeywords(keywords);
-};
-
-var applyTypeToSuggestions = function (types) {
-  if (types[0] === 'BOOLEAN') {
-    return;
-  }
-  if (parser.yy.result.suggestFunctions && !parser.yy.result.suggestFunctions.types) {
-    parser.yy.result.suggestFunctions.types = types;
-  }
-  if (parser.yy.result.suggestColumns && !parser.yy.result.suggestColumns.types) {
-    parser.yy.result.suggestColumns.types = types;
-  }
-};
-
-var findCaseType = function (whenThenList) {
-  var types = {};
-  whenThenList.caseTypes.forEach(function (valueExpression) {
-    valueExpression.types.forEach(function (type) {
-      types[type] = true;
-    });
-  });
-  if (Object.keys(types).length === 1) {
-    return {types: [Object.keys(types)[0]]};
-  }
-  return {types: ['T']};
-};
-
-findReturnTypes = function (functionName) {
-  return SqlFunctions.getReturnTypes(parser.yy.activeDialect, functionName.toLowerCase());
-};
-
-var applyArgumentTypesToSuggestions = function (functionName, position) {
-  var foundArguments = SqlFunctions.getArgumentTypes(parser.yy.activeDialect, functionName.toLowerCase(), position);
-  if (foundArguments.length == 0 && parser.yy.result.suggestColumns) {
-    delete parser.yy.result.suggestColumns;
-    delete parser.yy.result.suggestKeyValues;
-    delete parser.yy.result.suggestValues;
-    delete parser.yy.result.suggestFunctions;
-    delete parser.yy.result.suggestIdentifiers;
-    delete parser.yy.result.suggestKeywords;
-  } else {
-    applyTypeToSuggestions(foundArguments);
-  }
-};
-
-var commitLocations = function () {
-  var i = parser.yy.locations.length;
-  while (i--) {
-    var location = parser.yy.locations[i];
-
-    // Impala can have references to previous tables after FROM, i.e. FROM testTable t, t.testArray
-    // In this testArray would be marked a type table so we need to switch it to column.
-    if (location.type === 'table' && typeof location.identifierChain !== 'undefined' && location.identifierChain.length > 1 && parser.yy.latestTablePrimaries) {
-      var found = parser.yy.latestTablePrimaries.filter(function (primary) {
-        return primary.alias === location.identifierChain[0].name;
-      });
-      if (found.length > 0) {
-        location.type = 'column';
-      }
-    }
-
-    if (location.type === 'database' && parser.yy.latestTablePrimaries) {
-      var foundAlias = parser.yy.latestTablePrimaries.filter(function (primary) {
-        return primary.alias === location.identifierChain[0].name;
-      });
-      if (foundAlias.length > 0) {
-        // Impala complex reference in FROM clause, i.e. FROM testTable t, t.testMap tm
-        location.type = 'table';
-        expandIdentifierChain(location, true);
-      }
-    }
-
-    if (location.type === 'unknown') {
-      if (typeof location.identifierChain !== 'undefined' && location.identifierChain.length <= 2 && parser.yy.latestTablePrimaries) {
-        var found = parser.yy.latestTablePrimaries.filter(function (primary) {
-          return primary.alias === location.identifierChain[0].name || (primary.identifierChain && primary.identifierChain[0].name === location.identifierChain[0].name);
-        });
-        if (found.length > 0) {
-          if (found[0].identifierChain.length > 1 && location.identifierChain.length === 1 && found[0].identifierChain[0].name === location.identifierChain[0].name) {
-            location.type = 'database';
-          } else {
-            location.type = 'table';
-            expandIdentifierChain(location, true);
-          }
-        } else {
-          if (parser.yy.subQueries) {
-            found = parser.yy.subQueries.filter(function (subQuery) {
-              return subQuery.alias === location.identifierChain[0].name;
-            });
-            if (found.length > 0) {
-              location.type = 'subQuery';
-              location.identifierChain = [{ subQuery: found[0].alias }];
-            }
-          }
-        }
-      }
-    }
-
-    if (location.type === 'asterisk' && !location.linked) {
-      if (parser.yy.latestTablePrimaries && parser.yy.latestTablePrimaries.length > 0) {
-        location.tables = [];
-        location.linked = false;
-        expandIdentifierChain(location, true);
-        if (location.tables.length === 0) {
-          parser.yy.locations.splice(i, 1);
-        }
-      } else {
-        parser.yy.locations.splice(i, 1);
-      }
-    }
-
-    if (location.type === 'unknown') {
-      location.type = 'column';
-    }
-    if (location.type === 'column') {
-      if (isHive() && !location.linked) {
-        location.identifierChain = parser.expandLateralViews(parser.yy.lateralViews, location.identifierChain);
-      }
-      expandIdentifierChain(location, true);
-    }
-
-    if (location.type === 'table' && (typeof location.identifierChain === 'undefined' || location.identifierChain.length === 0)) {
-      parser.yy.locations.splice(i, 1);
-    }
-    if (location.type === 'column') {
-      if (typeof location.identifierChain === 'undefined') {
-        parser.yy.locations.splice(i, 1);
-      } else if (location.identifierChain.length < 2) {
-        location.tables = [];
-        location.linked = false;
-        expandIdentifierChain(location, true);
-        if (location.tables.length === 0) {
-          parser.yy.locations.splice(i, 1);
-        }
-      }
-    }
-  }
-  if (parser.yy.locations.length > 0) {
-    parser.yy.allLocations = parser.yy.allLocations.concat(parser.yy.locations);
-    parser.yy.locations = [];
-  }
-};
-
-var prioritizeSuggestions = function () {
-  parser.yy.result.lowerCase = parser.yy.lowerCase || false;
-
-  var cteIndex = {};
-
-  if (typeof parser.yy.latestCommonTableExpressions !== 'undefined') {
-    parser.yy.latestCommonTableExpressions.forEach(function (cte) {
-      cteIndex[cte.alias.toLowerCase()] = cte;
-    })
-  }
-
-  SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) {
-    if (suggestionType !== 'suggestAggregateFunctions' && typeof parser.yy.result[suggestionType] !== 'undefined' && parser.yy.result[suggestionType].tables.length === 0) {
-      delete parser.yy.result[suggestionType];
-    } else if (typeof parser.yy.result[suggestionType] !== 'undefined' && typeof parser.yy.result[suggestionType].tables !== 'undefined') {
-      for (var i = parser.yy.result[suggestionType].tables.length - 1; i >= 0; i--) {
-        var table = parser.yy.result[suggestionType].tables[i];
-        if (table.identifierChain.length === 1 && typeof table.identifierChain[0].name !== 'undefined' && typeof cteIndex[table.identifierChain[0].name] !== 'undefined') {
-          parser.yy.result[suggestionType].tables.splice(i, 1);
-        }
-      }
-    }
-  });
-
-  if (typeof parser.yy.result.colRef !== 'undefined') {
-    if (!parser.yy.result.colRef.linked || typeof parser.yy.result.colRef.identifierChain === 'undefined' || parser.yy.result.colRef.identifierChain.length === 0) {
-      delete parser.yy.result.colRef;
-      if (typeof parser.yy.result.suggestColRefKeywords !== 'undefined') {
-        Object.keys(parser.yy.result.suggestColRefKeywords).forEach(function (type) {
-          parser.yy.result.suggestKeywords = parser.yy.result.suggestKeywords.concat(createWeightedKeywords(parser.yy.result.suggestColRefKeywords[type], -1));
-        });
-        delete parser.yy.result.suggestColRefKeywords;
-      }
-      if (parser.yy.result.suggestColumns && parser.yy.result.suggestColumns.types.length === 1 && parser.yy.result.suggestColumns.types[0] === 'COLREF') {
-        parser.yy.result.suggestColumns.types = ['T'];
-      }
-      delete parser.yy.result.suggestValues;
-    }
-  }
-
-  if (typeof parser.yy.result.colRef !== 'undefined') {
-    if (!parser.yy.result.suggestValues && !parser.yy.result.suggestColRefKeywords &&
-        (!parser.yy.result.suggestColumns ||
-        parser.yy.result.suggestColumns.types[0] !== 'COLREF')) {
-      delete parser.yy.result.colRef;
-    }
-  }
-  if (typeof parser.yy.result.suggestIdentifiers !== 'undefined' && parser.yy.result.suggestIdentifiers.length > 0) {
-    delete parser.yy.result.suggestTables;
-    delete parser.yy.result.suggestDatabases;
-  }
-  if (typeof parser.yy.result.suggestColumns !== 'undefined') {
-    var suggestColumns = parser.yy.result.suggestColumns;
-    if (typeof suggestColumns.tables === 'undefined' || suggestColumns.tables.length === 0) {
-      // Impala supports statements like SELECT * FROM tbl1, tbl2 WHERE db.tbl1.col = tbl2.bla
-      if (parser.yy.result.suggestColumns.linked && isImpala() && typeof suggestColumns.identifierChain !== 'undefined' && suggestColumns.identifierChain.length > 0) {
-        if (suggestColumns.identifierChain.length === 1) {
-          parser.yy.result.suggestTables = suggestColumns;
-          delete parser.yy.result.suggestColumns
-        } else {
-          suggestColumns.tables = [{ identifierChain: suggestColumns.identifierChain }];
-          delete suggestColumns.identifierChain;
-        }
-      } else {
-        delete parser.yy.result.suggestColumns;
-        delete parser.yy.result.subQueries;
-      }
-    } else {
-      delete parser.yy.result.suggestTables;
-      delete parser.yy.result.suggestDatabases;
-
-      suggestColumns.tables.forEach(function (table) {
-        if (typeof table.identifierChain !== 'undefined' && table.identifierChain.length === 1 && typeof table.identifierChain[0].name !== 'undefined') {
-          var cte = cteIndex[table.identifierChain[0].name.toLowerCase()];
-          if (typeof cte !== 'undefined') {
-            delete table.identifierChain[0].name;
-            table.identifierChain[0].cte = cte.alias;
-          }
-        }
-      });
-
-      if (typeof suggestColumns.identifierChain !== 'undefined') {
-        delete suggestColumns.identifierChain;
-      }
-    }
-  } else {
-    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 (cte) {
-      var suggestion = { name: cte.alias };
-      if (parser.yy.result.suggestTables.prependFrom) {
-        suggestion.prependFrom = true
-      }
-      if (parser.yy.result.suggestTables.prependQuestionMark) {
-        suggestion.prependQuestionMark = true;
-      }
-      ctes.push(suggestion);
-    });
-    if (ctes.length > 0) {
-      parser.yy.result.suggestCommonTableExpressions = ctes;
-    }
-  }
-};
-
-/**
- * Impala supports referencing maps and arrays in the the table reference list i.e.
- *
- *  SELECT m['foo'].bar.| FROM someDb.someTable t, t.someMap m;
- *
- * From this the tablePrimaries would look like:
- *
- * [ { alias: 't', identifierChain: [ { name: 'someDb' }, { name: 'someTable' } ] },
- *   { alias: 'm', identifierChain: [ { name: 't' }, { name: 'someMap' } ] } ]
- *
- * with an identifierChain from the select list:
- *
- * [ { name: 'm', keySet: true }, { name: 'bar' } ]
- *
- * Calling this would return an expanded identifierChain, given the above it would be:
- *
- * [ { name: 't' }, { name: 'someMap', keySet: true }, { name: 'bar' } ]
- */
-parser.expandImpalaIdentifierChain = function (tablePrimaries, identifierChain) {
-  var expandedChain = identifierChain.concat(); // Clone in case it's called multiple times.
-  if (typeof expandedChain === 'undefined' || expandedChain.length === 0) {
-    return identifierChain;
-  }
-  var expand = function (identifier, expandedChain) {
-    var foundPrimary = tablePrimaries.filter(function (tablePrimary) {
-      return tablePrimary.alias === identifier;
-    });
-
-    if (foundPrimary.length === 1 && foundPrimary[0].identifierChain) {
-      var parentPrimary = tablePrimaries.filter(function (tablePrimary) {
-        return tablePrimary.alias === foundPrimary[0].identifierChain[0].name;
-      });
-      if (parentPrimary.length === 1) {
-        var keySet = expandedChain[0].keySet;
-        var secondPart = expandedChain.slice(1);
-        var firstPart = [];
-        // Clone to make sure we don't add keySet to the primaries
-        foundPrimary[0].identifierChain.forEach(function (identifier) {
-          firstPart.push({name: identifier.name});
-        });
-        if (keySet && firstPart.length > 0) {
-          firstPart[firstPart.length - 1].keySet = true;
-        }
-
-        if (firstPart.length === 0 || typeof secondPart === 'undefined' || secondPart.length === 0) {
-          return firstPart;
-        }
-        var result = firstPart.concat(secondPart);
-        if (result.length > 0) {
-          return expand(firstPart[0].name, result);
-        } else {
-          return result;
-        }
-      }
-    }
-    return expandedChain;
-  };
-  return expand(expandedChain[0].name, expandedChain);
-};
-
-parser.identifyPartials = function (beforeCursor, afterCursor) {
-  var beforeMatch = beforeCursor.match(/[0-9a-zA-Z_]*$/);
-  var afterMatch = afterCursor.match(/^[0-9a-zA-Z_]*(?:\((?:[^)]*\))?)?/);
-  return {left: beforeMatch ? beforeMatch[0].length : 0, right: afterMatch ? afterMatch[0].length : 0};
-};
-
-parser.expandLateralViews = function (lateralViews, originalIdentifierChain, columnSuggestion) {
-  var identifierChain = originalIdentifierChain.concat(); // Clone in case it's re-used
-  var firstIdentifier = identifierChain[0];
-  if (typeof lateralViews !== 'undefined') {
-    lateralViews.concat().reverse().forEach(function (lateralView) {
-      if (!lateralView.udtf.expression.columnReference) {
-        return;
-      }
-      if (firstIdentifier.name === lateralView.tableAlias && identifierChain.length > 1) {
-        identifierChain.shift();
-        firstIdentifier = identifierChain[0];
-        if (columnSuggestion) {
-          delete parser.yy.result.suggestKeywords;
-        }
-      } else if (firstIdentifier.name === lateralView.tableAlias && identifierChain.length === 1 && typeof parser.yy.result.suggestColumns !== 'undefined') {
-        if (columnSuggestion) {
-          if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
-            parser.yy.result.suggestIdentifiers = [];
-          }
-          lateralView.columnAliases.forEach(function (columnAlias) {
-            parser.yy.result.suggestIdentifiers.push({name: columnAlias, type: 'alias'});
-          });
-          delete parser.yy.result.suggestColumns;
-          delete parser.yy.result.suggestKeywords;
-        }
-        return identifierChain;
-      }
-      if (lateralView.columnAliases.indexOf(firstIdentifier.name) !== -1) {
-        if (lateralView.columnAliases.length === 2 && lateralView.udtf.function.toLowerCase() === 'explode' && firstIdentifier.name === lateralView.columnAliases[0]) {
-          identifierChain[0] = {name: 'key'};
-        } else if (lateralView.columnAliases.length === 2 && lateralView.udtf.function.toLowerCase() === 'explode' && firstIdentifier.name === lateralView.columnAliases[1]) {
-          identifierChain[0] = {name: 'value'};
-        } else {
-          identifierChain[0] = {name: 'item'};
-        }
-        identifierChain = lateralView.udtf.expression.columnReference.concat(identifierChain);
-        firstIdentifier = identifierChain[0];
-      }
-    });
-  }
-  return identifierChain;
-};
-
-var addCleanTablePrimary = function (tables, tablePrimary) {
-  if (tablePrimary.alias) {
-    tables.push({ alias: tablePrimary.alias, identifierChain: tablePrimary.identifierChain });
-  } else {
-    tables.push({ identifierChain: tablePrimary.identifierChain });
-  }
-};
-
-var expandIdentifierChain = function (wrapper, anyOwner) {
-  if (typeof wrapper.identifierChain === 'undefined' || typeof parser.yy.latestTablePrimaries === 'undefined') {
-    return;
-  }
-
-  var identifierChain = wrapper.identifierChain.concat();
-  var tablePrimaries = parser.yy.latestTablePrimaries;
-
-  if (tablePrimaries.length === 0) {
-    delete wrapper.identifierChain;
-    return;
-  }
-
-  if (identifierChain.length > 0 && identifierChain[identifierChain.length - 1].asterisk) {
-    var tables = [];
-    tablePrimaries.forEach(function (tablePrimary) {
-      if (identifierChain.length > 1 && !tablePrimary.subQueryAlias) {
-        if (identifierChain.length === 2 && tablePrimary.alias === identifierChain[0].name) {
-          addCleanTablePrimary(tables, tablePrimary);
-        } else if (identifierChain.length === 2 && tablePrimary.identifierChain[0].name === identifierChain[0].name) {
-          addCleanTablePrimary(tables, tablePrimary);
-        } else if (identifierChain.length === 3 && tablePrimary.identifierChain.length > 1 &&
-            tablePrimary.identifierChain[0].name === identifierChain[0].name &&
-            tablePrimary.identifierChain[1].name === identifierChain[1].name) {
-          addCleanTablePrimary(tables, tablePrimary);
-        }
-      } else {
-        if (tablePrimary.subQueryAlias) {
-          tables.push({ identifierChain: [{ subQuery: tablePrimary.subQueryAlias }]});
-        } else {
-          addCleanTablePrimary(tables, tablePrimary);
-        }
-      }
-    });
-    // Possible Joins
-    if (tables.length > 0) {
-      wrapper.tables = tables;
-      delete wrapper.identifierChain;
-      return;
-    }
-  }
-
-  if (!anyOwner) {
-    tablePrimaries = filterTablePrimariesForOwner(wrapper.owner);
-  }
-  // Impala can have references to maps or array, i.e. FROM table t, t.map m
-  // We need to replace those in the identifierChain
-  if (isImpala()) {
-    var lengthBefore = identifierChain.length;
-    identifierChain = parser.expandImpalaIdentifierChain(tablePrimaries, identifierChain);
-    // Change type of any locations marked as table
-    if (wrapper.type === 'table' && identifierChain.length > lengthBefore) {
-      wrapper.type = 'column';
-    }
-    wrapper.identifierChain = identifierChain;
-  }
-  // Expand exploded views in the identifier chain
-  if (isHive() && identifierChain.length > 0) {
-    identifierChain = parser.expandLateralViews(parser.yy.lateralViews, identifierChain);
-    wrapper.identifierChain = identifierChain;
-  }
-
-  // IdentifierChain contains a possibly started identifier or empty, example: a.b.c = ['a', 'b', 'c']
-  // Reduce the tablePrimaries to the one that matches the first identifier if found
-  var foundPrimary;
-  var doubleMatch = false;
-  if (identifierChain.length > 0) {
-    for (var i = 0; i < tablePrimaries.length; i++) {
-      if (tablePrimaries[i].subQueryAlias) {
-        if (tablePrimaries[i].subQueryAlias === identifierChain[0].name) {
-          foundPrimary = tablePrimaries[i];
-        }
-      } else if (tablePrimaries[i].alias === identifierChain[0].name) {
-        foundPrimary = tablePrimaries[i];
-        break;
-      } else if (tablePrimaries[i].identifierChain.length > 1 && identifierChain.length > 1 &&
-          tablePrimaries[i].identifierChain[0].name === identifierChain[0].name &&
-          tablePrimaries[i].identifierChain[1].name === identifierChain[1].name) {
-        foundPrimary = tablePrimaries[i];
-        doubleMatch = true;
-        break;
-      } else if (!foundPrimary && tablePrimaries[i].identifierChain[0].name === identifierChain[0].name) {
-        foundPrimary = tablePrimaries[i];
-        // No break as first two can still match.
-      } else if (!foundPrimary && tablePrimaries[i].identifierChain.length > 1
-          && tablePrimaries[i].identifierChain[tablePrimaries[i].identifierChain.length - 1].name === identifierChain[0].name) {
-        // This is for the case SELECT baa. FROM bla.baa, blo.boo;
-        foundPrimary = tablePrimaries[i];
-        break;
-      }
-    }
-  }
-
-  if (foundPrimary) {
-    identifierChain.shift();
-    if (doubleMatch) {
-      identifierChain.shift();
-    }
-  } else if (tablePrimaries.length === 1) {
-    foundPrimary = tablePrimaries[0];
-  }
-
-  if (foundPrimary) {
-    if (foundPrimary.subQueryAlias) {
-      identifierChain.unshift({ subQuery: foundPrimary.subQueryAlias });
-    } else {
-      identifierChain = foundPrimary.identifierChain.concat(identifierChain);
-    }
-    if (wrapper.tables) {
-      wrapper.tables.push({ identifierChain: identifierChain });
-      delete wrapper.identifierChain;
-    } else {
-      wrapper.identifierChain = identifierChain;
-    }
-  } else {
-    tablePrimaries.forEach(function (tablePrimary) {
-      var targetTable = { identifierChain: tablePrimary.identifierChain };
-      if (tablePrimary.alias) {
-        targetTable.alias = tablePrimary.alias;
-      }
-      if (wrapper.tables) {
-        wrapper.tables.push(targetTable)
-      }
-    });
-  }
-
-  delete wrapper.owner;
-  wrapper.linked = true;
-};
-
-var suggestLateralViewAliasesAsIdentifiers = function () {
-  if (typeof parser.yy.lateralViews === 'undefined' || parser.yy.lateralViews.length === 0) {
-    return;
-  }
-  if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
-    parser.yy.result.suggestIdentifiers = [];
-  }
-  parser.yy.lateralViews.forEach(function (lateralView) {
-    if (typeof lateralView.tableAlias !== 'undefined') {
-      parser.yy.result.suggestIdentifiers.push({name: lateralView.tableAlias + '.', type: 'alias'});
-    }
-    lateralView.columnAliases.forEach(function (columnAlias) {
-      parser.yy.result.suggestIdentifiers.push({name: columnAlias, type: 'alias'});
-    });
-  });
-  if (parser.yy.result.suggestIdentifiers.length === 0) {
-    delete parser.yy.result.suggestIdentifiers;
-  }
-};
-
-var filterTablePrimariesForOwner = function (owner) {
-  var result = [];
-  parser.yy.latestTablePrimaries.forEach(function (primary) {
-    if (typeof owner === 'undefined' && typeof primary.owner === 'undefined') {
-      result.push(primary);
-    } else if (owner === primary.owner) {
-      result.push(primary);
-    }
-  });
-  return result;
-};
-
-var convertTablePrimariesToSuggestions = function (tablePrimaries) {
-  var tables = [];
-  var identifiers = [];
-  tablePrimaries.forEach(function (tablePrimary) {
-    if (tablePrimary.identifierChain && tablePrimary.identifierChain.length > 0) {
-      var table = { identifierChain: tablePrimary.identifierChain };
-      if (tablePrimary.alias) {
-        table.alias = tablePrimary.alias;
-        identifiers.push({ name: table.alias + '.', type: 'alias' });
-        if (isImpala()) {
-          var testForImpalaAlias = [{ name: table.alias }];
-          var result = parser.expandImpalaIdentifierChain(tablePrimaries, testForImpalaAlias);
-          if (result.length > 1) {
-            // Continue if it's a reference to a complex type
-            return;
-          }
-        }
-      } else {
-        var lastIdentifier = tablePrimary.identifierChain[tablePrimary.identifierChain.length - 1];
-        if (typeof lastIdentifier.name !== 'undefined') {
-          identifiers.push({ name: lastIdentifier.name + '.', type: 'table' });
-        } else if (typeof lastIdentifier.subQuery !== 'undefined') {
-          identifiers.push({ name: lastIdentifier.subQuery + '.', type: 'sub-query' });
-        }
-      }
-      tables.push(table);
-    } else if (tablePrimary.subQueryAlias) {
-      identifiers.push({ name: tablePrimary.subQueryAlias + '.', type: 'sub-query' });
-      tables.push({ identifierChain: [{ subQuery: tablePrimary.subQueryAlias }] });
-    }
-  });
-  if (identifiers.length > 0) {
-    if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
-      parser.yy.result.suggestIdentifiers = identifiers;
-    } else {
-      parser.yy.result.suggestIdentifiers = identifiers.concat(parser.yy.result.suggestIdentifiers);
-    }
-  }
-  parser.yy.result.suggestColumns.tables = tables;
-  if (parser.yy.result.suggestColumns.identifierChain && parser.yy.result.suggestColumns.identifierChain.length == 0) {
-    delete parser.yy.result.suggestColumns.identifierChain;
-  }
-  parser.yy.result.suggestColumns.linked = true;
-};
-
-var linkTablePrimaries = function () {
-  if (!parser.yy.cursorFound || typeof parser.yy.latestTablePrimaries === 'undefined') {
-    return;
-  }
-
-  SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) {
-    if (typeof parser.yy.result[suggestionType] !== 'undefined' && parser.yy.result[suggestionType].tablePrimaries && !parser.yy.result[suggestionType].linked) {
-      parser.yy.result[suggestionType].tables = [];
-      parser.yy.result[suggestionType].tablePrimaries.forEach(function (tablePrimary) {
-        if (!tablePrimary.subQueryAlias) {
-          parser.yy.result[suggestionType].tables.push(tablePrimary.alias ? { identifierChain: tablePrimary.identifierChain.concat(), alias: tablePrimary.alias } : { identifierChain: tablePrimary.identifierChain.concat() });
-        }
-      });
-      delete parser.yy.result[suggestionType].tablePrimaries;
-      parser.yy.result[suggestionType].linked = true;
-    }
-  });
-
-  if (typeof parser.yy.result.suggestColumns !== 'undefined' && !parser.yy.result.suggestColumns.linked) {
-    var tablePrimaries = filterTablePrimariesForOwner(parser.yy.result.suggestColumns.owner);
-    if (!parser.yy.result.suggestColumns.tables) {
-      parser.yy.result.suggestColumns.tables = [];
-    }
-    if (parser.yy.subQueries.length > 0) {
-      parser.yy.result.subQueries = parser.yy.subQueries;
-    }
-    if (typeof parser.yy.result.suggestColumns.identifierChain === 'undefined' || parser.yy.result.suggestColumns.identifierChain.length === 0) {
-      if (tablePrimaries.length > 1) {
-        convertTablePrimariesToSuggestions(tablePrimaries);
-      } else {
-        suggestLateralViewAliasesAsIdentifiers();
-        if (tablePrimaries.length == 1 && (tablePrimaries[0].alias || tablePrimaries[0].subQueryAlias)) {
-          convertTablePrimariesToSuggestions(tablePrimaries);
-        }
-        expandIdentifierChain(parser.yy.result.suggestColumns);
-      }
-    } else {
-      // Expand exploded views in the identifier chain
-      if (isHive() && !parser.yy.result.suggestColumns.linked) {
-        var originalLength = parser.yy.result.suggestColumns.identifierChain.length;
-        parser.yy.result.suggestColumns.identifierChain = parser.expandLateralViews(parser.yy.lateralViews, parser.yy.result.suggestColumns.identifierChain, true);
-        // Drop '*' keyword for lateral views
-        if (typeof parser.yy.result.suggestColumns !== 'undefined') {
-          if (parser.yy.result.suggestColumns.identifierChain.length > originalLength &&
-              typeof parser.yy.result.suggestKeywords !== 'undefined' &&
-              parser.yy.result.suggestKeywords.length === 1 &&
-              parser.yy.result.suggestKeywords[0].value === '*') {
-            delete parser.yy.result.suggestKeywords;
-          }
-          expandIdentifierChain(parser.yy.result.suggestColumns);
-        }
-      } else {
-        expandIdentifierChain(parser.yy.result.suggestColumns);
-      }
-    }
-  }
-
-  if (typeof parser.yy.result.colRef !== 'undefined' && !parser.yy.result.colRef.linked) {
-    expandIdentifierChain(parser.yy.result.colRef);
-
-    var primaries = filterTablePrimariesForOwner();
-    if (primaries.length === 0 || (primaries.length > 1 && parser.yy.result.colRef.identifierChain.length === 1)) {
-      parser.yy.result.colRef.identifierChain = [];
-    }
-  }
-  if (typeof parser.yy.result.suggestKeyValues !== 'undefined' && !parser.yy.result.suggestKeyValues.linked) {
-    expandIdentifierChain(parser.yy.result.suggestKeyValues);
-  }
-};
-
-var getSubQuery = function (cols) {
-  var columns = [];
-  cols.selectList.forEach(function (col) {
-    var result = {};
-    if (col.alias) {
-      result.alias = col.alias;
-    }
-    if (col.valueExpression && col.valueExpression.columnReference) {
-      result.identifierChain = col.valueExpression.columnReference
-    } else if (col.asterisk) {
-      result.identifierChain = [{asterisk: true}];
-    }
-    if (col.valueExpression && col.valueExpression.types && col.valueExpression.types.length === 1) {
-      result.type = col.valueExpression.types[0];
-    }
-
-    columns.push(result);
-  });
-
-  return {
-    columns: columns
-  };
-};
-
-var addTablePrimary = function (ref) {
-  if (typeof parser.yy.latestTablePrimaries === 'undefined') {
-    parser.yy.latestTablePrimaries = [];
-  }
-  parser.yy.latestTablePrimaries.push(ref);
-};
-
-var suggestNumbers = function (numbers) {
-  parser.yy.result.suggestNumbers = numbers;
-};
-
-var suggestFileFormats = function () {
-  if (isHive()) {
-    suggestKeywords(['AVRO', 'INPUTFORMAT', 'ORC', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
-  } else {
-    suggestKeywords(['AVRO', 'KUDU', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
-  }
-};
-
-var getKeywordsForOptionalsLR = function (optionals, keywords, override) {
-  var result = [];
-
-  for (var i = 0; i < optionals.length; i++) {
-    if (!optionals[i] && (typeof override === 'undefined' || override[i])) {
-      if (keywords[i] instanceof Array) {
-        result = result.concat(keywords[i]);
-      } else {
-        result.push(keywords[i]);
-      }
-    } else if (optionals[i]) {
-      break;
-    }
-  }
-  return result;
-};
-
-var suggestDdlAndDmlKeywords = function (extraKeywords) {
-  var keywords = ['ALTER', 'CREATE', 'DESCRIBE', 'DROP', 'GRANT', 'INSERT', 'REVOKE', 'SELECT', 'SET', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE', 'WITH'];
-
-  if (extraKeywords) {
-    keywords = keywords.concat(extraKeywords);
-  }
-
-  if (isHive()) {
-    keywords = keywords.concat(['ANALYZE TABLE', 'DELETE', 'EXPORT', 'IMPORT', 'LOAD', 'MSCK', 'RELOAD FUNCTION', 'RESET']);
-  }
-
-  if (isImpala()) {
-    keywords = keywords.concat(['COMPUTE', 'INVALIDATE METADATA', 'LOAD', 'REFRESH']);
-  }
-
-  suggestKeywords(keywords);
-};
-
-var checkForSelectListKeywords = function (selectList) {
-  if (selectList.length === 0) {
-    return;
-  }
-  var last = selectList[selectList.length - 1];
-  if (!last || !last.valueExpression) {
-    return;
-  }
-  var valueExpressionKeywords = getValueExpressionKeywords(last.valueExpression);
-  var keywords = [];
-  if (last.suggestKeywords) {
-    keywords = keywords.concat(last.suggestKeywords);
-  }
-  if (valueExpressionKeywords.suggestKeywords) {
-    keywords = keywords.concat(valueExpressionKeywords.suggestKeywords);
-  }
-  if (valueExpressionKeywords.suggestColRefKeywords) {
-    suggestColRefKeywords(valueExpressionKeywords.suggestColRefKeywords);
-    addColRefIfExists(last.valueExpression);
-  }
-  if (!last.alias) {
-    keywords.push('AS');
-  }
-  if (keywords.length > 0) {
-    suggestKeywords(keywords);
-  }
-};
-
-var checkForKeywords = function (expression) {
-  if (expression) {
-    if (expression.suggestKeywords && expression.suggestKeywords.length > 0) {
-      suggestKeywords(expression.suggestKeywords);
-    }
-    if (expression.suggestColRefKeywords) {
-      suggestColRefKeywords(expression.suggestColRefKeywords);
-      addColRefIfExists(expression);
-    }
-  }
-};
-
-var createWeightedKeywords = function (keywords, weight) {
-  var result = [];
-  keywords.forEach(function (keyword) {
-    if (typeof keyword.weight !== 'undefined') {
-      keyword.weight = weight + (keyword.weight / 10);
-      result.push(keyword);
-    } else {
-      result.push({value: keyword, weight: weight });
-    }
-  });
-  return result;
-};
-
-var suggestKeywords = function (keywords) {
-  var weightedKeywords = [];
-  if (keywords.length == 0) {
-    return;
-  }
-  keywords.forEach(function (keyword) {
-    if (typeof keyword.weight !== 'undefined') {
-      weightedKeywords.push(keyword);
-    } else {
-      weightedKeywords.push({ value: keyword, weight: -1 })
-    }
-  });
-  weightedKeywords.sort(function (a, b) {
-    if (a.weight !== b.weight) {
-      return b.weight - a.weight;
-    }
-    return a.value.localeCompare(b.value);
-  });
-  parser.yy.result.suggestKeywords = weightedKeywords;
-};
-
-var suggestColRefKeywords = function (colRefKeywords) {
-  parser.yy.result.suggestColRefKeywords = colRefKeywords;
-};
-
-var suggestTablesOrColumns = function (identifier) {
-  if (typeof parser.yy.latestTablePrimaries == 'undefined') {
-    suggestTables({ identifierChain: [{ name: identifier }] });
-    return;
-  }
-  var tableRef = parser.yy.latestTablePrimaries.filter(function (tablePrimary) {
-    return tablePrimary.alias === identifier;
-  });
-  if (tableRef.length > 0) {
-    suggestColumns({identifierChain: [{ name: identifier }]});
-  } else {
-    suggestTables({ identifierChain: [{ name: identifier }] });
-  }
-};
-
-var suggestFunctions = function (details) {
-  parser.yy.result.suggestFunctions = details || {};
-};
-
-var suggestAggregateFunctions = function () {
-  var primaries = [];
-  var aliases = {};
-  parser.yy.latestTablePrimaries.forEach(function (primary) {
-    if (typeof primary.alias !== 'undefined') {
-      aliases[primary.alias] = true;
-    }
-    // Drop if the first one refers to a table alias (...FROM tbl t, t.map tm ...)
-    if (typeof primary.identifierChain !== 'undefined' && !aliases[primary.identifierChain[0].name] && typeof primary.owner === 'undefined') {
-      primaries.push(primary);
-    }
-  });
-  parser.yy.result.suggestAggregateFunctions = { tablePrimaries: primaries };
-};
-
-var suggestAnalyticFunctions = function () {
-  parser.yy.result.suggestAnalyticFunctions = true;
-};
-
-var suggestColumns = function (details) {
-  if (typeof details === 'undefined') {
-    details = {identifierChain: []};
-  } else if (typeof details.identifierChain === 'undefined') {
-    details.identifierChain = [];
-  }
-  parser.yy.result.suggestColumns = details;
-};
-
-var suggestGroupBys = function (details) {
-  parser.yy.result.suggestGroupBys = details || {};
-};
-
-var suggestOrderBys = function (details) {
-  parser.yy.result.suggestOrderBys = details || {};
-};
-
-var suggestFilters = function (details) {
-  parser.yy.result.suggestFilters = details || {};
-};
-
-var suggestKeyValues = function (details) {
-  parser.yy.result.suggestKeyValues = details || {};
-};
-
-var suggestTables = function (details) {
-  parser.yy.result.suggestTables = details || {};
-};
-
-var adjustLocationForCursor = function (location) {
-  // columns are 0-based and lines not, so add 1 to cols
-  var newLocation = {
-    first_line: location.first_line,
-    last_line: location.last_line,
-    first_column: location.first_column + 1,
-    last_column: location.last_column + 1
-  };
-  if (parser.yy.cursorFound) {
-    if (parser.yy.cursorFound.first_line === newLocation.first_line && parser.yy.cursorFound.last_column <= newLocation.first_column) {
-      var additionalSpace = parser.yy.partialLengths.left + parser.yy.partialLengths.right;
-      additionalSpace -= parser.yy.partialCursor ? 1 : 3; // For some reason the normal cursor eats 3 positions.
-      newLocation.first_column = newLocation.first_column + additionalSpace;
-      newLocation.last_column = newLocation.last_column + additionalSpace;
-    }
-  }
-  return newLocation;
-};
-
-var addFunctionLocation = function (location, functionName) {
-  // Remove trailing '(' from location
-  var adjustedLocation = {
-    first_line: location.first_line,
-    last_line: location.last_line,
-    first_column: location.first_column,
-    last_column: location.last_column - 1
-  };
-  parser.yy.locations.push({
-    type: 'function',
-    location: adjustLocationForCursor(adjustedLocation),
-    function: functionName.toLowerCase()
-  });
-};
-
-var addStatementLocation = function (location) {
-  // Don't report lonely cursor as a statement
-  if (location.first_line === location.last_line && Math.abs(location.last_column - location.first_column) === 1) {
-    return;
-  }
-  var adjustedLocation;
-  if (parser.yy.cursorFound && parser.yy.cursorFound.last_line === location.last_line &&
-      parser.yy.cursorFound.first_column >= location.first_column && parser.yy.cursorFound.last_column <= location.last_column) {
-    var additionalSpace = parser.yy.partialLengths.left + parser.yy.partialLengths.right;
-    adjustedLocation = {
-      first_line: location.first_line,
-      last_line: location.last_line,
-      first_column: location.first_column + 1,
-      last_column: location.last_column + additionalSpace - (parser.yy.partialCursor ? 0 : 2)
-    }
-  } else {
-    adjustedLocation = {
-      first_line: location.first_line,
-      last_line: location.last_line,
-      first_column: location.first_column + 1,
-      last_column: location.last_column + 1
-    }
-  }
-
-  parser.yy.locations.push({
-    type: 'statement',
-    location: adjustedLocation
-  });
-};
-
-var addHdfsLocation = function (location, path) {
-  parser.yy.locations.push({
-    type: 'hdfs',
-    location: adjustLocationForCursor(location),
-    path: path
-  });
-};
-
-var addDatabaseLocation = function (location, identifierChain) {
-  parser.yy.locations.push({
-    type: 'database',
-    location: adjustLocationForCursor(location),
-    identifierChain: identifierChain
-  });
-};
-
-var addTableLocation = function (location, identifierChain) {
-  parser.yy.locations.push({
-    type: 'table',
-    location: adjustLocationForCursor(location),
-    identifierChain: identifierChain
-  });
-};
-
-var addAsteriskLocation = function (location, identifierChain) {
-  parser.yy.locations.push({
-    type: 'asterisk',
-    location: adjustLocationForCursor(location),
-    identifierChain: identifierChain
-  });
-};
-
-var addColumnLocation = function (location, identifierChain) {
-  parser.yy.locations.push({
-    type: 'column',
-    location: adjustLocationForCursor(location),
-    identifierChain: identifierChain
-  });
-};
-
-var addUnknownLocation = function (location, identifierChain) {
-  parser.yy.locations.push({
-    type: 'unknown',
-    location: adjustLocationForCursor(location),
-    identifierChain: identifierChain
-  });
-};
-
-var suggestDatabases = function (details) {
-  parser.yy.result.suggestDatabases = details || {};
-};
-
-var suggestHdfs = function (details) {
-  parser.yy.result.suggestHdfs = details || {};
-};
-
-var suggestValues = function (details) {
-  parser.yy.result.suggestValues = details || {};
-};
-
-var determineCase = function (text) {
-  if (!parser.yy.caseDetermined) {
-    parser.yy.lowerCase = text.toLowerCase() === text;
-    parser.yy.caseDetermined = true;
-  }
-};
-
-parser.handleQuotedValueWithCursor = function(lexer, yytext, yylloc, quoteChar) {
-  if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) {
-    parser.yy.partialCursor = yytext.indexOf('\u2021') !== -1;
-    var cursorIndex = parser.yy.partialCursor ? yytext.indexOf('\u2021') : yytext.indexOf('\u2020');
-    parser.yy.cursorFound = {
-      first_line: yylloc.first_line,
-      last_line: yylloc.last_line,
-      first_column: yylloc.first_column + cursorIndex,
-      last_column: yylloc.first_column + cursorIndex + 1
-    };
-    var remainder = yytext.substring(cursorIndex + 1);
-    var remainingQuotes = (lexer.upcomingInput().match(new RegExp(quoteChar, 'g')) || []).length;
-    if (remainingQuotes > 0 && remainingQuotes & 1  != 0) {
-      parser.yy.missingEndQuote = false;
-      lexer.input();
-    } else {
-      parser.yy.missingEndQuote = true;
-      lexer.unput(remainder);
-    }
-    lexer.popState();
-    return true;
-  }
-  return false;
-};
-
-var lexerModified = false;
-
-/**
- * Main parser function
- */
-parser.parseSql = function (beforeCursor, afterCursor, dialect, debug) {
-  // Jison counts CRLF as two lines in the locations
-  beforeCursor = beforeCursor.replace(/\r\n|\n\r/gm, '\n');
-  afterCursor = afterCursor.replace(/\r\n|\n\r/gm, '\n');
-  parser.yy.result = {locations: []};
-  parser.yy.lowerCase = false;
-  parser.yy.locations = [];
-  parser.yy.allLocations = [];
-  parser.yy.subQueries = [];
-  parser.yy.errors = [];
-  parser.yy.selectListAliases = [];
-
-  parser.yy.locationsStack = [];
-  parser.yy.primariesStack = [];
-  parser.yy.lateralViewsStack = [];
-  parser.yy.subQueriesStack = [];
-  parser.yy.resultStack = [];
-  parser.yy.selectListAliasesStack = [];
-
-  delete parser.yy.caseDetermined;
-  delete parser.yy.cursorFound;
-  delete parser.yy.partialCursor;
-
-  prepareNewStatement();
-
-  var REASONABLE_SURROUNDING_LENGTH = 150000; // About 3000 lines before and after
-
-  if (beforeCursor.length > REASONABLE_SURROUNDING_LENGTH) {
-    if ((beforeCursor.length - beforeCursor.lastIndexOf(';')) > REASONABLE_SURROUNDING_LENGTH) {
-      // Bail out if the last complete statement is more than 150000 chars before
-      return {};
-    }
-    // Cut it at the first statement found within 150000 chars before
-    var lastReasonableChunk = beforeCursor.substring(beforeCursor.length - REASONABLE_SURROUNDING_LENGTH);
-    beforeCursor = lastReasonableChunk.substring(lastReasonableChunk.indexOf(';') + 1);
-  }
-
-  if (afterCursor.length > REASONABLE_SURROUNDING_LENGTH) {
-    if ((afterCursor.length - afterCursor.indexOf(';')) > REASONABLE_SURROUNDING_LENGTH) {
-      // No need to bail out for what's comes after, we can still get keyword completion
-      afterCursor = '';
-    } else {
-      // Cut it at the last statement found within 150000 chars after
-      var firstReasonableChunk = afterCursor.substring(0, REASONABLE_SURROUNDING_LENGTH);
-      afterCursor = firstReasonableChunk.substring(0, firstReasonableChunk.lastIndexOf(';'));
-    }
-  }
-
-  parser.yy.partialLengths = parser.identifyPartials(beforeCursor, afterCursor);
-
-  if (parser.yy.partialLengths.left > 0) {
-    beforeCursor = beforeCursor.substring(0, beforeCursor.length - parser.yy.partialLengths.left);
-  }
-
-  if (parser.yy.partialLengths.right > 0) {
-    afterCursor = afterCursor.substring(parser.yy.partialLengths.right);
-  }
-
-  parser.yy.activeDialect = (dialect !== 'hive' && dialect !== 'impala') ? undefined : dialect;
-
-  // Hack to set the inital state of the lexer without first having to hit a token
-  // has to be done as the first token found can be dependant on dialect
-  if (!lexerModified) {
-    var originalSetInput = parser.lexer.setInput;
-    parser.lexer.setInput = function (input, yy) {
-      var lexer = originalSetInput.bind(parser.lexer)(input, yy);
-      if (typeof parser.yy.activeDialect !== 'undefined') {
-        lexer.begin(parser.yy.activeDialect);
-      }
-      return lexer;
-    };
-    lexerModified = true;
-  }
-
-  var result;
-  try {
-    // Add |CURSOR| or |PARTIAL_CURSOR| to represent the different cursor states in the lexer
-    result = parser.parse(beforeCursor + (beforeCursor.length == 0 || /[\s\(]$$/.test(beforeCursor) ? ' \u2020 ' : '\u2021') + afterCursor);
-  } catch (err) {
-    // On any error try to at least return any existing result
-    if (typeof parser.yy.result === 'undefined') {
-      throw err;
-    }
-    if (debug) {
-      console.log(err);
-      console.error(err.stack);
-    }
-    result = parser.yy.result;
-  }
-  if (parser.yy.errors.length > 0) {
-    parser.yy.result.errors = parser.yy.errors;
-    if (debug) {
-      console.log(parser.yy.errors);
-    }
-  }
-  try {
-    linkTablePrimaries();
-    commitLocations();
-    // Clean up and prioritize
-    prioritizeSuggestions();
-  } catch (err) {
-    if (debug) {
-      console.log(err);
-      console.error(err.stack);
-    }
-  }
-
-
-  parser.yy.allLocations.sort(function (a, b) {
-    if (a.location.first_line !== b.location.first_line) {
-      return a.location.first_line - b.location.first_line;
-    }
-    return a.location.first_column - b.location.first_column;
-  });
-  parser.yy.result.locations = parser.yy.allLocations;
-
-  parser.yy.result.locations.forEach(function (location) {
-    delete location.linked;
-  });
-  if (typeof parser.yy.result.suggestColumns !== 'undefined') {
-    delete parser.yy.result.suggestColumns.linked;
-  }
-
-  SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) {
-    if (typeof parser.yy.result[suggestionType] !== 'undefined') {
-      delete parser.yy.result[suggestionType].linked;
-    }
-  });
-
-  if (typeof parser.yy.result.colRef !== 'undefined') {
-    delete parser.yy.result.colRef.linked;
-  }
-  if (typeof parser.yy.result.suggestKeyValues !== 'undefined') {
-    delete parser.yy.result.suggestKeyValues.linked;
-  }
-
-  if (typeof result.error !== 'undefined' && typeof result.error.expected !== 'undefined') {
-    // Remove any expected tokens from other dialects, jison doesn't remove tokens from other lexer states.
-    var actualExpected = {};
-    result.error.expected.forEach(function (expected) {
-      var match = expected.match(/\<([a-z]+)\>(.*)/);
-      if (match !== null) {
-        if (typeof parser.yy.activeDialect !== 'undefined' && parser.yy.activeDialect === match[1]) {
-          actualExpected[("'" + match[2])] = true;
-        }
-      } else if (expected.indexOf('CURSOR') == -1) {
-        actualExpected[expected] = true;
-      }
-    });
-    result.error.expected = Object.keys(actualExpected);
-  }
-
-  if (typeof result.error !== 'undefined' && result.error.recoverable) {
-    delete result.error;
-  }
-
-  // Adjust all the statement locations to include white space surrounding them
-  var lastStatementLocation = null;
-  result.locations.forEach(function (location) {
-    if (location.type === 'statement') {
-      if (lastStatementLocation === null) {
-        location.location.first_line = 1;
-        location.location.first_column = 1;
-      } else {
-        location.location.first_line = lastStatementLocation.location.last_line;
-        location.location.first_column = lastStatementLocation.location.last_column + 1;
-      }
-      lastStatementLocation = location;
-    }
-  });
-
-  return result;
-};

+ 1 - 0
desktop/core/src/desktop/templates/hue.mako

@@ -469,6 +469,7 @@ ${ hueIcons.symbols() }
 <script src="${ static('desktop/ext/js/dropzone.min.js') }"></script>
 
 # Task History
+<script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sql.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter2.js') }"></script>

+ 1 - 1
desktop/core/src/desktop/templates/jasmineRunner.html

@@ -96,7 +96,7 @@
   <script type="text/javascript" src="../static/desktop/js/hdfsAutocompleter.js"></script>
   <script type="text/javascript" src="../static/desktop/spec/hdfsAutocompleterSpec.js"></script>
 
-
+  <script type="text/javascript" src="../static/desktop/js/autocomplete/sqlParseSupport.js"></script>
   <script type="text/javascript" src="../static/desktop/js/autocomplete/sql.js"></script>
   <script type="text/javascript" src="../static/desktop/spec/autocomplete/sqlSpec.js"></script>
 

+ 1 - 0
desktop/libs/indexer/src/indexer/templates/importer.mako

@@ -30,6 +30,7 @@
 ${ commonheader(_("Importer"), "indexer", user, request, "60px") | n,unicode }
 
 ## TODO lot of those re-imported
+<script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sql.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter2.js') }"></script>

+ 1 - 0
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -61,6 +61,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, ENABLE_
 
 <script src="${ static('desktop/js/ko.selectize.js') }"></script>
 <script src="${ static('desktop/js/sqlFunctions.js') }"></script>
+<script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sql.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter2.js') }"></script>

+ 1 - 0
desktop/libs/notebook/src/notebook/templates/editor_m.mako

@@ -173,6 +173,7 @@ ${ commonheader_m(editor_type, editor_type, user, request, "68px") | n,unicode }
 <script src="${ static('desktop/js/ace.extended.js') }"></script>
 <script src="${ static('desktop/js/ko.switch-case.js') }"></script>
 <script src="${ static('desktop/js/sqlFunctions.js') }"></script>
+<script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sql.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter2.js') }"></script>

+ 4 - 6
tools/jison/hue-jison.sh

@@ -20,23 +20,21 @@ echo ""
 echo "Generating parser..."
 
 pushd ../../desktop/core/src/desktop/static/desktop/js/autocomplete/jison
-echo "%%" > sql_end.jison
 
 # For quick version of select and no support for value expressions (i.e. a = b or a IN (1, 2, 3))
-# cat sql_main.jison sql_end.jison ../sql_support.js > sql.jison
+# cat sql_main.jison ../sql_end.jison > sql.jison
 
 # For quick version of select with value expressions
-#cat sql_valueExpression_dev.jison sql_valueExpression.jison sql_end.jison ../sql_support.js > sql.jison
+#cat sql_valueExpression_dev.jison sql_valueExpression.jison ../sql_end.jison > sql.jison
 
 # For quick version of select with create only and no support for value expressions (i.e. a = b or a IN (1, 2, 3))
-# cat sql_main.jison sql_create.jison sql_end.jison ../sql_support.js > sql.jison
+# cat sql_main.jison sql_create.jison sql_end.jison > sql.jison
 
-cat sql_main.jison sql_valueExpression.jison sql_error.jison sql_alter.jison sql_analyze.jison sql_create.jison sql_drop.jison sql_grant.jison sql_insert.jison sql_load.jison sql_set.jison sql_show.jison sql_update.jison sql_use.jison sql_end.jison ../sql_support.js > sql.jison
+cat sql_main.jison sql_valueExpression.jison sql_error.jison sql_alter.jison sql_analyze.jison sql_create.jison sql_drop.jison sql_grant.jison sql_insert.jison sql_load.jison sql_set.jison sql_show.jison sql_update.jison sql_use.jison ../sql_end.jison > sql.jison
 
 jison sql.jison sql.jisonlex
 cat license.txt sql.js > ../sql.js
 rm sql.jison
 rm sql.js
-rm sql_end.jison
 popd
 echo "Done!"

部分文件因文件數量過多而無法顯示