浏览代码

HUE-9115 [editor] Revert the flink parser to its originally cloned state to fix the failing tests

Johan Ahlen 5 年之前
父节点
当前提交
6125870f66

+ 60 - 113
desktop/core/src/desktop/js/parse/jison/sql/flink/sql.jisonlex

@@ -29,183 +29,130 @@
 <between>'AND'                             { this.popState(); return 'BETWEEN_AND'; }
 
 // Reserved Keywords
-'ADVANCE'                                  { return 'ADVANCE'; }
-'ANALYZE'                                  { return 'ANALYZE'; }
+'ALL'                                      { return 'ALL'; }
+'ALTER'                                    { parser.determineCase(yytext); parser.addStatementTypeLocation('ALTER', yylloc, yy.lexer.upcomingInput()); return 'ALTER'; }
 'AND'                                      { return 'AND'; }
-'ARRAY'                                    { return 'ARRAY'; }
 'AS'                                       { return 'AS'; }
-'AT'                                       { return 'AT'; }
-'BEGINNING'                                { return 'BEGINNING' }
+'ASC'                                      { return 'ASC'; }
 'BETWEEN'                                  { this.begin('between'); return 'BETWEEN'; }
 'BIGINT'                                   { return 'BIGINT'; }
 'BOOLEAN'                                  { return 'BOOLEAN'; }
 'BY'                                       { return 'BY'; }
+'CASCADE'                                  { return 'CASCADE'; }
 'CASE'                                     { return 'CASE'; }
-'CAST'                                     { return 'CAST'; }
-'CATALOG'                                  { return 'CATALOG'; }
-'CHANGES'                                  { return 'CHANGES'; }
-'COLUMN'                                   { return 'COLUMN'; }
-'COLUMNS'                                  { return 'COLUMNS'; }
-'CONNECTOR'                                { return 'CONNECTOR'; }
-'CONNECTORS'                               { return 'CONNECTORS'; }
+'CHAR'                                     { return 'CHAR'; }
+'COMMENT'                                  { return 'COMMENT'; }
 'CREATE'                                   { parser.determineCase(yytext); return 'CREATE'; }
-'DATE'                                     { return 'DATE'; }
-'DAY'                                      { return 'DAY'; }
+'CROSS'                                    { return 'CROSS'; }
+'CURRENT'                                  { return 'CURRENT'; }
+'DATABASE'                                 { return 'DATABASE'; }
 'DECIMAL'                                  { return 'DECIMAL'; }
-'DELETE'                                   { return 'DELETE'; }
-'DESCRIBE'                                 { return 'DESCRIBE'; }
+'DESC'                                     { return 'DESC'; }
 'DISTINCT'                                 { return 'DISTINCT'; }
+'DIV'                                      { return 'ARITHMETIC_OPERATOR'; }
 'DOUBLE'                                   { return 'DOUBLE'; }
 'DROP'                                     { parser.determineCase(yytext); parser.addStatementTypeLocation('DROP', yylloc, yy.lexer.upcomingInput()); return 'DROP'; }
 'ELSE'                                     { return 'ELSE'; }
-'EMIT'                                     { return 'EMIT'; }
 'END'                                      { return 'END'; }
 'EXISTS'                                   { parser.yy.correlatedSubQuery = true; return 'EXISTS'; }
-'EXPLAIN'                                  { parser.determineCase(yytext); return 'EXPLAIN'; }
-'EXPORT'                                   { return 'EXPORT'; }
-'EXTENDED'                                 { return 'EXTENDED'; }
+'FALSE'                                    { return 'FALSE'; }
+'FLOAT'                                    { return 'FLOAT'; }
+'FOLLOWING'                                { return 'FOLLOWING'; }
 'FROM'                                     { parser.determineCase(yytext); return 'FROM'; }
 'FULL'                                     { return 'FULL'; }
-'FUNCTION'                                 { return 'FUNCTION'; }
-'FUNCTIONS'                                { return 'FUNCTIONS'; }
 'GROUP'                                    { return 'GROUP'; }
 'HAVING'                                   { return 'HAVING'; }
-'HOPPING'                                  { return 'HOPPING'; }
-'HOUR'                                     { return 'HOUR'; }
-'HOURS'                                    { return 'HOURS'; }
 'IF'                                       { return 'IF'; }
 'IN'                                       { return 'IN'; }
 'INNER'                                    { return 'INNER'; }
 'INSERT'                                   { return 'INSERT'; }
 'INT'                                      { return 'INT'; }
-'INTEGER'                                  { return 'INTEGER'; }
 'INTO'                                     { return 'INTO'; }
 'IS'                                       { return 'IS'; }
 'JOIN'                                     { return 'JOIN'; }
-'KEY'                                      { return 'KEY'; }
 'LEFT'                                     { return 'LEFT'; }
 'LIKE'                                     { return 'LIKE'; }
 'LIMIT'                                    { return 'LIMIT'; }
-'LIST'                                     { return 'LIST'; }
-'LOAD'                                     { return 'LOAD'; }
-'MAP'                                      { return 'MAP'; }
-'MILLISECOND'                              { return 'MILLISECOND'; }
-'MILLISECONDS'                             { return 'MILLISECONDS'; }
-'MINUTE'                                   { return 'MINUTE'; }
-'MINUTES'                                  { return 'MINUTES'; }
-'MONTH'                                    { return 'MONTH'; }
-'MONTHS'                                   { return 'MONTHS'; }
 'NOT'                                      { return 'NOT'; }
 'NULL'                                     { return 'NULL'; }
 'ON'                                       { return 'ON'; }
+'OPTION'                                   { return 'OPTION'; }
 'OR'                                       { return 'OR'; }
+'ORDER'                                    { return 'ORDER'; }
 'OUTER'                                    { return 'OUTER'; }
 'PARTITION'                                { return 'PARTITION'; }
