Преглед изворни кода

HUE-4579 [editor] The new autocompleter should support Hive INSERT statements

This takes care of the HIVE and generic INSERT statements.
Johan Ahlen пре 9 година
родитељ
комит
c810ce2

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

@@ -46,6 +46,7 @@
 <hive>'FUNCTION'                           { return '<hive>FUNCTION'; }
 <hive>'GRANT'                              { return '<hive>GRANT'; }
 <hive>'GROUPING'                           { return '<hive>GROUPING'; }
+<hive>'INSERT'                             { determineCase(yytext); return '<hive>INSERT'; }
 <hive>'LATERAL'                            { return '<hive>LATERAL'; }
 <hive>'LOCAL'                              { return '<hive>LOCAL'; }
 <hive>'MACRO'                              { return '<hive>MACRO'; }
@@ -86,6 +87,7 @@
 <hive>'DELIMITED'                          { return '<hive>DELIMITED'; }
 <hive>'DEPENDENCY'                         { return '<hive>DEPENDENCY'; }
 <hive>'DESC'                               { return '<hive>DESC'; }
+<hive>'DIRECTORY'                          { this.begin('hdfs'); return '<hive>DIRECTORY'; }
 <hive>'DISABLE'                            { return '<hive>DISABLE'; }
 <hive>'DISTRIBUTE'                         { return '<hive>DISTRIBUTE'; }
 <hive>'ESCAPED'                            { return '<hive>ESCAPED'; }
@@ -279,13 +281,14 @@
 'FALSE'                                    { return 'FALSE'; }
 'FLOAT'                                    { return 'FLOAT'; }
 'FOLLOWING'                                { return 'FOLLOWING'; }
-'FROM'                                     { return 'FROM'; }
+'FROM'                                     { determineCase(yytext); return 'FROM'; }
 'FULL'                                     { return 'FULL'; }
 'GROUP'                                    { return 'GROUP'; }
 'HAVING'                                   { return 'HAVING'; }
 'IF'                                       { return 'IF'; }
 'IN'                                       { return 'IN'; }
 'INNER'                                    { return 'INNER'; }
+'INSERT'                                   { return 'INSERT'; }
 'INT'                                      { return 'INT'; }
 'INTO'                                     { return 'INTO'; }
 'IS'                                       { return 'IS'; }
@@ -327,6 +330,7 @@
 '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'; }

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

@@ -736,6 +736,20 @@ HiveOrImpalaRowFormat_EDIT
  ;
 
 HiveRowFormat
+ : HiveDelimitedRowFormat
+ | '<hive>SERDE' QuotedValue OptionalHiveWithSerdeproperties
+   {
+     if (!$3) {
+       $$ = { suggestKeywords: [{ value: 'WITH SERDEPROPERTIES', weight: 1 }] };
+     }
+   }
+ ;
+
+HiveRowFormat_EDIT
+ : HiveDelimitedRowFormat_EDIT
+ ;
+
+HiveDelimitedRowFormat
  : '<hive>DELIMITED' OptionalFieldsTerminatedBy OptionalCollectionItemsTerminatedBy OptionalMapKeysTerminatedBy
    OptionalLinesTerminatedBy OptionalNullDefinedAs
    {
@@ -753,15 +767,9 @@ HiveRowFormat
        $$ = { suggestKeywords: [{ value: 'NULL DEFINED AS', weight: 1 }] };
      }
    }
- | '<hive>SERDE' QuotedValue OptionalHiveWithSerdeproperties
-   {
-     if (!$3) {
-       $$ = { suggestKeywords: [{ value: 'WITH SERDEPROPERTIES', weight: 1 }] };
-     }
-   }
  ;
 
-HiveRowFormat_EDIT
+HiveDelimitedRowFormat_EDIT
  : '<hive>DELIMITED' OptionalFieldsTerminatedBy_EDIT OptionalCollectionItemsTerminatedBy OptionalMapKeysTerminatedBy
    OptionalLinesTerminatedBy OptionalNullDefinedAs
  | '<hive>DELIMITED' OptionalFieldsTerminatedBy OptionalCollectionItemsTerminatedBy_EDIT OptionalMapKeysTerminatedBy

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

@@ -0,0 +1,369 @@
+// 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
+ : InsertStatement
+ ;
+
+InsertStatement
+ : HiveInsertStatement
+ | InsertValuesStatement
+ ;
+
+DataManipulation_EDIT
+ : HiveInsertStatement_EDIT
+ | InsertValuesStatement_EDIT
+ ;
+
+HiveInsertStatement
+ : HiveInsertWithoutQuery QuerySpecification
+ | FromClause HiveInserts
+ | FromClause SelectWithoutTableExpression OptionalSelectConditions
+ ;
+
+HiveInsertStatement_EDIT
+ : HiveInsertWithoutQuery_EDIT
+ | HiveInsertWithoutQuery 'CURSOR'
+   {
+     var keywords = [];
+     if ($1.suggestKeywords) {
+       keywords = createWeightedKeywords($1.suggestKeywords, 2).concat([{ value: 'SELECT', weight: 1}]);
+     } else {
+       keywords = ['SELECT'];
+     }
+     if ($1.addValues) {
+       keywords.push({ weight: 1.1, value: 'VALUES' });
+     }
+     if (keywords.length > 0) {
+       suggestKeywords(keywords);
+     }
+   }
+ | HiveInsertWithoutQuery_EDIT QuerySpecification
+ | HiveInsertWithoutQuery QuerySpecification_EDIT
+ | FromClause HiveInserts_EDIT
+   {
+     if (!$2.keepTables) {
+       delete parser.yy.result.suggestTables;
+       delete parser.yy.result.suggestDatabases;
+     }
+   }
+ | FromClause_EDIT
+ | FromClause_EDIT HiveInserts
+ | FromClause_EDIT SelectWithoutTableExpression OptionalSelectConditions
+ | FromClause 'CURSOR'
+   {
+     suggestKeywords(['INSERT INTO', 'INSERT OVERWRITE', 'SELECT']);
+   }
+ | FromClause SelectWithoutTableExpression_EDIT OptionalSelectConditions
+   {
+     if ($2.cursorAtEnd) {
+       checkForSelectListKeywords($2);
+       var keywords = parser.yy.result.suggestKeywords || [];
+       if ($3.suggestKeywords) {
+         keywords = keywords.concat($3.suggestKeywords);
+       }
+       if (keywords.length > 0) {
+         suggestKeywords(keywords);
+       }
+     }
+     delete parser.yy.result.suggestTables;
+     delete parser.yy.result.suggestDatabases;
+   }
+ | FromClause SelectWithoutTableExpression OptionalSelectConditions_EDIT
+   {
+     if ($3.cursorAtStart) {
+       checkForSelectListKeywords($2.tableExpression);
+     }
+   }
+ ;
+
+HiveInsertWithoutQuery
+ : '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalIfNotExists
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+     if (!$5 && !$6) {
+       $$ = { suggestKeywords: ['PARTITION'] }
+     } else if (!$6) {
+       $$ = { suggestKeywords: ['IF NOT EXISTS'] }
+     }
+   }
+ | '<hive>INSERT' '<hive>OVERWRITE' '<hive>LOCAL' '<hive>DIRECTORY' HdfsPath OptionalInsertRowFormat OptionalStoredAs
+   {
+     if (!$6 && !$7) {
+       $$ = { suggestKeywords: [{ value: 'ROW FORMAT', weight: 2 }, { value: 'STORED AS', weight: 1}] };
+     } else if (!$7) {
+       $$ = { suggestKeywords: ['STORED AS'] };
+     }
+   }
+ | '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+     if (!$5 && !$6) {
+       $$ = { suggestKeywords: ['PARTITION'], addValues: true };
+     } else if (!$6) {
+       $$ = { addValues: true };
+     }
+   }
+ ;
+
+HiveInsertWithoutQuery_EDIT
+ : '<hive>INSERT' 'CURSOR'
+   {
+     suggestKeywords(['OVERWRITE', 'INTO']);
+   }
+ | '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable 'CURSOR'
+   {
+     if (!$3) {
+       suggestKeywords(['LOCAL DIRECTORY', 'TABLE']);
+     }
+     suggestTables();
+     suggestDatabases({ appendDot: true });
+     $$ = { keepTables: true }
+   }
+ | '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec OptionalParenthesizedColumnList
+   {
+     $$ = { keepTables: true }
+   }
+ | '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT OptionalIfNotExists
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+     if (parser.yy.result.suggestColumns) {
+       parser.yy.result.suggestColumns.owner = 'insert';
+     }
+   }
+ | '<hive>INSERT' '<hive>OVERWRITE' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalIfNotExists_EDIT
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+   }
+ | '<hive>INSERT' '<hive>OVERWRITE' '<hive>LOCAL'
+   {
+     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
+ | '<hive>INSERT' '<hive>OVERWRITE' '<hive>LOCAL' '<hive>DIRECTORY' HdfsPath OptionalInsertRowFormat OptionalStoredAs_EDIT
+ | '<hive>INSERT' 'INTO' OptionalHiveTable 'CURSOR'
+   {
+     if (!$3) {
+       suggestKeywords(['TABLE']);
+     }
+     suggestTables();
+     suggestDatabases({ appendDot: true });
+     $$ = { keepTables: true }
+   }
+ | '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec OptionalParenthesizedColumnList
+   {
+     $$ = { keepTables: true }
+   }
+ | '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec_EDIT OptionalParenthesizedColumnList
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+     if (parser.yy.result.suggestColumns) {
+       parser.yy.result.suggestColumns.owner = 'insert';
+     }
+   }
+ | '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList_EDIT
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+     if (parser.yy.result.suggestColumns) {
+       parser.yy.result.suggestColumns.owner = 'insert';
+     }
+   }
+ ;
+
+HiveInserts
+ : HiveInsert
+ | HiveInserts HiveInsert
+ ;
+
+HiveInserts_EDIT
+ : HiveInsert_EDIT
+ | HiveInserts HiveInsert_EDIT
+ | HiveInsert_EDIT HiveInserts
+ | HiveInserts HiveInsert_EDIT HiveInserts
+ ;
+
+HiveInsert
+ : HiveInsertWithoutQuery SelectWithoutTableExpression OptionalSelectConditions
+ ;
+
+HiveInsert_EDIT
+ : HiveInsertWithoutQuery_EDIT
+ | HiveInsertWithoutQuery_EDIT SelectWithoutTableExpression OptionalSelectConditions
+ | HiveInsertWithoutQuery 'CURSOR'
+   {
+     if ($1.suggestKeywords) {
+       suggestKeywords(createWeightedKeywords($1.suggestKeywords, 2).concat([{ value: 'SELECT', weight: 1}]));
+     } else {
+       suggestKeywords(['SELECT']);
+     }
+   }
+ | HiveInsertWithoutQuery SelectWithoutTableExpression_EDIT OptionalSelectConditions
+   {
+     if ($2.cursorAtEnd) {
+       checkForSelectListKeywords($2);
+       var keywords = parser.yy.result.suggestKeywords || [];
+       if ($3.suggestKeywords) {
+         keywords = keywords.concat($3.suggestKeywords);
+       }
+       if (keywords.length > 0) {
+         suggestKeywords(keywords);
+       }
+     }
+   }
+ | HiveInsertWithoutQuery SelectWithoutTableExpression OptionalSelectConditions_EDIT
+ ;
+
+// Also for Impala
+InsertValuesStatement
+ : '<hive>INSERT' 'INTO' OptionalHiveTable SchemaQualifiedTableIdentifier OptionalPartitionSpec 'VALUES' InsertValuesList
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+   }
+ | 'INSERT' 'INTO' OptionalTable SchemaQualifiedTableIdentifier 'VALUES' InsertValuesList
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+   }
+ ;
+
+InsertValuesStatement_EDIT
+ : 'INSERT' 'CURSOR'
+   {
+     suggestKeywords(['INTO']);
+   }
+ | 'INSERT' 'INTO' OptionalTable 'CURSOR'
+   {
+     if (!$3) {
+       suggestKeywords(['TABLE']);
+     }
+     suggestTables();
+     suggestDatabases({ appendDot: true });
+   }
+ | 'INSERT' 'INTO' OptionalTable SchemaQualifiedTableIdentifier_EDIT
+ | 'INSERT' 'INTO' OptionalTable SchemaQualifiedTableIdentifier 'CURSOR'
+   {
+     $4.owner = 'insert';
+     addTablePrimary($4);
+     suggestKeywords(['VALUES']);
+   }
+ | 'INSERT' 'INTO' OptionalTable SchemaQualifiedTableIdentifier_EDIT 'VALUES' InsertValuesList
+ ;
+
+InsertValuesList
+ : ParenthesizedRowValuesList
+ | RowValuesList ',' ParenthesizedRowValuesList
+ ;
+
+ParenthesizedRowValuesList
+ : '(' InValueList ')'
+ ;
+
+OptionalTable
+ :
+ | '<impala>TABLE'
+ | 'TABLE'
+ ;
+
+AnyInsert
+ : '<hive>INSERT'
+ | 'INSERT'
+ ;
+
+OptionalInsertRowFormat
+ :
+ | 'ROW' '<hive>FORMAT' HiveDelimitedRowFormat
+ ;
+
+OptionalInsertRowFormat_EDIT
+ : 'ROW' 'CURSOR'
+   {
+     suggestKeywords(['FORMAT DELIMITED']);
+   }
+ | 'ROW' '<hive>FORMAT' 'CURSOR'
+   {
+     suggestKeywords(['DELIMITED']);
+   }
+ | 'ROW' '<hive>FORMAT' HiveDelimitedRowFormat_EDIT
+ ;
+
+SelectWithoutTableExpression
+ : 'SELECT' OptionalAllOrDistinct SelectList  -> { selectList: $3 }
+ ;
+
+SelectWithoutTableExpression_EDIT
+ : 'SELECT' OptionalAllOrDistinct SelectList 'CURSOR'
+   {
+     $$ = $3;
+     $$.cursorAtEnd = true;
+   }
+ | 'SELECT' OptionalAllOrDistinct SelectList_EDIT
+   {
+     if ($3.cursorAtStart) {
+       var keywords = [];
+       if ($2) {
+         keywords = [{ value: '*', weight: 1000 }];
+       } else {
+         keywords = [{ value: '*', weight: 1000 }, 'ALL', 'DISTINCT'];
+       }
+       if (isImpala()) {
+         keywords.push('STRAIGHT_JOIN');
+       }
+       suggestKeywords(keywords);
+     } else {
+       checkForSelectListKeywords($3);
+     }
+     if ($3.suggestAggregateFunctions && (!$2 || $2 === 'ALL')) {
+       suggestAggregateFunctions();
+       suggestAnalyticFunctions();
+     }
+   }
+ | 'SELECT' OptionalAllOrDistinct 'CURSOR'
+   {
+     var keywords = [];
+     if ($2) {
+       keywords = [{ value: '*', weight: 1000 }];
+       if ($2 === 'ALL') {
+         suggestAggregateFunctions();
+         suggestAnalyticFunctions();
+       }
+     } else {
+       keywords = [{ value: '*', weight: 1000 }, 'ALL', 'DISTINCT'];
+       suggestAggregateFunctions();
+       suggestAnalyticFunctions();
+     }
+     if (isImpala()) {
+       keywords.push('STRAIGHT_JOIN');
+     }
+     suggestKeywords(keywords);
+     suggestFunctions();
+     suggestColumns();
+     suggestTables({ prependQuestionMark: true, prependFrom: true });
+     suggestDatabases({ prependQuestionMark: true, prependFrom: true, appendDot: true });
+   }
+ ;
+
+OptionalHiveTable
+ :
+ | '<hive>TABLE'
+ ;

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