-'PARTITIONS'                               { return 'PARTITIONS'; }
-'PRINT'                                    { return 'PRINT'; }
-'PROPERTIES'                               { return 'PROPERTIES'; }
-'QUERIES'                                  { return 'QUERIES'; }
-'QUERY'                                    { return 'QUERY'; }
-'RENAME'                                   { return 'RENAME'; }
-'RESET'                                    { return 'RESET'; }
+'PRECEDING'                                { return 'PRECEDING'; }
+'PURGE'                                    { return 'PURGE'; }
+'RANGE'                                    { return 'RANGE'; }
+'REGEXP'                                   { return 'REGEXP'; }
 'RIGHT'                                    { return 'RIGHT'; }
-'RUN'                                      { return 'RUN'; }
-'SAMPLE'                                   { return 'SAMPLE'; }
-'SCRIPT'                                   { return 'SCRIPT'; }
-'SECOND'                                   { return 'SECOND'; }
-'SECOND'                                   { return 'SECOND'; }
+'RLIKE'                                    { return 'RLIKE'; }
+'ROW'                                      { return 'ROW'; }
+'ROLE'                                     { return 'ROLE'; }
+'ROWS'                                     { return 'ROWS'; }
+'SCHEMA'                                   { return 'SCHEMA'; }
 'SELECT'                                   { parser.determineCase(yytext); parser.addStatementTypeLocation('SELECT', yylloc); return 'SELECT'; }
-'SESSION'                                  { return 'SESSION'; }
+'SEMI'                                     { return 'SEMI'; }
 'SET'                                      { parser.determineCase(yytext); parser.addStatementTypeLocation('SET', yylloc); return 'SET'; }
 'SHOW'                                     { parser.determineCase(yytext); parser.addStatementTypeLocation('SHOW', yylloc); return 'SHOW'; }
-'SINK'                                     { return 'SINK'; }
-'SOURCE'                                   { return 'SOURCE'; }
-'STREAM'                                   { return 'STREAM'; }
-'STREAMS'                                  { return 'STREAMS'; }
+'SMALLINT'                                 { return 'SMALLINT'; }
 'STRING'                                   { return 'STRING'; }
-'STRUCT'                                   { return 'STRUCT'; }
 'TABLE'                                    { return 'TABLE'; }
-'TABLES'                                   { return 'TABLES'; }
-'TERMINATE'                                { return 'TERMINATE'; }
 'THEN'                                     { return 'THEN'; }
-'TIME'                                     { return 'TIME'; }
 'TIMESTAMP'                                { return 'TIMESTAMP'; }
+'TINYINT'                                  { return 'TINYINT'; }
 'TO'                                       { return 'TO'; }
 'TRUE'                                     { return 'TRUE'; }
-'TOPIC'                                    { return 'TOPIC'; }
-'TOPICS'                                   { return 'TOPICS'; }
-'TUMBLING'                                 { return 'TUMBLING'; }
-'TYPE'                                     { return 'TYPE'; }
-'TYPES'                                    { return 'TYPES'; }
-'UNSET'                                    { return 'UNSET'; }
+'TRUNCATE'                                 { parser.determineCase(yytext); parser.addStatementTypeLocation('TRUNCATE', yylloc, yy.lexer.upcomingInput()); return 'TRUNCATE'; }
+'UNBOUNDED'                                { return 'UNBOUNDED'; }
+'UNION'                                    { return 'UNION'; }
+'UPDATE'                                   { parser.determineCase(yytext); return 'UPDATE'; }
+'USE'                                      { parser.determineCase(yytext); parser.addStatementTypeLocation('USE', yylloc); return 'USE'; }
 'VALUES'                                   { return 'VALUES'; }
 'VARCHAR'                                  { return 'VARCHAR'; }
+'VIEW'                                     { return 'VIEW'; }
 'WHEN'                                     { return 'WHEN'; }
 'WHERE'                                    { return 'WHERE'; }
 'WITH'                                     { parser.determineCase(yytext); parser.addStatementTypeLocation('WITH', yylloc); return 'WITH'; }