@@ -53,6 +53,7 @@ NonReservedKeyword
  | '<hive>DEFINED'
  | '<hive>DELIMITED'
  | '<hive>DEPENDENCY'
+ | '<hive>DIRECTORY'
  | '<hive>DISABLE'
  | '<hive>ENABLE'
  | '<hive>ESCAPED'
@@ -191,7 +192,9 @@ SqlStatements_EDIT
 SqlStatement_EDIT
  : AnyCursor
    {
-     if (isHive() || isImpala()) {
+     if (isHive()) {
+       suggestDdlAndDmlKeywords(['EXPLAIN', 'FROM']);
+     } else if (isImpala()) {
        suggestDdlAndDmlKeywords(['EXPLAIN']);
      } else {
        suggestDdlAndDmlKeywords();
@@ -239,9 +242,9 @@ OptionalHiveExplainTypes
 // This is a work-around for error handling when a statement starts with some token that the parser can understand but
 // it's not a valid statement (see ErrorStatement). It contains everything except valid starting tokens ('SELECT', 'USE' etc.)
 NonStartingToken
- : '<hive>ALL' | '<hive>ARRAY' | '<hive>AS' | '<hive>AUTHORIZATION' | '<hive>AVRO' | '<hive>BINARY' | '<hive>BUCKET' | '<hive>BUCKETS' | '<hive>CACHE' | '<hive>CLUSTER' | '<hive>CLUSTERED' | '<hive>COLLECTION' | '<hive>COMPUTE' | '<hive>CONF' | '<hive>CROSS' | '<hive>CUBE' | '<hive>CURRENT' | '<hive>DATE' | '<hive>DEFERRED' | '<hive>DELIMITED' | '<hive>DEPENDENCY' | '<hive>DISTRIBUTE' | '<hive>DISTRIBUTED' | '<hive>ESCAPED' | '<hive>EXTENDED' | '<hive>EXTERNAL' | '<hive>FIELDS' | '<hive>FILE' | '<hive>FOR' | '<hive>FORMAT' | '<hive>FUNCTION' | '<hive>GRANT' | '<hive>GROUPING' | '<hive>IDXPROPERTIES' | '<hive>LATERAL' | '<hive>LOCAL' | '<hive>MACRO' | '<hive>OVERWRITE' | '<hive>PARTITION' | '<hive>REBUILD' | '<hive>REPAIR' | '<hive>ROLLUP' | '<hive>SETS' | '<hive>STATISTICS' | '<hive>TABLE' | '<hive>USER' | '<hive>ASC' | '<hive>COLUMNS' | '<hive>COMMENT' | '<hive>COMPACTIONS' | '<hive>DATA' | '<hive>DATABASES' | '<hive>DEFINED' | '<hive>DESC' |  '<hive>FORMATTED' | '<hive>FUNCTIONS' | '<hive>INDEX' | '<hive>INDEXES' | '<hive>INPATH' | '<hive>INPUTFORMAT' | '<hive>ITEMS' | '<hive>JAR' | '<hive>KEYS' | '<hive>LINES' | '<hive>LIMIT' | '<hive>LOCATION' | '<hive>LOCKS' | '<hive>MAP' | '<hive>METADATA' | '<hive>NONE' | '<hive>NOSCAN' | '<hive>OF' | '<hive>ORC' | '<hive>OUT' | '<hive>OUTPUTFORMAT' | '<hive>PARQUET' | '<hive>PARTITIONED' | '<hive>PARTITIONS' | '<hive>RCFILE' | '<hive>ROLE' | '<hive>ROLES' | '<hive>SCHEMA' | '<hive>SCHEMAS' | '<hive>SEQUENCEFILE' | '<hive>SERDE' | '<hive>SERDEPROPERTIES' | '<hive>SKEWED' | '<hive>SORTED' | '<hive>STORED' | '<hive>STORED_AS_DIRECTORIES' | '<hive>STRING' | '<hive>STRUCT' | '<hive>TABLES' | '<hive>TABLESAMPLE' | '<hive>TBLPROPERTIES' | '<hive>TEMPORARY' | '<hive>TERMINATED' | '<hive>TEXTFILE' | '<hive>TINYINT' | '<hive>TRANSACTIONS' | '<hive>UNIONTYPE' | '<hive>USING' | '<hive>VIEW' | '<hive>WINDOW' | '<hive>.' | '<hive>[' | '<hive>]'
+ : '<hive>ALL' | '<hive>ARRAY' | '<hive>AS' | '<hive>AUTHORIZATION' | '<hive>AVRO' | '<hive>BINARY' | '<hive>BUCKET' | '<hive>BUCKETS' | '<hive>CACHE' | '<hive>CLUSTER' | '<hive>CLUSTERED' | '<hive>COLLECTION' | '<hive>COMPUTE' | '<hive>CONF' | '<hive>CROSS' | '<hive>CUBE' | '<hive>CURRENT' | '<hive>DATE' | '<hive>DEFERRED' | '<hive>DELIMITED' | '<hive>DEPENDENCY' | '<hive>DIRECTORY' | '<hive>DISTRIBUTE' | '<hive>DISTRIBUTED' | '<hive>ESCAPED' | '<hive>EXTENDED' | '<hive>EXTERNAL' | '<hive>FIELDS' | '<hive>FILE' | '<hive>FOR' | '<hive>FORMAT' | '<hive>FUNCTION' | '<hive>GRANT' | '<hive>GROUPING' | '<hive>IDXPROPERTIES' | '<hive>LATERAL' | '<hive>LOCAL' | '<hive>MACRO' | '<hive>OVERWRITE' | '<hive>PARTITION' | '<hive>REBUILD' | '<hive>REPAIR' | '<hive>ROLLUP' | '<hive>SETS' | '<hive>STATISTICS' | '<hive>TABLE' | '<hive>USER' | '<hive>ASC' | '<hive>COLUMNS' | '<hive>COMMENT' | '<hive>COMPACTIONS' | '<hive>DATA' | '<hive>DATABASES' | '<hive>DEFINED' | '<hive>DESC' |  '<hive>FORMATTED' | '<hive>FUNCTIONS' | '<hive>INDEX' | '<hive>INDEXES' | '<hive>INPATH' | '<hive>INPUTFORMAT' | '<hive>ITEMS' | '<hive>JAR' | '<hive>KEYS' | '<hive>LINES' | '<hive>LIMIT' | '<hive>LOCATION' | '<hive>LOCKS' | '<hive>MAP' | '<hive>METADATA' | '<hive>NONE' | '<hive>NOSCAN' | '<hive>OF' | '<hive>ORC' | '<hive>OUT' | '<hive>OUTPUTFORMAT' | '<hive>PARQUET' | '<hive>PARTITIONED' | '<hive>PARTITIONS' | '<hive>RCFILE' | '<hive>ROLE' | '<hive>ROLES' | '<hive>SCHEMA' | '<hive>SCHEMAS' | '<hive>SEQUENCEFILE' | '<hive>SERDE' | '<hive>SERDEPROPERTIES' | '<hive>SKEWED' | '<hive>SORTED' | '<hive>STORED' | '<hive>STORED_AS_DIRECTORIES' | '<hive>STRING' | '<hive>STRUCT' | '<hive>TABLES' | '<hive>TABLESAMPLE' | '<hive>TBLPROPERTIES' | '<hive>TEMPORARY' | '<hive>TERMINATED' | '<hive>TEXTFILE' | '<hive>TINYINT' | '<hive>TRANSACTIONS' | '<hive>UNIONTYPE' | '<hive>USING' | '<hive>VIEW' | '<hive>WINDOW' | '<hive>.' | '<hive>[' | '<hive>]'
  | '<impala>AGGREGATE' | '<impala>AVRO' | '<impala>CACHED' | '<impala>CLOSE_FN' | '<impala>COLUMN' | '<impala>COMMENT' | '<impala>DATA' | '<impala>DATABASES' | '<impala>DELIMITED' | '<impala>ESCAPED' | '<impala>EXTERNAL' | '<impala>FIELDS' | '<impala>FINALIZE_FN' | '<impala>FIRST' | '<impala>FORMAT' | '<impala>FORMATTED' | '<impala>FUNCTION' | '<impala>FUNCTIONS' | '<impala>GROUP' | '<impala>INCREMENTAL' | '<impala>INTERVAL' | '<impala>INIT_FN' | '<impala>INPATH' | '<impala>LAST' | '<impala>LINES' | '<impala>LOCATION' | '<impala>MERGE_FN' | '<impala>NULLS' | '<impala>PARTITIONS' | '<impala>PREPARE_FN' | '<impala>REAL' | '<impala>RETURNS' | '<impala>SCHEMAS' | '<impala>SERIALIZE_FN' | '<impala>STATS' | '<impala>STRAIGHT_JOIN' | '<impala>SYMBOL' | '<impala>TABLE' | '<impala>TABLES' | '<impala>USING' | '<impala>ANALYTIC' | '<impala>ANTI' | '<impala>CURRENT' | '<impala>GRANT' | '<impala>PARQUET' | '<impala>PARTITIONED' | '<impala>RCFILE' | '<impala>ROLE' | '<impala>ROLES' | '<impala>SEQUENCEFILE' | '<impala>SERDEPROPERTIES' | '<impala>SHUFFLE' | '<impala>STORED' | '<impala>TBLPROPERTIES' | '<impala>TERMINATED' | '<impala>TEXTFILE' | '<impala>UPDATE_FN' | '<impala>BROADCAST' | '<impala>...' | '<impala>.' | '<impala>[' | '<impala>]'
- | 'ALL' | 'AS' | 'ASC' | 'BETWEEN' | 'BIGINT' | 'BOOLEAN' | 'BY' | 'CASE' | 'CHAR' | 'CURRENT' | 'DATABASE' | 'DECIMAL' | 'DISTINCT' | 'DOUBLE' | 'DESC' | 'ELSE' | 'END' | 'EXISTS' | 'FALSE' | 'FLOAT' | 'FOLLOWING' | 'FROM' | 'FULL' | 'GROUP' | 'HAVING' | 'IF' | 'IN' | 'INNER' | 'INT' | 'INTO' | 'IS' | 'JOIN' | 'LEFT' | 'LIKE' | 'LIMIT' | 'NOT' | 'NULL' | 'ON' | 'ORDER' | 'OUTER' | 'OVER' | 'PARTITION' | 'PRECEDING' | 'RANGE' | 'REGEXP' | 'RIGHT' | 'RLIKE' | 'ROW' | 'ROWS' | 'SCHEMA' | 'SEMI' | 'SET' | 'SMALLINT' | 'STRING' | 'TABLE' | 'THEN' | 'TIMESTAMP' | 'TINYINT' | 'TRUE' | 'UNION' | 'VARCHAR' | 'WHEN' | 'WHERE' | 'WITH' | 'ROLE'
+ | 'ALL' | 'AS' | 'ASC' | 'BETWEEN' | 'BIGINT' | 'BOOLEAN' | 'BY' | 'CASE' | 'CHAR' | 'CURRENT' | 'DATABASE' | 'DECIMAL' | 'DISTINCT' | 'DOUBLE' | 'DESC' | 'ELSE' | 'END' | 'EXISTS' | 'FALSE' | 'FLOAT' | 'FOLLOWING' | 'FROM' | 'FULL' | 'GROUP' | 'HAVING' | 'IF' | 'IN' | 'INNER' | 'INSERT' | 'INT' | 'INTO' | 'IS' | 'JOIN' | 'LEFT' | 'LIKE' | 'LIMIT' | 'NOT' | 'NULL' | 'ON' | 'ORDER' | 'OUTER' | 'OVER' | 'PARTITION' | 'PRECEDING' | 'RANGE' | 'REGEXP' | 'RIGHT' | 'RLIKE' | 'ROW' | 'ROWS' | 'SCHEMA' | 'SEMI' | 'SET' | 'SMALLINT' | 'STRING' | 'TABLE' | 'THEN' | 'TIMESTAMP' | 'TINYINT' | 'TRUE' | 'UNION' | 'VALUES' | 'VARCHAR' | 'WHEN' | 'WHERE' | 'WITH' | 'ROLE'
  | 'AVG' | 'CAST' | 'COUNT' | 'MAX' | 'MIN' | 'STDDEV_POP' | 'STDDEV_SAMP' | 'SUM' | 'VARIANCE' | 'VAR_POP' | 'VAR_SAMP'
  | '<hive>COLLECT_SET' | '<hive>COLLECT_LIST' | '<hive>CORR' | '<hive>COVAR_POP' | '<hive>COVAR_SAMP' | '<hive>HISTOGRAM_NUMERIC' | '<hive>NTILE' | '<hive>PERCENTILE' | '<hive>PERCENTILE_APPROX'
  | '<impala>APPX_MEDIAN' | '<impala>EXTRACT' | '<impala>GROUP_CONCAT' | '<impala>STDDEV' | '<impala>VARIANCE_POP' | '<impala>VARIANCE_SAMP'
@@ -597,6 +600,15 @@ RightParenthesisOrError
  | error
  ;
 
+OptionalParenthesizedColumnList
+ :
+ | ParenthesizedColumnList
+ ;
+
+OptionalParenthesizedColumnList_EDIT
+ : ParenthesizedColumnList_EDIT
+ ;
+
 ParenthesizedColumnList
  : '(' ColumnList ')'
  ;
@@ -629,7 +641,6 @@ ColumnList_EDIT
    }
  ;
 
-
 ParenthesizedSimpleValueList
  : '(' SimpleValueList ')'
  ;
@@ -1287,6 +1298,57 @@ TableExpression
 
 TableExpression_EDIT
  : FromClause_EDIT OptionalSelectConditions
+ | FromClause 'CURSOR' OptionalSelectConditions OptionalJoins
+   {
+     var keywords = [];
+
+     if ($1 && typeof $1.hasJoinCondition !== 'undefined' && !$1.hasJoinCondition) {
+       keywords.push({ value: 'ON', weight: 3 });
+       if (isImpala()) {
+         keywords.push({ value: 'USING', weight: 3 });
+       }
+     } else if ($1 && $1.suggestKeywords) {
+       keywords = createWeightedKeywords($1.suggestKeywords, 3);
+     } else if ($1 && $1.types) {
+       var veKeywords = getValueExpressionKeywords($1);
+       keywords = veKeywords.suggestKeywords;
+       if (veKeywords.suggestColRefKeywords) {
+         suggestColRefKeywords(veKeywords.suggestColRefKeywords);
+         addColRefIfExists($1);
+       }
+     }
+
+     if ($3.empty && $4 && $4.joinType.toUpperCase() === 'JOIN') {
+       keywords = keywords.concat(['FULL', 'FULL OUTER', 'LEFT', 'LEFT OUTER', 'RIGHT', 'RIGHT OUTER']);
+       if (isHive()) {
+         keywords = keywords.concat(['CROSS', 'LEFT SEMI']);
+       } else if (isImpala()) {
+         keywords = keywords.concat(['INNER', 'LEFT ANTI', 'LEFT SEMI', 'RIGHT ANTI', 'RIGHT SEMI']);
+       } else {
+         keywords.push('INNER');
+       }
+       suggestKeywords(keywords);
+       return;
+     }
+
+     if ($3.suggestKeywords) {
+       keywords = keywords.concat(createWeightedKeywords($3.suggestKeywords, 2));
+     }
+
+     if ($3.empty) {
+       keywords.push({ value: 'UNION', weight: 2.11 });
+     }
+
+     keywords = keywords.concat([{ value: 'FULL JOIN', weight: 1 }, { value: 'FULL OUTER JOIN', weight: 1 }, { value: 'JOIN', weight: 1 }, { value: 'LEFT JOIN', weight: 1 }, { value: 'LEFT OUTER JOIN', weight: 1 }, { value: 'RIGHT JOIN', weight: 1 }, { value: 'RIGHT OUTER JOIN', weight: 1 }]);
+     if (isHive()) {
+       keywords = keywords.concat([{ value: 'CROSS JOIN', weight: 1 }, { value: 'LEFT SEMI JOIN', weight: 1 }]);
+     } else if (isImpala()) {
+       keywords = keywords.concat([{ value: 'INNER JOIN', weight: 1 },  { value: 'LEFT ANTI JOIN', weight: 1 }, { value: 'LEFT SEMI JOIN', weight: 1 }, { value: 'RIGHT ANTI JOIN', weight: 1 }, { value: 'RIGHT SEMI JOIN', weight: 1 }]);
+     } else {
+       keywords.push({ value: 'INNER JOIN', weight: 1 });
+     }
+     suggestKeywords(keywords);
+  }
  | FromClause OptionalSelectConditions_EDIT OptionalJoins
    {
      // A couple of things are going on here:
@@ -1301,37 +1363,6 @@ TableExpression_EDIT
      }
      var keywords = [];
 
-     if ($2.cursorAtStart) {
-       if ($1 && typeof $1.hasJoinCondition !== 'undefined' && !$1.hasJoinCondition) {
-         keywords.push({ value: 'ON', weight: 3 });
-         if (isImpala()) {
-           keywords.push({ value: 'USING', weight: 3 });
-         }
-       } else if ($1 && $1.suggestKeywords) {
-         keywords = createWeightedKeywords($1.suggestKeywords, 3);
-       } else if ($1 && $1.types) {
-         var veKeywords = getValueExpressionKeywords($1);
-         keywords = veKeywords.suggestKeywords;
-         if (veKeywords.suggestColRefKeywords) {
-           suggestColRefKeywords(veKeywords.suggestColRefKeywords);
-           addColRefIfExists($1);
-         }
-       }
-
-       if ($2.cursorAtEnd && $3 && $3.joinType.toUpperCase() === 'JOIN') {
-         keywords = keywords.concat(['FULL', 'FULL OUTER', 'LEFT', 'LEFT OUTER', 'RIGHT', 'RIGHT OUTER']);
-         if (isHive()) {
-           keywords = keywords.concat(['CROSS', 'LEFT SEMI']);
-         } else if (isImpala()) {
-           keywords = keywords.concat(['INNER', 'LEFT ANTI', 'LEFT SEMI', 'RIGHT ANTI', 'RIGHT SEMI']);
-         } else {
-           keywords.push('INNER');
-         }
-         suggestKeywords(keywords);
-         return;
-       }
-     }
-
      if ($2.suggestColRefKeywords) {
        suggestColRefKeywords($2.suggestColRefKeywords);
        addColRefIfExists($2);
@@ -1372,6 +1403,12 @@ FromClause_EDIT
 
 OptionalSelectConditions
  : OptionalWhereClause OptionalGroupByClause OptionalHavingClause OptionalWindowClause OptionalOrderByClause OptionalClusterOrDistributeBy OptionalLimitClause OptionalOffsetClause
+   {
+     var keywords = getKeywordsForOptionalsLR([$1, $2, $3, $4, $5, $6, $7, $8], [{ value: 'WHERE', weight: 9 }, { 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, true, isHive(), true, isHive(), true, isImpala()]);
+     if (keywords.length > 0) {
+       $$ = { suggestKeywords: keywords, empty: !$1 && !$2 && !$3 && !$4 && !$5 && !$6 && !$7 && !$8 }
+     }
+   }
  ;
 
 OptionalSelectConditions_EDIT
@@ -1386,21 +1423,7 @@ OptionalSelectConditions_EDIT
  ;
 
 OptionalSelectConditions_EDIT
- : 'CURSOR' OptionalWhereClause OptionalGroupByClause OptionalHavingClause OptionalWindowClause OptionalOrderByClause OptionalClusterOrDistributeBy OptionalLimitClause OptionalOffsetClause
-   {
-     var keywords = getKeywordsForOptionalsLR([$2, $3, $4, $5, $6, $7, $8, $9], [{ value: 'WHERE', weight: 9 }, { 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, true, isHive(), true, isHive(), true, isImpala()]);
-
-     keywords = keywords.concat([{ value: 'FULL JOIN', weight: 1 }, { value: 'FULL OUTER JOIN', weight: 1 }, { value: 'JOIN', weight: 1 }, { value: 'LEFT JOIN', weight: 1 }, { value: 'LEFT OUTER JOIN', weight: 1 }, { value: 'RIGHT JOIN', weight: 1 }, { value: 'RIGHT OUTER JOIN', weight: 1 }]);
-     if (isHive()) {
-       keywords = keywords.concat([{ value: 'CROSS JOIN', weight: 1 }, { value: 'LEFT SEMI JOIN', weight: 1 }]);
-     } else if (isImpala()) {
-       keywords = keywords.concat([{ value: 'INNER JOIN', weight: 1 },  { value: 'LEFT ANTI JOIN', weight: 1 }, { value: 'LEFT SEMI JOIN', weight: 1 }, { value: 'RIGHT ANTI JOIN', weight: 1 }, { value: 'RIGHT SEMI JOIN', weight: 1 }]);
-     } else {
-       keywords.push({ value: 'INNER JOIN', weight: 1 });
-     }
-     $$ = { suggestKeywords: keywords, cursorAtStart: true, cursorAtEnd: !$2 && !$3 && !$4 && !$5 && !$6 && !$7 && !$8 && !$9 };
-  }
- | WhereClause 'CURSOR' OptionalGroupByClause OptionalHavingClause OptionalWindowClause OptionalOrderByClause OptionalClusterOrDistributeBy OptionalLimitClause OptionalOffsetClause
+ : WhereClause 'CURSOR' OptionalGroupByClause OptionalHavingClause OptionalWindowClause OptionalOrderByClause OptionalClusterOrDistributeBy OptionalLimitClause OptionalOffsetClause
    {
      var keywords = getKeywordsForOptionalsLR([$3, $4, $5, $6, $7, $8, $9], [{ 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()]);
      if ($1.suggestKeywords) {

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js


+ 29 - 5
desktop/core/src/desktop/static/desktop/js/autocomplete/sql_support.js

@@ -18,7 +18,6 @@ var prepareNewStatement = function () {
   linkTablePrimaries();
   commitLocations();
 
-  delete parser.yy.caseDetermined;
   delete parser.yy.latestTablePrimaries;
   delete parser.yy.latestCommonTableExpressions;
   delete parser.yy.correlatedSubQuery;
@@ -214,7 +213,7 @@ var commitLocations = function () {
   var i = parser.yy.locations.length;
   while (i--) {
     var location = parser.yy.locations[i];
-    expandIdentifierChain(location);
+    expandIdentifierChain(location, true);
     // 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' && location.table && typeof location.identifierChain !== 'undefined' && location.identifierChain.length > 0) {
@@ -342,6 +341,9 @@ parser.expandImpalaIdentifierChain = function (tablePrimaries, identifierChain)
           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);
@@ -400,7 +402,7 @@ parser.expandLateralViews = function (tablePrimaries, originalIdentifierChain) {
   return identifierChain;
 };
 
-var expandIdentifierChain = function (wrapper) {
+var expandIdentifierChain = function (wrapper, anyOwner) {
   if (typeof wrapper.identifierChain === 'undefined' || typeof parser.yy.latestTablePrimaries === 'undefined') {
     return;
   }
@@ -408,6 +410,10 @@ var expandIdentifierChain = function (wrapper) {
   var identifierChain = wrapper.identifierChain.concat();
   var tablePrimaries = parser.yy.latestTablePrimaries;
 
+  if (!anyOwner) {
+    tablePrimaries = filterTablePrimariesForOwner(wrapper.owner);
+  }
+
   if (identifierChain.length > 0 && identifierChain[identifierChain.length - 1].asterisk) {
     var tables = [];
     tablePrimaries.forEach(function (tablePrimary) {
@@ -496,6 +502,7 @@ var expandIdentifierChain = function (wrapper) {
       wrapper.subQuery = tablePrimaries[0].subQueryAlias;
     }
   }
+  delete wrapper.owner;
   wrapper.linked = true;
 };
 
@@ -543,21 +550,37 @@ var suggestLateralViewAliasesAsIdentifiers = function () {
   }
 };
 
+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 linkTablePrimaries = function () {
   if (!parser.yy.cursorFound || typeof parser.yy.latestTablePrimaries === 'undefined') {
     return;
   }
+
+  var tablePrimaries = parser.yy.latestTablePrimaries;
   if (typeof parser.yy.result.suggestColumns !== 'undefined' && !parser.yy.result.suggestColumns.linked) {
+    tablePrimaries = filterTablePrimariesForOwner(parser.yy.result.suggestColumns.owner);
+
     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 (parser.yy.latestTablePrimaries.length > 1) {
+      if (tablePrimaries.length > 1) {
         suggestTablePrimariesAsIdentifiers();
         delete parser.yy.result.suggestColumns;
       } else {
         suggestLateralViewAliasesAsIdentifiers();
-        if (parser.yy.latestTablePrimaries.length == 1 && (parser.yy.latestTablePrimaries[0].alias || parser.yy.latestTablePrimaries[0].subQueryAlias)) {
+        if (tablePrimaries.length == 1 && (tablePrimaries[0].alias || tablePrimaries[0].subQueryAlias)) {
           suggestTablePrimariesAsIdentifiers();
         }
         expandIdentifierChain(parser.yy.result.suggestColumns);
@@ -858,6 +881,7 @@ parser.parseSql = function (beforeCursor, afterCursor, dialect, sqlFunctions, de
   parser.yy.subQueries = [];
   parser.yy.errors = [];
 
+  delete parser.yy.caseDetermined;
   delete parser.yy.cursorFound;
   delete parser.yy.partialCursor;
 

+ 10 - 9
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpec.js

@@ -23,6 +23,7 @@ define([
   'desktop/spec/autocomplete/sqlSpecDescribe',
   'desktop/spec/autocomplete/sqlSpecDrop',
   'desktop/spec/autocomplete/sqlSpecError',
+  'desktop/spec/autocomplete/sqlSpecInsert',
   'desktop/spec/autocomplete/sqlSpecLoad',
   'desktop/spec/autocomplete/sqlSpecSelect',
   'desktop/spec/autocomplete/sqlSpecSet',
@@ -142,9 +143,9 @@ define([
         });
       });
 
-      it('should suggest keywords for "FROM USE; |"', function() {
+      it('should suggest keywords for "INTO USE; |"', function() {
         assertAutoComplete({
-          beforeCursor: 'FROM USE; ',
+          beforeCursor: 'INTO USE; ',
           afterCursor: '',
           containsKeywords: ['SELECT'],
           expectedResult: {
@@ -153,9 +154,9 @@ define([
         });
       });
 
-      it('should suggest keywords for "FROM SELECT; OR FROM FROM; |"', function() {
+      it('should suggest keywords for "INTO SELECT; OR FROM FROM; |"', function() {
         assertAutoComplete({
-          beforeCursor: 'FROM SELECT; OR FROM FROM;',
+          beforeCursor: 'INTO SELECT; OR FROM FROM;',
           afterCursor: '',
           containsKeywords: ['SELECT'],
           expectedResult: {
@@ -164,9 +165,9 @@ define([
         });
       });
 
-      it('should suggest keywords for "FROM SELECT; OR FROM FROM; |;BLAAA; AND;"', function() {
+      it('should suggest keywords for "INTO SELECT; OR FROM FROM; |;BLAAA; AND;"', function() {
         assertAutoComplete({
-          beforeCursor: 'FROM SELECT; OR FROM FROM;',
+          beforeCursor: 'INTO SELECT; OR FROM FROM;',
           afterCursor: ';BLAAA; AND;',
           containsKeywords: ['SELECT'],
           expectedResult: {
@@ -175,9 +176,9 @@ define([
         });
       });
       
-      it('should suggest keywords for "FROM bla bla;AND booo; |"', function() {
+      it('should suggest keywords for "INTO bla bla;AND booo; |"', function() {
         assertAutoComplete({
-          beforeCursor: 'FROM bla bla;AND booo;',
+          beforeCursor: 'INTO bla bla;AND booo;',
           afterCursor: '',
           containsKeywords: ['SELECT'],
           expectedResult: {
@@ -346,7 +347,7 @@ define([
           expectedResult: {
             lowerCase: false,
             suggestKeywords: ['ALTER', 'ANALYZE', 'CREATE', 'DELETE', 'DESCRIBE',
-              'DROP', 'EXPLAIN', 'EXPORT', 'IMPORT', 'INSERT', 'LOAD', 'MSCK',
+              'DROP', 'EXPLAIN', 'EXPORT', 'FROM', 'IMPORT', 'INSERT', 'LOAD', 'MSCK',
               'RELOAD FUNCTION', 'RESET', 'REVOKE', 'SELECT', 'SET', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE', 'WITH']
           }
         });

+ 863 - 0
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecInsert.js

@@ -0,0 +1,863 @@
+// 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.
+define([
+  'knockout',
+  'desktop/js/autocomplete/sql',
+  'desktop/spec/autocompleterTestUtils'
+], function(ko, sql, testUtils) {
+
+  describe('sql.js INSERT statements', function() {
+
+    beforeAll(function () {
+      sql.yy.parseError = function (msg) {
+        throw Error(msg);
+      };
+      jasmine.addMatchers(testUtils.testDefinitionMatcher);
+    });
+
+    var assertAutoComplete = testUtils.assertAutocomplete;
+
+    it('should handle "INSERT INTO bla.boo VALUES (1, 2, \'a\', 3); |"', function() {
+      assertAutoComplete({
+        beforeCursor: 'INSERT INTO bla.boo VALUES (1, 2, \'a\', 3); ',
+        afterCursor: '',
+        noErrors: true,
+        hasLocations: true,
+        containsKeywords: ['SELECT'],
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    it('should suggest keywords for "|"', function() {
+      assertAutoComplete({
+        beforeCursor: '',
+        afterCursor: '',
+        containsKeywords: ['INSERT'],
+        noErrors: true,
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    it('should suggest keywords for "INSERT |"', function() {
+      assertAutoComplete({
+        beforeCursor: 'INSERT ',
+        afterCursor: '',
+        containsKeywords: ['INTO'],
+        noErrors: true,
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    it('should suggest tables for "INSERT INTO |"', function() {
+      assertAutoComplete({
+        beforeCursor: 'INSERT INTO ',
+        afterCursor: '',
+        noErrors: true,
+        expectedResult: {
+          lowerCase: false,
+          suggestTables: {},
+          suggestDatabases: { appendDot: true },
+          suggestKeywords: ['TABLE']
+        }
+      });
+    });
+
+    it('should suggest tables for "INSERT INTO baa.|"', function() {
+      assertAutoComplete({
+        beforeCursor: 'INSERT INTO baa.',
+        afterCursor: '',
+        noErrors: true,
+        expectedResult: {
+          lowerCase: false,
+          suggestTables: { database: 'baa' }
+        }
+      });
+    });
+
+    it('should suggest tables for "INSERT INTO TABLE baa.|"', function() {
+      assertAutoComplete({
+        beforeCursor: 'INSERT INTO TABLE baa.',
+        afterCursor: '',
+        noErrors: true,
+        expectedResult: {
+          lowerCase: false,
+          suggestTables: { database: 'baa' }
+        }
+      });
+    });
+
+    it('should suggest keywords for "INSERT INTO baa |"', function() {
+      assertAutoComplete({
+        beforeCursor: 'INSERT INTO baa ',
+        afterCursor: '',
+        containsKeywords: ['VALUES'],
+        noErrors: true,
+        hasLocations: true,
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    it('should suggest keywords for "INSERT INTO TABLE baa |"', function() {
+      assertAutoComplete({
+        beforeCursor: 'INSERT INTO TABLE baa ',
+        afterCursor: '',
+        containsKeywords: ['VALUES'],
+        noErrors: true,
+        hasLocations: true,
+        expectedResult: {
+          lowerCase: false
+        }
+      });
+    });
+
+    describe('Hive specific', function () {
+      it('should handle "INSERT OVERWRITE TABLE bla.boo PARTITION (bla=1, bo) IF NOT EXISTS SELECT ba.boo, ba, ble FROM db.tbl; |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE TABLE bla.boo PARTITION (bla=1, bo) IF NOT EXISTS SELECT ba.boo, ba, ble FROM db.tbl;',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should handle "INSERT INTO TABLE bla.boo PARTITION (bla=1, bo) (a, b, c) SELECT ba.boo, ba, ble FROM db.tbl; |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO TABLE bla.boo PARTITION (bla=1, bo) (a, b, c) SELECT ba.boo, ba, ble FROM db.tbl;',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should handle "INSERT INTO bla.boo SELECT ba.boo, ba, ble FROM db.tbl; |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO bla.boo SELECT ba.boo, ba, ble FROM db.tbl;',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should handle "FROM boo.baa\\nINSERT INTO TABLE baa2 PARTITION (a, b) SELECT * ORDER BY ba\\nINSERT INTO TABLE baa3 SELECT * GROUP BY boo;|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM boo.baa\n' +
+          'INSERT INTO TABLE baa2 PARTITION (a, b) SELECT * ORDER BY ba\n' +
+          'INSERT INTO TABLE baa3 SELECT * GROUP BY boo;',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should handle "FROM boo.baa SELECT * ORDER BY ba;|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM boo.baa SELECT * ORDER BY ba;',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should suggest keywords for "|"', function() {
+        assertAutoComplete({
+          beforeCursor: '',
+          afterCursor: '',
+          dialect: 'hive',
+          containsKeywords: ['FROM', 'INSERT'],
+          noErrors: true,
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should suggest tables for "FROM |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest keywords for "from baa.boo |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'from baa.boo ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: true,
+            suggestKeywords: ['INSERT INTO', 'INSERT OVERWRITE', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['INTO', 'OVERWRITE']
+          }
+        });
+      });
+
+      it('should suggest tables for "FROM baa.boo INSERT INTO |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {},
+            suggestDatabases: { appendDot: true },
+            suggestKeywords: ['TABLE']
+          }
+        });
+      });
+
+      it('should suggest tables for "FROM baa.boo INSERT INTO baa.|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO baa.',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: { database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT INTO TABLE baa |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO TABLE baa ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['PARTITION', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest columns for "FROM baa.boo INSERT INTO TABLE baa PARTITION (|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO TABLE baa PARTITION (',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestColumns: { table: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest columns for "FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestColumns: { table: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (x, z) |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (x, z) ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['SELECT']
+          }
+        });
+      });
+
+      it('should suggest columns for "FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['ALL', 'DISTINCT'],
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: {},
+            suggestAggregateFunctions: true,
+            suggestAnalyticFunctions: true,
+            suggestColumns: { table: 'boo', database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest columns for "FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT c INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT a, |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT c INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT a, ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: {},
+            suggestAggregateFunctions: true,
+            suggestAnalyticFunctions: true,
+            suggestColumns: { table: 'boo', database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT c, d |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT c, d ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsColRefKeywords: true,
+          containsKeywords: ['WHERE', 'ORDER BY'],
+          doesNotContainKeywords: ['FROM'],
+          expectedResult: {
+            lowerCase: false,
+            colRef: { identifierChain: [{ name: 'd' }], table: 'boo', database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT OVERWRITE bla.ble |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['PARTITION', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT OVERWRITE bla.ble |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['PARTITION', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest columns for "FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestColumns: { table: 'ble', database: 'bla' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['IF NOT EXISTS', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) IF |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) IF ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['NOT EXISTS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['EXISTS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT EXISTS |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT EXISTS ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['SELECT']
+          }
+        });
+      });
+
+      it('should suggest columns for "FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT EXISTS SELECT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT EXISTS SELECT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['*'],
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: {},
+            suggestAggregateFunctions: true,
+            suggestAnalyticFunctions: true,
+            suggestColumns: { table: 'boo', database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT OVERWRITE bla.ble SELECT c, d |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble SELECT c, d ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsColRefKeywords: true,
+          containsKeywords: ['WHERE', 'ORDER BY'],
+          doesNotContainKeywords: ['FROM'],
+          expectedResult: {
+            lowerCase: false,
+            colRef: { identifierChain: [{ name: 'd' }], table: 'boo', database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo INSERT OVERWRITE bla.ble SELECT c, d INSERT OVERWRITE bla.ble SELECT a |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo INSERT OVERWRITE bla.ble SELECT c, d INSERT OVERWRITE bla.ble SELECT a ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsColRefKeywords: true,
+          containsKeywords: ['WHERE', 'ORDER BY'],
+          doesNotContainKeywords: ['FROM'],
+          expectedResult: {
+            lowerCase: false,
+            colRef: { identifierChain: [{ name: 'a' }], table: 'boo', database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest columns for "FROM baa.boo SELECT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo SELECT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['*'],
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: {},
+            suggestAggregateFunctions: true,
+            suggestAnalyticFunctions: true,
+            suggestColumns: { table: 'boo', database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "FROM baa.boo SELECT c, d |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'FROM baa.boo SELECT c, d ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsColRefKeywords: true,
+          containsKeywords: ['WHERE', 'ORDER BY'],
+          doesNotContainKeywords: ['FROM'],
+          expectedResult: {
+            lowerCase: false,
+            colRef: { identifierChain: [{ name: 'd' }], table: 'boo', database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['INTO', 'OVERWRITE']
+          }
+        });
+      });
+
+      it('should suggest tables for "INSERT INTO |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {},
+            suggestDatabases: { appendDot: true },
+            suggestKeywords: ['TABLE']
+          }
+        });
+      });
+
+      it('should suggest tables for "INSERT INTO baa.|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO baa.',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: { database: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT INTO TABLE baa |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO TABLE baa ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['PARTITION', 'VALUES', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest columns for "INSERT INTO TABLE baa PARTITION (|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO TABLE baa PARTITION (',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestColumns: { table: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest columns for "INSERT INTO TABLE baa PARTITION (a,b) (x, |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO TABLE baa PARTITION (a,b) (x, ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestColumns: { table: 'baa' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "insert into table baa partition (a,b) (x, z) |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'insert into table baa partition (a,b) (x, z) ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: true,
+            suggestKeywords: ['SELECT']
+          }
+        });
+      });
+
+      it('should suggest columns for "INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['*'],
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: {},
+            suggestAggregateFunctions: true,
+            suggestAnalyticFunctions: true,
+            suggestTables: { prependFrom: true, prependQuestionMark: true },
+            suggestDatabases:  { prependFrom: true, prependQuestionMark: true, appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest columns for "INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT c, |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT c, ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: {},
+            suggestAggregateFunctions: true,
+            suggestAnalyticFunctions: true,
+            suggestTables: { prependFrom: true, prependQuestionMark: true },
+            suggestDatabases:  { prependFrom: true, prependQuestionMark: true, appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT c, d |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT INTO TABLE baa PARTITION (a,b) (x, z) SELECT c, d ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['AS', 'IN'],
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: { prependFrom: true },
+            suggestDatabases:  { prependFrom: true, appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT OVERWRITE bla.ble |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['PARTITION', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT OVERWRITE bla.ble |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['PARTITION', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest columns for "INSERT OVERWRITE bla.ble PARTITION (|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble PARTITION (',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestColumns: { table: 'ble', database: 'bla' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT OVERWRITE bla.ble PARTITION (a, b) |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble PARTITION (a, b) ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['IF NOT EXISTS', 'SELECT']
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT OVERWRITE bla.ble PARTITION (a, b) IF |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble PARTITION (a, b) IF ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['NOT EXISTS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['EXISTS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT EXISTS |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT EXISTS ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['SELECT']
+          }
+        });
+      });
+
+      it('should suggest columns for "INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT EXISTS SELECT |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble PARTITION (a, b) IF NOT EXISTS SELECT ',
+          afterCursor: '',
+          dialect: 'hive',
+          noErrors: true,
+          hasLocations: true,
+          containsKeywords: ['*'],
+          expectedResult: {
+            lowerCase: false,
+            suggestFunctions: {},
+            suggestAggregateFunctions: true,
+            suggestAnalyticFunctions: true,
+            suggestTables: { prependFrom: true, prependQuestionMark: true },
+            suggestDatabases:  { prependFrom: true, prependQuestionMark: true, appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest keywords for "INSERT OVERWRITE bla.ble SELECT c, d |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'INSERT OVERWRITE bla.ble SELECT c, d ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          noErrors: true,
+          containsKeywords: ['AS', 'IN'],
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: { prependFrom: true },
+            suggestDatabases:  { prependFrom: true, appendDot: true }
+          }
+        });
+      });
+    });
+  });
+});

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

@@ -65,9 +65,9 @@ define([
       });
     });
 
-    it('should use a use statement for "USE database_two; \\nselect |"', function () {
+    it('should use a use statement for "use database_two; \\nselect |"', function () {
       assertAutoComplete({
-        beforeCursor: 'USE database_two; \nselect ',
+        beforeCursor: 'use database_two; \nSELECT ',
         afterCursor: '',
         containsKeywords: ['*', 'ALL', 'DISTINCT'],
         expectedResult: {

+ 1 - 1
tools/jison/hue-jison.sh

@@ -30,7 +30,7 @@ echo "%%" > sql_end.jison
 # With this all create tests will pass
 # cat sql_main.jison sql_create.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_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_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
 
 jison sql.jison sql.jisonlex -m amd
 cat license.txt sql.js > ../sql.js

Неке датотеке нису приказане због велике количине промена