-'WITHIN'                                   { return 'WITHIN'; }
-'YEAR'                                     { return 'YEAR'; }
-'YEARS'                                    { return 'YEARS'; }
-'ZONE'                                     { return 'ZONE'; }
-
-// --- UDFs ---
-ABS\s*\(                                   { yy.lexer.unput('('); yytext = 'abs'; parser.addFunctionLocation(yylloc, yytext); return 'ABS'; }
-ARRAYCONTAINS\s*\(                         { yy.lexer.unput('('); yytext = 'arraycontains'; parser.addFunctionLocation(yylloc, yytext); return 'ARRAYCONTAINS'; }
-CEIL\s*\(                                  { yy.lexer.unput('('); yytext = 'ceil'; parser.addFunctionLocation(yylloc, yytext); return 'CEIL'; }
-CONCAT\s*\(                                { yy.lexer.unput('('); yytext = 'concat'; parser.addFunctionLocation(yylloc, yytext); return 'CONCAT'; }
-DATETOSTRING\s*\(                          { yy.lexer.unput('('); yytext = 'datetostring'; parser.addFunctionLocation(yylloc, yytext); return 'DATETOSTRING'; }
-ELT\s*\(                                   { yy.lexer.unput('('); yytext = 'elt'; parser.addFunctionLocation(yylloc, yytext); return 'ELT'; }
-EXTRACTJSONFIELD\s*\(                      { yy.lexer.unput('('); yytext = 'extractjsonfield'; parser.addFunctionLocation(yylloc, yytext); return 'EXTRACTJSONFIELD'; }
-FIELD\s*\(                                 { yy.lexer.unput('('); yytext = 'field'; parser.addFunctionLocation(yylloc, yytext); return 'FIELD'; }
-FLOOR\s*\(                                 { yy.lexer.unput('('); yytext = 'floor'; parser.addFunctionLocation(yylloc, yytext); return 'FLOOR'; }
-GEO_DISTANCE\s*\(                          { yy.lexer.unput('('); yytext = 'geo_distance'; parser.addFunctionLocation(yylloc, yytext); return 'GEO_DISTANCE'; }
-IFNULL\s*\(                                { yy.lexer.unput('('); yytext = 'ifnull'; parser.addFunctionLocation(yylloc, yytext); return 'IFNULL'; }
-LCASE\s*\(                                 { yy.lexer.unput('('); yytext = 'lcase'; parser.addFunctionLocation(yylloc, yytext); return 'LCASE'; }
-LEN\s*\(                                   { yy.lexer.unput('('); yytext = 'len'; parser.addFunctionLocation(yylloc, yytext); return 'LEN'; }
-MASK\s*\(                                  { yy.lexer.unput('('); yytext = 'msk'; parser.addFunctionLocation(yylloc, yytext); return 'MASK'; }
-MASK_KEEP_LEFT\s*\(                        { yy.lexer.unput('('); yytext = 'mask_keep_left'; parser.addFunctionLocation(yylloc, yytext); return 'MASK_KEEP_LEFT'; }
-MASK_KEEP_RIGHT\s*\(                       { yy.lexer.unput('('); yytext = 'mask_keep_right'; parser.addFunctionLocation(yylloc, yytext); return 'MASK_KEEP_RIGHT'; }
-MASK_LEFT\s*\(                             { yy.lexer.unput('('); yytext = 'mask_left'; parser.addFunctionLocation(yylloc, yytext); return 'MASK_LEFT'; }
-MASK_RIGHT\s*\(                            { yy.lexer.unput('('); yytext = 'mask_right'; parser.addFunctionLocation(yylloc, yytext); return 'MASK_RIGHT'; }
-RANDOM\s*\(                                { yy.lexer.unput('('); yytext = 'random'; parser.addFunctionLocation(yylloc, yytext); return 'RANDOM'; }
-ROUND\s*\(                                 { yy.lexer.unput('('); yytext = 'round'; parser.addFunctionLocation(yylloc, yytext); return 'ROUND'; }
-SPLIT\s*\(                                 { yy.lexer.unput('('); yytext = 'split'; parser.addFunctionLocation(yylloc, yytext); return 'SPLIT'; }
-STRINGTODATE\s*\(                          { yy.lexer.unput('('); yytext = 'stringtodate'; parser.addFunctionLocation(yylloc, yytext); return 'STRINGTODATE'; }
-STRINGTOTIMESTAMP\s*\(                     { yy.lexer.unput('('); yytext = 'stringtotimestamp'; parser.addFunctionLocation(yylloc, yytext); return 'STRINGTOTIMESTAMP'; }
-SUBSTRING\s*\(                             { yy.lexer.unput('('); yytext = 'substring'; parser.addFunctionLocation(yylloc, yytext); return 'SUBSTRING'; }
-TIMESTAMPTOSTRING\s*\(                     { yy.lexer.unput('('); yytext = 'timestamptostring'; parser.addFunctionLocation(yylloc, yytext); return 'TIMESTAMPTOSTRING'; }
-TRIM\s*\(                                  { yy.lexer.unput('('); yytext = 'trim'; parser.addFunctionLocation(yylloc, yytext); return 'TRIM'; }
-UCASE\s*\(                                 { yy.lexer.unput('('); yytext = 'ucase'; parser.addFunctionLocation(yylloc, yytext); return 'UCASE'; }
-URL_DECODE_PARAM\s*\(                      { yy.lexer.unput('('); yytext = 'url_decode_param'; parser.addFunctionLocation(yylloc, yytext); return 'URL_DECODE_PARAM'; }
-URL_ENCODE_PARAM\s*\(                      { yy.lexer.unput('('); yytext = 'urel_encode_param'; parser.addFunctionLocation(yylloc, yytext); return 'URL_ENCODE_PARAM'; }
-URL_EXTRACT_FRAGMENT\s*\(                  { yy.lexer.unput('('); yytext = 'url_extract_fragment'; parser.addFunctionLocation(yylloc, yytext); return 'URL_EXTRACT_FRAGMENT'; }
-URL_EXTRACT_HOST\s*\(                      { yy.lexer.unput('('); yytext = 'url_extract_host'; parser.addFunctionLocation(yylloc, yytext); return 'URL_EXTRACT_HOST'; }
-URL_EXTRACT_PARAMETER\s*\(                 { yy.lexer.unput('('); yytext = 'url_extract_parameter'; parser.addFunctionLocation(yylloc, yytext); return 'URL_EXTRACT_PARAMETER'; }
-URL_EXTRACT_PATH\s*\(                      { yy.lexer.unput('('); yytext = 'url_extrct_path'; parser.addFunctionLocation(yylloc, yytext); return 'URL_EXTRACT_PATH'; }
-URL_EXTRACT_PORT\s*\(                      { yy.lexer.unput('('); yytext = 'url_extract_port'; parser.addFunctionLocation(yylloc, yytext); return 'URL_EXTRACT_PORT'; }
-URL_EXTRACT_PROTOCOL\s*\(                  { yy.lexer.unput('('); yytext = 'url_extract_protocol'; parser.addFunctionLocation(yylloc, yytext); return 'URL_EXTRACT_PROTOCOL'; }
-URL_EXTRACT_QUERY\s*\(                     { yy.lexer.unput('('); yytext = 'url_extract_query'; parser.addFunctionLocation(yylloc, yytext); return 'URL_EXTRACT_QUERY'; }
 
+// Non-reserved Keywords
+'OVER'                                     { return 'OVER'; }
+'ROLE'                                     { return 'ROLE'; }
 
-// Analytical functions
-COLLECT_LIST\s*\(                          { yy.lexer.unput('('); yytext = 'collect_list'; parser.addFunctionLocation(yylloc, yytext); return 'COLLECT_LIST'; }
-COLLECT_SET\s*\(                           { yy.lexer.unput('('); yytext = 'collect_set'; parser.addFunctionLocation(yylloc, yytext); return 'COLLECT_SET'; }
+// --- UDFs ---
+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'; }
-HISTOGRAM\s*\(                             { yy.lexer.unput('('); yytext = 'historgram'; parser.addFunctionLocation(yylloc, yytext); return 'HISTOGRAM'; }
 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'; }
-TOPK\s*\(                                  { yy.lexer.unput('('); yytext = 'topk'; parser.addFunctionLocation(yylloc, yytext); return 'TOPK'; }
-TOPKDISTINCT\s*\(                          { yy.lexer.unput('('); yytext = 'topkdistinct'; parser.addFunctionLocation(yylloc, yytext); return 'TOPKDISTINCT'; }
-WindowStart\s*\(                           { yy.lexer.unput('('); yytext = 'windowstart'; parser.addFunctionLocation(yylloc, yytext); return 'WindowStart'; }
-WindowEnd\s*\(                             { yy.lexer.unput('('); yytext = 'windowend'; parser.addFunctionLocation(yylloc, yytext); return 'WindowEnd'; }
+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'; }
+VARIANCE\s*\(                              { yy.lexer.unput('('); yytext = 'variance'; parser.addFunctionLocation(yylloc, yytext); return 'VARIANCE'; }
 
+// Analytical functions
+CUME_DIST\s*\(                             { yy.lexer.unput('('); yytext = 'cume_dist'; parser.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'; }
 
 [0-9]+                                     { return 'UNSIGNED_INTEGER'; }
 [0-9]+(?:[YSL]|BD)?                        { return 'UNSIGNED_INTEGER'; }
 [0-9]+E                                    { return 'UNSIGNED_INTEGER_E'; }
 [A-Za-z0-9_]+                              { return 'REGULAR_IDENTIFIER'; }
 
+<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]+                   { parser.addFileLocation(yylloc, yytext); return 'HDFS_PATH'; }
+<hdfs>['"]                                 { this.popState(); return 'HDFS_END_QUOTE'; }
+<hdfs><<EOF>>                              { return 'EOF'; }
 
 '&&'                                       { return 'AND'; }
 '||'                                       { return 'OR'; }

+ 109 - 0
desktop/core/src/desktop/js/parse/jison/sql/flink/sql_alter.jison

@@ -0,0 +1,109 @@
+// 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.
+
+DataDefinition
+ : AlterStatement
+ ;
+
+DataDefinition_EDIT
+ : AlterStatement_EDIT
+ ;
+
+AlterStatement
+ : AlterTable
+ | AlterView
+ ;
+
+AlterStatement_EDIT
+ : AlterTable_EDIT
+ | AlterView_EDIT
+ | 'ALTER' 'CURSOR'
+   {
+     parser.suggestKeywords(['TABLE', 'VIEW']);
+   }
+ ;
+
+AlterTable
+ : AlterTableLeftSide PartitionSpec
+ ;
+
+AlterTable_EDIT
+ : AlterTableLeftSide_EDIT
+ | AlterTableLeftSide_EDIT PartitionSpec
+ | AlterTableLeftSide 'CURSOR'
+ | AlterTableLeftSide PartitionSpec 'CURSOR'
+ ;
+
+AlterTableLeftSide
+ : 'ALTER' 'TABLE' SchemaQualifiedTableIdentifier
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+AlterTableLeftSide_EDIT
+ : 'ALTER' 'TABLE' SchemaQualifiedTableIdentifier_EDIT
+   {
+     if (parser.yy.result.suggestTables) {
+       parser.yy.result.suggestTables.onlyTables = true;
+     }
+   }
+ | 'ALTER' 'TABLE' 'CURSOR'
+   {
+     parser.suggestTables({ onlyTables: true });
+     parser.suggestDatabases({ appendDot: true });
+   }
+ ;
+
+AlterView
+ : AlterViewLeftSide 'AS' QuerySpecification
+ ;
+
+AlterView_EDIT
+ : AlterViewLeftSide_EDIT
+ | AlterViewLeftSide 'CURSOR'
+   {
+     parser.suggestKeywords(['AS']);
+   }
+ | AlterViewLeftSide 'SET' 'CURSOR'
+ | AlterViewLeftSide 'AS' 'CURSOR'
+   {
+     parser.suggestKeywords(['SELECT']);
+   }
+ | AlterViewLeftSide 'AS' QuerySpecification_EDIT
+ ;
+
+
+AlterViewLeftSide
+ : 'ALTER' 'VIEW' SchemaQualifiedTableIdentifier
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+AlterViewLeftSide_EDIT
+ : 'ALTER' 'VIEW' SchemaQualifiedTableIdentifier_EDIT
+   {
+     if (parser.yy.result.suggestTables) {
+       parser.yy.result.suggestTables.onlyViews = true;
+     }
+   }
+ | 'ALTER' 'VIEW' 'CURSOR'
+   {
+     parser.suggestTables({ onlyViews: true });
+     parser.suggestDatabases({ appendDot: true });
+   }
+ ;

+ 2 - 2
desktop/core/src/desktop/js/parse/jison/sql/flink/sql_main.jison

@@ -476,7 +476,7 @@ SchemaQualifiedTableIdentifier_EDIT
  ;
 
 SchemaQualifiedIdentifier
- : RegularOrBacktickedIdentifier                                    -> [{ name: $1 }]
+ : RegularOrBacktickedIdentifier                                       -> [{ name: $1 }]
  | RegularOrBacktickedIdentifier '.' RegularOrBacktickedIdentifier  -> [{ name: $1 }, { name: $2 }]
  ;
 
@@ -658,7 +658,7 @@ DerivedColumnChain_EDIT
  ;
 
 ColumnIdentifier
- : RegularOrBacktickedIdentifier -> { identifier: { name: $1 }, location: @1 }
+ : RegularOrBacktickedIdentifier                                                                               -> { identifier: { name: $1 }, location: @1 }
  ;
 
 PartialBacktickedIdentifierOrPartialCursor

+ 0 - 39
desktop/core/src/desktop/js/parse/jison/sql/flink/sql_show.jison

@@ -1,39 +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.
-
-DataDefinition
- : 'SHOW' ShowStatement
- ;
-
-DataDefinition_EDIT
- : ShowStatement_EDIT
- ;
-
-ShowStatement
- : 'TABLES'
- | 'STREAMS'
- | 'TOPICS'
- | 'QUERIES'
- | 'PROPERTIES'
- ;
-
-
-ShowStatement_EDIT
- : 'SHOW' 'CURSOR'
-   {
-     parser.suggestKeywords(['TABLES', 'STREAMS', 'TOPICS', 'QUERIES', 'PROPERTIES']);
-   }
- ;

+ 122 - 0
desktop/core/src/desktop/js/parse/jison/sql/flink/sql_update.jison

@@ -0,0 +1,122 @@
+// 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.
+
+DataManipulation
+ : UpdateStatement
+ ;
+
+DataManipulation_EDIT
+ : UpdateStatement_EDIT
+ ;
+
+UpdateStatement
+ : 'UPDATE' TargetTable 'SET' SetClauseList OptionalFromJoinedTable OptionalWhereClause
+ ;
+
+UpdateStatement_EDIT
+ : 'UPDATE' TargetTable_EDIT 'SET' SetClauseList OptionalFromJoinedTable OptionalWhereClause
+ | 'UPDATE' TargetTable 'SET' SetClauseList_EDIT OptionalFromJoinedTable OptionalWhereClause
+ | 'UPDATE' TargetTable 'SET' SetClauseList FromJoinedTable_EDIT OptionalWhereClause
+ | 'UPDATE' TargetTable 'SET' SetClauseList OptionalFromJoinedTable WhereClause_EDIT
+ | 'UPDATE' TargetTable 'SET' SetClauseList OptionalFromJoinedTable OptionalWhereClause 'CURSOR'
+   {
+     parser.suggestKeywords([ 'WHERE' ]);
+   }
+ | 'UPDATE' TargetTable 'CURSOR'
+   {
+     parser.suggestKeywords([ 'SET' ]);
+   }
+ | 'UPDATE' TargetTable_EDIT
+ | 'UPDATE' TargetTable
+ | 'UPDATE' 'CURSOR'
+   {
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
+   }
+ ;
+
+TargetTable
+ : TableName
+ ;
+
+TargetTable_EDIT
+ : TableName_EDIT
+ ;
+
+TableName
+ : LocalOrSchemaQualifiedName
+   {
+     parser.addTablePrimary($1);
+   }
+ ;
+
+TableName_EDIT
+ : LocalOrSchemaQualifiedName_EDIT
+ ;
+
+SetClauseList
+ : SetClause
+ | SetClauseList ',' SetClause
+ ;
+
+SetClauseList_EDIT
+ : SetClause_EDIT
+ | SetClauseList ',' SetClause_EDIT
+ | SetClause_EDIT ',' SetClauseList
+ | SetClauseList ',' SetClause_EDIT ',' SetClauseList
+ ;
+
+SetClause
+ : SetTarget '=' UpdateSource
+ ;
+
+SetClause_EDIT
+ : SetTarget '=' UpdateSource_EDIT
+ | SetTarget 'CURSOR'
+   {
+     parser.suggestKeywords([ '=' ]);
+   }
+ | 'CURSOR'
+   {
+     parser.suggestColumns();
+   }
+ ;
+
+SetTarget
+ : ColumnReference
+ ;
+
+UpdateSource
+ : ValueExpression
+ ;
+
+UpdateSource_EDIT
+ : ValueExpression_EDIT
+ ;
+
+OptionalFromJoinedTable
+ :
+ | 'FROM' TableReference  -> $2
+ ;
+
+FromJoinedTable_EDIT
+ : 'FROM' 'CURSOR'
+   {
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | 'FROM' TableReference_EDIT
+ ;

+ 12 - 10
desktop/core/src/desktop/js/parse/jison/sql/flink/sql_list.jison → desktop/core/src/desktop/js/parse/jison/sql/flink/sql_use.jison

@@ -15,23 +15,25 @@
 // limitations under the License.
 
 DataDefinition
- : 'LIST' ListStatement
+ : UseStatement
  ;
 
 DataDefinition_EDIT
- : ListStatement_EDIT
+ : UseStatement_EDIT
  ;
 
-ListStatement
- : 'TABLES'
- | 'STREAMS'
- | 'TOPICS'
+UseStatement
+ : 'USE' RegularIdentifier
+   {
+     if (! parser.yy.cursorFound) {
+       parser.yy.result.useDatabase = $2;
+     }
+   }
  ;
 
-
-ListStatement_EDIT
- : 'LIST' 'CURSOR'
+UseStatement_EDIT
+ : 'USE' 'CURSOR'
    {
-     parser.suggestKeywords(['TABLES', 'STREAMS', 'TOPICS']);
+     parser.suggestDatabases();
    }
  ;

文件差异内容过多而无法显示
+ 0 - 0
desktop/core/src/desktop/js/parse/sql/flink/flinkAutocompleteParser.js


文件差异内容过多而无法显示
+ 0 - 0
desktop/core/src/desktop/js/parse/sql/flink/flinkSyntaxParser.js


+ 6 - 1
desktop/core/src/desktop/js/parse/sql/flink/sqlParseSupport.js

@@ -1128,15 +1128,20 @@ const initSqlParser = function(parser) {
 
   parser.suggestDdlAndDmlKeywords = function(extraKeywords) {
     let keywords = [
+      'ALTER',
       'CREATE',
       'DESCRIBE',
       'DROP',
+      'GRANT',
       'INSERT',
+      'REVOKE',
       'SELECT',
       'SET',
       'SHOW',
+      'TRUNCATE',
       'UPDATE',
-      'LIST'
+      'USE',
+      'WITH'
     ];
 
     if (extraKeywords) {

+ 155 - 0
desktop/core/src/desktop/js/parse/sql/flink/test/flinkAutocompleteParser.Alter.test.js

@@ -0,0 +1,155 @@
+// 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.
+
+import flinkAutocompleteParser from '../flinkAutocompleteParser';
+
+describe('flinkAutocompleteParser.js ALTER statements', () => {
+  beforeAll(() => {
+    flinkAutocompleteParser.yy.parseError = function(msg) {
+      throw Error(msg);
+    };
+  });
+
+  const assertAutoComplete = testDefinition => {
+    const debug = false;
+
+    expect(
+      flinkAutocompleteParser.parseSql(
+        testDefinition.beforeCursor,
+        testDefinition.afterCursor,
+        debug
+      )
+    ).toEqualDefinition(testDefinition);
+  };
+
+  describe('ALTER TABLE', () => {
+    it('should suggest keywords for "ALTER |"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER ',
+        afterCursor: '',
+        containsKeywords: ['TABLE'],
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    it('should suggest tables for "ALTER TABLE |"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER TABLE ',
+        afterCursor: '',
+        expectedResult: {
+          lowerCase: false,
+          suggestTables: { onlyTables: true },
+          suggestDatabases: { appendDot: true }
+        }
+      });
+    });
+
+    it('should suggest tables for "ALTER TABLE foo.|"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER TABLE foo.',
+        afterCursor: '',
+        expectedResult: {
+          lowerCase: false,
+          suggestTables: { identifierChain: [{ name: 'foo' }], onlyTables: true }
+        }
+      });
+    });
+  });
+
+  describe('ALTER VIEW', () => {
+    it('should handle "ALTER VIEW baa.boo AS SELECT * FROM bla;|"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER VIEW baa.boo AS SELECT * FROM bla;',
+        afterCursor: '',
+        noErrors: true,
+        containsKeywords: ['SELECT'],
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    it('should suggest keywords for "ALTER |"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER ',
+        afterCursor: '',
+        containsKeywords: ['VIEW'],
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    it('should suggest views for "ALTER VIEW |"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER VIEW ',
+        afterCursor: '',
+        expectedResult: {
+          lowerCase: false,
+          suggestTables: { onlyViews: true },
+          suggestDatabases: { appendDot: true }
+        }
+      });
+    });
+
+    it('should suggest views for "ALTER VIEW boo.|"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER VIEW boo.',
+        afterCursor: '',
+        expectedResult: {
+          lowerCase: false,
+          suggestTables: { identifierChain: [{ name: 'boo' }], onlyViews: true }
+        }
+      });
+    });
+
+    it('should suggest keywords for "ALTER VIEW boo |"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER VIEW boo ',
+        afterCursor: '',
+        containsKeywords: ['AS'],
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    it('should suggest keywords for "ALTER VIEW baa.boo AS |"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER VIEW baa.boo AS ',
+        afterCursor: '',
+        expectedResult: {
+          lowerCase: false,
+          suggestKeywords: ['SELECT']
+        }
+      });
+    });
+
+    it('should suggest databases for "ALTER VIEW baa.boo AS SELECT * FROM |"', () => {
+      assertAutoComplete({
+        beforeCursor: 'ALTER VIEW baa.boo AS SELECT * FROM ',
+        afterCursor: '',
+        expectedResult: {
+          lowerCase: false,
+          suggestTables: {},
+          suggestDatabases: { appendDot: true }
+        }
+      });
+    });
+  });
+});

+ 382 - 0
desktop/core/src/desktop/js/parse/sql/flink/test/flinkAutocompleteParser.Update.test.js

@@ -0,0 +1,382 @@
+// 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.
+
+import flinkAutocompleteParser from '../flinkAutocompleteParser';
+
+describe('flinkAutocompleteParser.js UPDATE statements', () => {
+  beforeAll(() => {
+    flinkAutocompleteParser.yy.parseError = function(msg) {
+      throw Error(msg);
+    };
+  });
+
+  const assertAutoComplete = testDefinition => {
+    const debug = false;
+
+    expect(
+      flinkAutocompleteParser.parseSql(
+        testDefinition.beforeCursor,
+        testDefinition.afterCursor,
+        debug
+      )
+    ).toEqualDefinition(testDefinition);
+  };
+
+  it('should suggest keywords for "|"', () => {
+    assertAutoComplete({
+      beforeCursor: '',
+      afterCursor: '',
+      containsKeywords: ['UPDATE'],
+      expectedResult: {
+        lowerCase: false
+      }
+    });
+  });
+
+  it('should suggest keywords for "UPDATE bar  |"', () => {
+    assertAutoComplete({
+      beforeCursor: 'UPDATE bar  ',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestKeywords: ['SET'],
+        locations: [
+          {
+            type: 'statement',
+            location: { first_line: 1, last_line: 1, first_column: 1, last_column: 12 }
+          },
+          {
+            type: 'table',
+            location: { first_line: 1, last_line: 1, first_column: 8, last_column: 11 },
+            identifierChain: [{ name: 'bar' }]
+          }
+        ]
+      }
+    });
+  });
+
+  it('should suggest keywords for "UPDATE bar SET id=1, foo=2 |"', () => {
+    assertAutoComplete({
+      beforeCursor: 'UPDATE bar SET id=1, foo=2 ',
+      afterCursor: '',
+      containsKeywords: ['WHERE'],
+      expectedResult: {
+        lowerCase: false,
+        locations: [
+          {
+            type: 'statement',
+            location: { first_line: 1, last_line: 1, first_column: 1, last_column: 27 }
+          },
+          {
+            type: 'table',
+            location: { first_line: 1, last_line: 1, first_column: 8, last_column: 11 },
+            identifierChain: [{ name: 'bar' }]
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 16, last_column: 18 },
+            identifierChain: [{ name: 'id' }],
+            tables: [{ identifierChain: [{ name: 'bar' }] }],
+            qualified: false
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 22, last_column: 25 },
+            identifierChain: [{ name: 'foo' }],
+            tables: [{ identifierChain: [{ name: 'bar' }] }],
+            qualified: false
+          }
+        ]
+      }
+    });
+  });
+
+  it('should suggest keywords for "UPDATE bar SET id |"', () => {
+    assertAutoComplete({
+      beforeCursor: 'UPDATE bar SET id ',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestKeywords: ['='],
+        locations: [
+          {
+            type: 'statement',
+            location: { first_line: 1, last_line: 1, first_column: 1, last_column: 18 }
+          },
+          {
+            type: 'table',
+            location: { first_line: 1, last_line: 1, first_column: 8, last_column: 11 },
+            identifierChain: [{ name: 'bar' }]
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 16, last_column: 18 },
+            identifierChain: [{ name: 'id' }],
+            tables: [{ identifierChain: [{ name: 'bar' }] }],
+            qualified: false
+          }
+        ]
+      }
+    });
+  });
+
+  it('should suggest tables for "UPDATE |"', () => {
+    assertAutoComplete({
+      beforeCursor: 'UPDATE ',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestTables: {},
+        suggestDatabases: {
+          appendDot: true
+        }
+      }
+    });
+  });
+
+  it('should suggest tables for "UPDATE bla|"', () => {
+    assertAutoComplete({
+      beforeCursor: 'UPDATE bla',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestTables: {},
+        suggestDatabases: {
+          appendDot: true
+        }
+      }
+    });
+  });
+
+  it('should suggest tables for "UPDATE bar.|"', () => {
+    assertAutoComplete({
+      beforeCursor: 'UPDATE bar.',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestTables: { identifierChain: [{ name: 'bar' }] }
+      }
+    });
+  });
+
+  it('should suggest tables for "UPDATE bar.foo|"', () => {
+    assertAutoComplete({
+      beforeCursor: 'UPDATE bar.foo',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestTables: { identifierChain: [{ name: 'bar' }] }
+      }
+    });
+  });
+
+  it('should suggest columns for "UPDATE bar.foo SET |"', () => {
+    assertAutoComplete({
+      beforeCursor: 'UPDATE bar.foo SET ',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestColumns: { tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }] },
+        locations: [
+          {
+            type: 'statement',
+            location: { first_line: 1, last_line: 1, first_column: 1, last_column: 19 }
+          },
+          {
+            type: 'database',
+            location: { first_line: 1, last_line: 1, first_column: 8, last_column: 11 },
+            identifierChain: [{ name: 'bar' }]
+          },
+          {
+            type: 'table',
+            location: { first_line: 1, last_line: 1, first_column: 12, last_column: 15 },
+            identifierChain: [{ name: 'bar' }, { name: 'foo' }]
+          }
+        ]
+      }
+    });
+  });
+
+  it('should suggest columns for "UPDATE bar.foo SET id = 1, bla = \'foo\', |"', () => {
+    assertAutoComplete({
+      beforeCursor: "UPDATE bar.foo SET id = 1, bla = 'foo', ",
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestColumns: { tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }] },
+        locations: [
+          {
+            type: 'statement',
+            location: { first_line: 1, last_line: 1, first_column: 1, last_column: 40 }
+          },
+          {
+            type: 'database',
+            location: { first_line: 1, last_line: 1, first_column: 8, last_column: 11 },
+            identifierChain: [{ name: 'bar' }]
+          },
+          {
+            type: 'table',
+            location: { first_line: 1, last_line: 1, first_column: 12, last_column: 15 },
+            identifierChain: [{ name: 'bar' }, { name: 'foo' }]
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 20, last_column: 22 },
+            identifierChain: [{ name: 'id' }],
+            tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }],
+            qualified: false
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 28, last_column: 31 },
+            identifierChain: [{ name: 'bla' }],
+            tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }],
+            qualified: false
+          }
+        ]
+      }
+    });
+  });
+
+  it('should suggest columns for "UPDATE bar.foo SET bla = \'foo\' WHERE |"', () => {
+    assertAutoComplete({
+      beforeCursor: "UPDATE bar.foo SET bla = 'foo' WHERE ",
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestFunctions: {},
+        suggestColumns: { tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }] },
+        suggestFilters: { tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }] },
+        suggestKeywords: ['EXISTS', 'NOT EXISTS'],
+        locations: [
+          {
+            type: 'statement',
+            location: { first_line: 1, last_line: 1, first_column: 1, last_column: 37 }
+          },
+          {
+            type: 'database',
+            location: { first_line: 1, last_line: 1, first_column: 8, last_column: 11 },
+            identifierChain: [{ name: 'bar' }]
+          },
+          {
+            type: 'table',
+            location: { first_line: 1, last_line: 1, first_column: 12, last_column: 15 },
+            identifierChain: [{ name: 'bar' }, { name: 'foo' }]
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 20, last_column: 23 },
+            identifierChain: [{ name: 'bla' }],
+            tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }],
+            qualified: false
+          }
+        ]
+      }
+    });
+  });
+
+  it('should suggest values for "UPDATE bar.foo SET bla = \'foo\' WHERE id = |"', () => {
+    assertAutoComplete({
+      beforeCursor: "UPDATE bar.foo SET bla = 'foo' WHERE id = ",
+      afterCursor: '',
+      containsKeywords: ['CASE'],
+      expectedResult: {
+        locations: [
+          {
+            type: 'statement',
+            location: { first_line: 1, last_line: 1, first_column: 1, last_column: 42 }
+          },
+          {
+            type: 'database',
+            location: { first_line: 1, last_line: 1, first_column: 8, last_column: 11 },
+            identifierChain: [{ name: 'bar' }]
+          },
+          {
+            type: 'table',
+            location: { first_line: 1, last_line: 1, first_column: 12, last_column: 15 },
+            identifierChain: [{ name: 'bar' }, { name: 'foo' }]
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 20, last_column: 23 },
+            identifierChain: [{ name: 'bla' }],
+            tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }],
+            qualified: false
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 38, last_column: 40 },
+            identifierChain: [{ name: 'id' }],
+            tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }],
+            qualified: false
+          }
+        ],
+        suggestFunctions: { types: ['COLREF'] },
+        suggestValues: {},
+        colRef: { identifierChain: [{ name: 'bar' }, { name: 'foo' }, { name: 'id' }] },
+        suggestColumns: {
+          types: ['COLREF'],
+          tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }]
+        },
+        lowerCase: false
+      }
+    });
+  });
+
+  it('should suggest columns for "UPDATE bar.foo SET bla = \'foo\' WHERE id = 1 AND |"', () => {
+    assertAutoComplete({
+      beforeCursor: "UPDATE bar.foo SET bla = 'foo' WHERE id = 1 AND ",
+      afterCursor: '',
+      containsKeywords: ['CASE'],
+      expectedResult: {
+        lowerCase: false,
+        suggestFunctions: {},
+        suggestColumns: { tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }] },
+        suggestFilters: { tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }] },
+        locations: [
+          {
+            type: 'statement',
+            location: { first_line: 1, last_line: 1, first_column: 1, last_column: 48 }
+          },
+          {
+            type: 'database',
+            location: { first_line: 1, last_line: 1, first_column: 8, last_column: 11 },
+            identifierChain: [{ name: 'bar' }]
+          },
+          {
+            type: 'table',
+            location: { first_line: 1, last_line: 1, first_column: 12, last_column: 15 },
+            identifierChain: [{ name: 'bar' }, { name: 'foo' }]
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 20, last_column: 23 },
+            identifierChain: [{ name: 'bla' }],
+            tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }],
+            qualified: false
+          },
+          {
+            type: 'column',
+            location: { first_line: 1, last_line: 1, first_column: 38, last_column: 40 },
+            identifierChain: [{ name: 'id' }],
+            tables: [{ identifierChain: [{ name: 'bar' }, { name: 'foo' }] }],
+            qualified: false
+          }
+        ]
+      }
+    });
+  });
+});

+ 144 - 0
desktop/core/src/desktop/js/parse/sql/flink/test/flinkAutocompleteParser.Use.test.js

@@ -0,0 +1,144 @@
+// 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.
+
+import flinkAutocompleteParser from '../flinkAutocompleteParser';
+
+describe('flinkAutocompleteParser.js USE statements', () => {
+  beforeAll(() => {
+    flinkAutocompleteParser.yy.parseError = function(msg) {
+      throw Error(msg);
+    };
+  });
+
+  const assertAutoComplete = testDefinition => {
+    const debug = false;
+
+    expect(
+      flinkAutocompleteParser.parseSql(
+        testDefinition.beforeCursor,
+        testDefinition.afterCursor,
+        debug
+      )
+    ).toEqualDefinition(testDefinition);
+  };
+
+  it('should suggest keywords for "|"', () => {
+    assertAutoComplete({
+      beforeCursor: '',
+      afterCursor: '',
+      containsKeywords: ['USE'],
+      expectedResult: {
+        lowerCase: false
+      }
+    });
+  });
+
+  it('should suggest databases for "USE |"', () => {
+    assertAutoComplete({
+      serverResponses: {},
+      beforeCursor: 'USE ',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestDatabases: {}
+      }
+    });
+  });
+
+  it('should suggest databases for "USE bla|"', () => {
+    assertAutoComplete({
+      serverResponses: {},
+      beforeCursor: 'USE bla',
+      afterCursor: '',
+      expectedResult: {
+        lowerCase: false,
+        suggestDatabases: {}
+      }
+    });
+  });
+
+  it('should use a use statement for "use database_two; \\nselect |"', () => {
+    assertAutoComplete({
+      beforeCursor: 'use database_two; \nSELECT ',
+      afterCursor: '',
+      containsKeywords: ['*', 'ALL', 'DISTINCT'],
+      expectedResult: {
+        useDatabase: 'database_two',
+        lowerCase: true,
+        suggestAggregateFunctions: { tables: [] },
+        suggestAnalyticFunctions: true,
+        suggestFunctions: {},
+        suggestTables: {
+          prependQuestionMark: true,
+          prependFrom: true
+        },
+        suggestDatabases: {
+          prependQuestionMark: true,
+          prependFrom: true,
+          appendDot: true
+        }
+      }
+    });
+  });
+
+  it('should use the last use statement for "USE other_db; USE closest_db; \\n\\tSELECT |"', () => {
+    assertAutoComplete({
+      beforeCursor: 'USE other_db; USE closest_db; \n\tSELECT ',
+      afterCursor: '',
+      containsKeywords: ['*', 'ALL', 'DISTINCT'],
+      expectedResult: {
+        useDatabase: 'closest_db',
+        lowerCase: false,
+        suggestAggregateFunctions: { tables: [] },
+        suggestAnalyticFunctions: true,
+        suggestFunctions: {},
+        suggestTables: {
+          prependQuestionMark: true,
+          prependFrom: true
+        },
+        suggestDatabases: {
+          prependQuestionMark: true,
+          prependFrom: true,
+          appendDot: true
+        }
+      }
+    });
+  });
+
+  it('should use the use statement for "USE other_db; USE closest_db; \\n\\tSELECT |; USE some_other_db;"', () => {
+    assertAutoComplete({
+      beforeCursor: 'USE other_db; USE closest_db; \n\tSELECT ',
+      afterCursor: '; USE some_other_db;',
+      containsKeywords: ['*', 'ALL', 'DISTINCT'],
+      expectedResult: {
+        useDatabase: 'closest_db',
+        lowerCase: false,
+        suggestAggregateFunctions: { tables: [] },
+        suggestAnalyticFunctions: true,
+        suggestFunctions: {},
+        suggestTables: {
+          prependQuestionMark: true,
+          prependFrom: true
+        },
+        suggestDatabases: {
+          prependQuestionMark: true,
+          prependFrom: true,
+          appendDot: true
+        }
+      }
+    });
+  });
+});

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