Jelajahi Sumber

HUE-4535 [editor] Add autocomplete for CREATE and ALTER statements

This covers:
- Impala CREATE (FUNCTION, ROLE, VIEW), the Impala CREATE is now complete according to docs
- Hive CREATE (FUNCTION, INDEX, ROLE, VIEW)
- Impala and Hive ALTER TABLE
- Some small improvements here and there
Johan Ahlen 9 tahun lalu
induk
melakukan
221ac4f1fd

+ 0 - 6000
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql.jison

@@ -1,6000 +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.
-
-%left 'AND' 'OR'
-%left 'BETWEEN'
-%left 'NOT' '!' '~'
-%left '=' '<' '>' 'COMPARISON_OPERATOR'
-%left '-' '*' 'ARITHMETIC_OPERATOR'
-
-%left ';'
-%nonassoc 'CURSOR' 'PARTIAL_CURSOR'
-%nonassoc 'IN' 'IS' 'LIKE' 'RLIKE' 'REGEXP' 'EXISTS' NEGATION
-
-%start Sql
-
-%%
-
-NonReservedKeyword
- : '<hive>AVRO'
- | '<hive>BUCKETS'
- | '<hive>CLUSTERED'
- | '<hive>COLLECTION'
- | '<hive>COLUMNS'
- | '<hive>COMMENT'
- | '<hive>COMPACTIONS'
- | '<hive>DATA'
- | '<hive>DATABASES'
- | '<hive>DEFINED'
- | '<hive>DELIMITED'
- | '<hive>ESCAPED'
- | '<hive>FIELDS'
- | '<hive>FORMAT'
- | '<hive>FUNCTIONS'
- | '<hive>INPATH'
- | '<hive>INPUTFORMAT'
- | '<hive>ITEMS'
- | '<hive>KEYS'
- | '<hive>LINES'
- | '<hive>LOAD'
- | '<hive>LOCATION'
- | '<hive>LOCKS'
- | '<hive>ORC'
- | '<hive>OUTPUTFORMAT'
- | '<hive>PARQUET'
- | '<hive>PARTITIONED'
- | '<hive>PARTITIONS'
- | '<hive>RCFILE'
- | '<hive>ROLE'
- | '<hive>ROLES'
- | '<hive>SCHEMAS'
- | '<hive>SEQUENCEFILE'
- | '<hive>SERDE'
- | '<hive>SERDEPROPERTIES'
- | '<hive>SKEWED'
- | '<hive>SORTED'
- | '<hive>STORED'
- | '<hive>STRING'
- | '<hive>STRUCT'
- | '<hive>TABLES'
- | '<hive>TBLPROPERTIES'
- | '<hive>TEMPORARY'
- | '<hive>TERMINATED'
- | '<hive>TEXTFILE'
- | '<hive>TINYINT'
- | '<hive>TRANSACTIONS'
- | '<hive>UNIONTYPE'
- | '<hive>USE'
- | '<hive>VIEW'
-// | '<hive>ASC'      // These cause conflicts, we need separate lexer state for DESCRIBE and SHOW then it should be fine
-// | '<hive>DESC'
-// | '<hive>FORMATTED'
-// | '<hive>INDEX'
-// | '<hive>INDEXES'
-// | '<hive>LIMIT'
-// | '<hive>SCHEMA'
-// | '<hive>SHOW'
- | '<impala>ANALYTIC'
- | '<impala>ANTI'
- | '<impala>CURRENT'
- | '<impala>GRANT'
- | '<impala>ROLE'
- | '<impala>ROLES'
- | 'ROLE'
- ;
-
-RegularIdentifier
- : 'REGULAR_IDENTIFIER'
- | 'VARIABLE_REFERENCE'
- | NonReservedKeyword
- ;
-
-NewStatement
- : /* empty */
-   {
-     prepareNewStatement();
-   }
- ;
-
-Sql
- : NewStatement SqlStatements EOF
-   {
-     return parser.yy.result;
-   }
- | NewStatement SqlStatements_EDIT EOF
-   {
-     return parser.yy.result;
-   }
- ;
-
-SqlStatements
- :
- | ErrorStatement
- | DataDefinition
- | DataManipulation
- | QuerySpecification
- | SqlStatements ';' NewStatement SqlStatements
- ;
-
-
-ErrorStatement
- : error
- | NonStartingToken error // Having just ': error' does not work for some reason, jison bug?
- ;
-
-// 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>AVRO' | '<hive>BINARY' | '<hive>BUCKETS' | '<hive>AS' | '<hive>CLUSTERED' | '<hive>COLLECTION' | '<hive>CONF' | '<hive>CROSS' | '<hive>CURRENT' | '<hive>DATE' | '<hive>DELIMITED' | '<hive>ESCAPED' | '<hive>EXTENDED' | '<hive>EXTERNAL' | '<hive>FIELDS' | '<hive>FORMAT' | '<hive>FUNCTION' | '<hive>GRANT' | '<hive>LATERAL' | '<hive>MACRO' | '<hive>TABLE' | '<hive>USER' | '<hive>ASC' | '<hive>COLUMNS' | '<hive>COMMENT' | '<hive>COMPACTIONS' | '<hive>DATA' | '<hive>DATABASES' | '<hive>DEFINED' | '<hive>DESC' | '<hive>STORED_AS_DIRECTORIES' | '<hive>FORMATTED' | '<hive>FUNCTIONS' | '<hive>INDEX' | '<hive>INDEXES' | '<hive>INPATH' | '<hive>INPUTFORMAT' | '<hive>ITEMS' | '<hive>LIMIT' | '<hive>KEYS' | '<hive>LINES' | '<hive>LOCATION' | '<hive>LOCKS' | '<hive>MAP' | '<hive>ORC' | '<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>STRING' | '<hive>STRUCT' | '<hive>TABLES' | '<hive>TBLPROPERTIES' | '<hive>TEMPORARY' | '<hive>TERMINATED' | '<hive>TEXTFILE' | '<hive>TINYINT' | '<hive>TRANSACTIONS' | '<hive>UNIONTYPE' | '<hive>VIEW' | '<hive>WINDOW' | '<hive>.' | '<hive>[' | '<hive>]'
- | '<impala>AGGREGATE' | '<impala>AVRO' | '<impala>CACHED' | '<impala>COLUMN' | '<impala>COMMENT' | '<impala>DATA' | '<impala>DATABASES' | '<impala>DELIMITED' | '<impala>ESCAPED' | '<impala>EXTERNAL' | '<impala>FIELDS' | '<impala>FIRST' | '<impala>FORMAT' | '<impala>FORMATTED' | '<impala>FUNCTION' | '<impala>FUNCTIONS' | '<impala>GROUP' | '<impala>INCREMENTAL' | '<impala>INPATH' | '<impala>LAST' | '<impala>LINES' | '<impala>LOCATION' | '<impala>NULLS' | '<impala>PARTITIONS' | '<impala>REAL' | '<impala>SCHEMAS' | '<impala>STATS' | '<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>BROADCAST' | '<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' | 'GROUPING' | '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' | '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'
- | 'ANALYTIC'
- | 'UNSIGNED_INTEGER' | 'UNSIGNED_INTEGER_E' | 'REGULAR_IDENTIFIER' | 'HDFS_START_QUOTE' | 'AND' | 'OR' | '=' | '<' | '>' | 'COMPARISON_OPERATOR' | '-' | '*' | 'ARITHMETIC_OPERATOR' | ',' | '.' | '~' | '!' | '(' | ')' | '[' | ']' | 'VARIABLE_REFERENCE' | 'BACKTICK' | 'SINGLE_QUOTE' | 'DOUBLE_QUOTE'
- ;
-
-SqlStatements_EDIT
- : SqlStatement_EDIT
- | SqlStatement_EDIT ';' NewStatement SqlStatements
- | SqlStatements ';' NewStatement SqlStatement_EDIT
- | SqlStatements ';' NewStatement SqlStatement_EDIT ';' NewStatement SqlStatements
- ;
-
-SqlStatement_EDIT
- : AnyCursor
-   {
-     suggestDdlAndDmlKeywords();
-   }
- | DataDefinition_EDIT
- | DataManipulation_EDIT
- | QuerySpecification_EDIT
- ;
-
-DataDefinition
- : DescribeStatement
- | DropStatement
- ;
-
-DataDefinition_EDIT
- : DescribeStatement_EDIT
- | DropStatement_EDIT
- ;
-
-DataManipulation
- : LoadStatement
- ;
-
-DataManipulation_EDIT
- : LoadStatement_EDIT
- ;
-
-
-// ===================================== Commonly used constructs =====================================
-
-AggregateOrAnalytic
- : '<impala>AGGREGATE'
- | '<impala>ANALYTIC'
- ;
-
-AnyCreate
- : 'CREATE'
- | '<hive>CREATE'
- | '<impala>CREATE'
- ;
-
-AnyCursor
- : 'CURSOR'
- | 'PARTIAL_CURSOR'
- ;
-
-AnyDot
- : '.'
- | '<impala>.'
- | '<hive>.'
- ;
-
-AnyFromOrIn
- : 'FROM'
- | 'IN'
- ;
-
-AnyTable
- : 'TABLE'
- | '<hive>TABLE'
- | '<impala>TABLE'
- ;
-
-DatabaseOrSchema
- : 'DATABASE'
- | 'SCHEMA'
- | '<hive>SCHEMA'
- ;
-
-FromOrIn
- : 'FROM'
- | 'IN'
- ;
-
-HiveIndexOrIndexes
- : '<hive>INDEX'
- | '<hive>INDEXES'
- ;
-
-HiveOrImpalaComment
- : '<hive>COMMENT'
- | '<impala>COMMENT'
- ;
-
-HiveOrImpalaCreate
- : '<hive>CREATE'
- | '<impala>CREATE'
- ;
-
-HiveOrImpalaCurrent
- : '<hive>CURRENT'
- | '<impala>CURRENT'
- ;
-
-HiveOrImpalaData
- : '<hive>DATA'
- | '<impala>DATA'
- ;
-
-HiveOrImpalaDatabasesOrSchemas
- : '<hive>DATABASES'
- | '<hive>SCHEMAS'
- | '<impala>DATABASES'
- | '<impala>SCHEMAS'
- ;
-
-HiveOrImpalaExternal
- : '<hive>EXTERNAL'
- | '<impala>EXTERNAL'
- ;
-
-HiveOrImpalaLoad
- : '<hive>LOAD'
- | '<impala>LOAD'
- ;
-
-HiveOrImpalaInpath
- : '<hive>INPATH'
- | '<impala>INPATH'
- ;
-
-HiveOrImpalaLeftSquareBracket
- : '<hive>['
- | '<impala>['
- ;
-
-HiveOrImpalaLocation
- : '<hive>LOCATION'
- | '<impala>LOCATION'
- ;
-
-HiveOrImpalaRightSquareBracket
- : '<hive>]'
- | '<impala>]'
- ;
-
-HiveOrImpalaTables
- : '<hive>TABLES'
- | '<impala>TABLES'
- ;
-
-HiveRoleOrUser
- : '<hive>ROLE'
- | '<hive>USER'
- ;
-
-SingleQuotedValue
- : 'SINGLE_QUOTE' 'VALUE' 'SINGLE_QUOTE'  -> $2
- | 'SINGLE_QUOTE' 'SINGLE_QUOTE'          -> ''
- ;
-
-DoubleQuotedValue
- : 'DOUBLE_QUOTE' 'VALUE' 'DOUBLE_QUOTE'  -> $2
- | 'DOUBLE_QUOTE' 'DOUBLE_QUOTE'          -> ''
- ;
-
-AnyAs
- : 'AS'
- | '<hive>AS'
- ;
-
-AnyGroup
- : 'GROUP'
- | '<hive>GROUP'
- | '<impala>GROUP'
- ;
-
-OptionalAggregateOrAnalytic
- :
- | AggregateOrAnalytic
- ;
-
-OptionalExtended
- :
- | '<hive>EXTENDED'
- ;
-
-OptionalExtendedOrFormatted
- :
- | '<hive>EXTENDED'
- | '<hive>FORMATTED'
- ;
-
-OptionalFormatted
- :
- | '<impala>FORMATTED'
- ;
-
-OptionallyFormattedIndex
- : '<hive>FORMATTED' HiveIndexOrIndexes
- | HiveIndexOrIndexes
- ;
-
-OptionallyFormattedIndex_EDIT
- : '<hive>FORMATTED' 'CURSOR'
-   {
-     suggestKeywords(['INDEX', 'INDEXES']);
-   }
- | 'CURSOR' HiveIndexOrIndexes
-   {
-     suggestKeywords(['FORMATTED']);
-   }
- ;
-
-OptionalFromDatabase
- :
- | FromOrIn DatabaseIdentifier
- ;
-
-OptionalFromDatabase_EDIT
- : FromOrIn DatabaseIdentifier_EDIT
- ;
-
-OptionalHiveCascadeOrRestrict
- :
- | '<hive>CASCADE'
- | '<hive>RESTRICT'
- ;
-
-OptionalIfExists
- :
- | 'IF' 'EXISTS'
-   {
-     parser.yy.correlatedSubQuery = false;
-   }
- ;
-
-OptionalIfExists_EDIT
- : 'IF' 'CURSOR'
-   {
-     suggestKeywords(['EXISTS']);
-   }
- ;
-
-OptionalIfNotExists
- :
- | 'IF' 'NOT' 'EXISTS'
-   {
-     parser.yy.correlatedSubQuery = false;
-   }
- ;
-
-OptionalIfNotExists_EDIT
- : 'IF' 'CURSOR'
-   {
-     suggestKeywords(['NOT EXISTS']);
-   }
- | 'IF' 'NOT' 'CURSOR'
-   {
-     suggestKeywords(['EXISTS']);
-   }
- ;
-
-OptionalInDatabase
- :
- | 'IN' DatabaseIdentifier
- | 'IN' DatabaseIdentifier_EDIT
- ;
-
-ConfigurationName
- : RegularIdentifier
- | 'CURSOR'
- | ConfigurationName '<hive>.' RegularIdentifier
- | ConfigurationName '<hive>.' 'PARTIAL_CURSOR'
- ;
-
-PartialBacktickedOrAnyCursor
- : AnyCursor
- | PartialBacktickedIdentifier
- ;
-
-PartialBacktickedOrCursor
- : 'CURSOR'
- | PartialBacktickedIdentifier
- ;
-
-PartialBacktickedOrPartialCursor
- : 'PARTIAL_CURSOR'
- | PartialBacktickedIdentifier
- ;
-
-PartialBacktickedIdentifier
- : 'BACKTICK' 'PARTIAL_VALUE'
- ;
-
-RightParenthesisOrError
- : ')'
- | error
- ;
-
-SchemaQualifiedTableIdentifier
- : RegularOrBacktickedIdentifier
-   {
-     addTableLocation(@1, [ { name: $1 } ]);
-     $$ = { identifierChain: [ { name: $1 } ] };
-   }
- | RegularOrBacktickedIdentifier AnyDot RegularOrBacktickedIdentifier
-   {
-     addTableLocation(@3, [ { name: $1 }, { name: $3 } ]);
-     $$ = { identifierChain: [ { name: $1 }, { name: $3 } ] };
-   }
- ;
-
-SchemaQualifiedTableIdentifier_EDIT
- : PartialBacktickedIdentifier
-   {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
-   }
- | PartialBacktickedIdentifier AnyDot RegularOrBacktickedIdentifier
-   {
-     suggestDatabases();
-     $$ = { identifierChain: [{ name: $1 }] };
-   }
- | RegularOrBacktickedIdentifier AnyDot PartialBacktickedOrPartialCursor
-   {
-     // In Impala you can have statements like 'SELECT ... FROM testTable t, t.|'
-     suggestTablesOrColumns($1);
-   }
- ;
-
-DatabaseIdentifier
- : RegularOrBacktickedIdentifier
- ;
-
-DatabaseIdentifier_EDIT
- : PartialBacktickedOrCursor
-   {
-     suggestDatabases();
-     $$ = { cursorOrPartialIdentifier: true };
-   }
- ;
-
-PartitionSpecList
- : PartitionSpec
- | PartitionSpecList ',' PartitionSpec
- ;
-
-PartitionSpec
- : RegularOrBacktickedIdentifier '=' SingleQuotedValue
- ;
-
-RegularOrBacktickedIdentifier
- : RegularIdentifier
- | 'BACKTICK' 'VALUE' 'BACKTICK'  -> $2
- | 'BACKTICK' 'BACKTICK'          -> ''
- ;
-
-// TODO: Same as SchemaQualifiedTableIdentifier?
-RegularOrBackTickedSchemaQualifiedName
- : RegularOrBacktickedIdentifier
-   {
-     addTableLocation(@1, [ { name: $1 } ]);
-     $$ = { identifierChain: [ { name: $1 } ] };
-   }
- | RegularOrBacktickedIdentifier AnyDot RegularOrBacktickedIdentifier
-   {
-     addTableLocation(@3, [ { name: $1 }, { name: $3 } ]);
-     $$ = { identifierChain: [ { name: $1 }, { name: $3 } ] };
-   }
- ;
-
-RegularOrBackTickedSchemaQualifiedName_EDIT
- : PartialBacktickedIdentifier
-   {
-     suggestTables();
-     suggestDatabases({ prependDot: true });
-   }
- | RegularOrBacktickedIdentifier AnyDot PartialBacktickedOrPartialCursor
-   {
-     suggestTablesOrColumns($1);
-   }
- ;
-
-
-LocalOrSchemaQualifiedName
- : RegularOrBackTickedSchemaQualifiedName
- | RegularOrBackTickedSchemaQualifiedName RegularOrBacktickedIdentifier  -> { identifierChain: $1.identifierChain, alias: $2 }
- ;
-
-LocalOrSchemaQualifiedName_EDIT
- : RegularOrBackTickedSchemaQualifiedName_EDIT
- | RegularOrBackTickedSchemaQualifiedName_EDIT RegularOrBacktickedIdentifier
- ;
-
-ColumnReference
- : BasicIdentifierChain
-   {
-     addColumnLocation(@1, $1);
-   }
- | BasicIdentifierChain AnyDot '*'
-   {
-     addColumnLocation(@1, $1);
-   }
- ;
-
-ColumnReference_EDIT
- : BasicIdentifierChain_EDIT
- ;
-
-BasicIdentifierChain
- : ColumnIdentifier                              -> [ $1 ]
- | BasicIdentifierChain AnyDot ColumnIdentifier
-   {
-     $1.push($3);
-   }
- ;
-
-// TODO: Merge with DerivedColumnChain_EDIT ( issue is starting with PartialBacktickedOrPartialCursor)
-BasicIdentifierChain_EDIT
- : ColumnIdentifier_EDIT
-   {
-     if ($1.insideKey) {
-       suggestKeyValues({ identifierChain: [{ name: $1.name }] });
-       suggestColumns();
-       suggestFunctions();
-     }
-   }
- | BasicIdentifierChain AnyDot ColumnIdentifier_EDIT
-   {
-     if ($3.insideKey) {
-       suggestKeyValues({ identifierChain: $1.concat({ name: $3.name }) });
-       suggestColumns();
-       suggestFunctions();
-     }
-   }
- | BasicIdentifierChain AnyDot ColumnIdentifier_EDIT AnyDot BasicIdentifierChain
- | ColumnIdentifier_EDIT AnyDot BasicIdentifierChain
- | BasicIdentifierChain AnyDot PartialBacktickedOrPartialCursor
-   {
-     suggestColumns({
-       identifierChain: $1
-     });
-     $$ = { suggestKeywords: ['*'] };
-   }
- | BasicIdentifierChain AnyDot PartialBacktickedOrPartialCursor AnyDot BasicIdentifierChain
-   {
-     suggestColumns({
-       identifierChain: $1
-     });
-     $$ = { suggestKeywords: ['*'] };
-   }
- ;
-
-DerivedColumnChain
- : ColumnIdentifier  -> [ $1 ]
- | DerivedColumnChain AnyDot ColumnIdentifier
-   {
-     $1.push($3);
-   }
- ;
-
-DerivedColumnChain_EDIT
- : ColumnIdentifier_EDIT
-   {
-     if ($1.insideKey) {
-       suggestKeyValues({ identifierChain: [{ name: $1.name }] });
-       suggestColumns();
-       suggestFunctions();
-     }
-   }
- | DerivedColumnChain AnyDot ColumnIdentifier_EDIT
-   {
-     if ($3.insideKey) {
-       suggestKeyValues({ identifierChain: $1.concat({ name: $3.name }) });
-       suggestColumns();
-       suggestFunctions();
-     }
-   }
- | DerivedColumnChain AnyDot ColumnIdentifier_EDIT AnyDot DerivedColumnChain
-   {
-     if ($3.insideKey) {
-       suggestKeyValues({ identifierChain: $1.concat({ name: $3.name }) });
-       suggestColumns();
-       suggestFunctions();
-     }
-   }
- | ColumnIdentifier_EDIT AnyDot DerivedColumnChain
-   {
-     if ($1.insideKey) {
-       suggestKeyValues({ identifierChain: [{ name: $1.name }] });
-       suggestColumns();
-       suggestFunctions();
-     }
-   }
- | PartialBacktickedIdentifierOrPartialCursor
-   {
-     suggestColumns();
-   }
- | DerivedColumnChain AnyDot PartialBacktickedIdentifierOrPartialCursor
-   {
-     suggestColumns({ identifierChain: $1 });
-   }
- | DerivedColumnChain AnyDot PartialBacktickedIdentifierOrPartialCursor AnyDot DerivedColumnChain
-   {
-     suggestColumns({ identifierChain: $1 });
-   }
- | PartialBacktickedIdentifierOrPartialCursor AnyDot DerivedColumnChain
-   {
-     suggestColumns();
-   }
- ;
-
-ColumnIdentifier
- : RegularOrBacktickedIdentifier OptionalMapOrArrayKey
-   {
-     if ($2) {
-       $$ = { name: $1, keySet: true };
-     } else {
-       $$ = { name: $1 };
-     }
-   }
- ;
-
-ColumnIdentifier_EDIT
- : RegularOrBacktickedIdentifier HiveOrImpalaLeftSquareBracket AnyCursor HiveOrImpalaRightSquareBracketOrError
-   {
-     $$ = { name: $1, insideKey: true }
-   }
- | RegularOrBacktickedIdentifier HiveOrImpalaLeftSquareBracket ValueExpression_EDIT HiveOrImpalaRightSquareBracketOrError
-   {
-     $$ = { name: $1 }
-   }
- ;
-
-PartialBacktickedIdentifierOrPartialCursor
- : PartialBacktickedIdentifier
- | 'PARTIAL_CURSOR'
- ;
-
-OptionalMapOrArrayKey
- :
- | HiveOrImpalaLeftSquareBracket ValueExpression HiveOrImpalaRightSquareBracket
- | HiveOrImpalaLeftSquareBracket HiveOrImpalaRightSquareBracket
- ;
-
-HiveOrImpalaRightSquareBracketOrError
- : HiveOrImpalaRightSquareBracket
- | error
- ;
-
-// TODO: Support | DECIMAL(precision, scale)  -- (Note: Available in Hive 0.13.0 and later)
-PrimitiveType
- : 'TINYINT'
- | '<hive>TINYINT'
- | 'SMALLINT'
- | 'INT'
- | 'BIGINT'
- | 'BOOLEAN'
- | 'FLOAT'
- | 'DOUBLE'
- | '<impala>REAL'
- | 'STRING'
- | '<hive>STRING'
- | 'DECIMAL'
- | 'CHAR'
- | 'VARCHAR'
- | 'TIMESTAMP'
- | '<hive>BINARY'
- | '<hive>DATE'
- ;
-
-// ===================================== DESCRIBE statement =====================================
-
-DescribeStatement
- : HiveDescribeStatement
- | ImpalaDescribeStatement
- ;
-
-DescribeStatement_EDIT
- : HiveDescribeStatement_EDIT
- | ImpalaDescribeStatement_EDIT
- ;
-
-HiveDescribeStatement
- : '<hive>DESCRIBE' OptionalExtendedOrFormatted SchemaQualifiedTableIdentifier DerivedColumnChain
-   {
-     addTablePrimary($3);
-     addColumnLocation(@4, $4);
-   }
- | '<hive>DESCRIBE' OptionalExtendedOrFormatted SchemaQualifiedTableIdentifier
-   {
-     addTablePrimary($3);
-   }
- | '<hive>DESCRIBE' DatabaseOrSchema OptionalExtended DatabaseIdentifier
-   {
-     addDatabaseLocation(@4, $4);
-   }
- | '<hive>DESCRIBE' '<hive>FUNCTION' OptionalExtended RegularIdentifier
- ;
-
-HiveDescribeStatement_EDIT
- : '<hive>DESCRIBE' OptionalExtendedOrFormatted SchemaQualifiedTableIdentifier_EDIT
- | '<hive>DESCRIBE' OptionalExtendedOrFormatted SchemaQualifiedTableIdentifier DerivedColumnChain_EDIT
-   {
-     addTablePrimary($3);
-   }
- | '<hive>DESCRIBE' OptionalExtendedOrFormatted SchemaQualifiedTableIdentifier 'CURSOR'
-   {
-     addTablePrimary($3);
-     suggestColumns();
-   }
- | '<hive>DESCRIBE' OptionalExtendedOrFormatted 'CURSOR'
-   {
-     if (!$2) {
-       suggestKeywords(['DATABASE', 'EXTENDED', 'FORMATTED', 'FUNCTION', 'SCHEMA']);
-     }
-     suggestTables();
-     suggestDatabases({ appendDot: true });
-    }
- | '<hive>DESCRIBE' DatabaseOrSchema OptionalExtended DatabaseIdentifier_EDIT
-   {
-     if (!$3) {
-       suggestKeywords(['EXTENDED']);
-     }
-   }
- | '<hive>DESCRIBE' DatabaseOrSchema OptionalExtended 'CURSOR' DatabaseIdentifier
-    {
-      if (!$3) {
-        suggestKeywords(['EXTENDED']);
-      }
-    }
- | '<hive>DESCRIBE' '<hive>FUNCTION' OptionalExtended 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['EXTENDED']);
-     }
-   }
- | '<hive>DESCRIBE' '<hive>FUNCTION' OptionalExtended 'CURSOR' RegularIdentifier
-    {
-      if (!$3) {
-        suggestKeywords(['EXTENDED']);
-      }
-    }
- ;
-
-ImpalaDescribeStatement
- : '<impala>DESCRIBE' OptionalFormatted SchemaQualifiedTableIdentifier
-   {
-     addTablePrimary($3);
-   }
- ;
-
-ImpalaDescribeStatement_EDIT
- : '<impala>DESCRIBE' OptionalFormatted SchemaQualifiedTableIdentifier_EDIT
- | '<impala>DESCRIBE' OptionalFormatted 'CURSOR' SchemaQualifiedTableIdentifier
-   {
-     addTablePrimary($4);
-     if (!$2) {
-       suggestKeywords(['FORMATTED']);
-     }
-   }
- | '<impala>DESCRIBE' OptionalFormatted 'CURSOR'
-   {
-     if (!$2) {
-       suggestKeywords(['FORMATTED']);
-     }
-     suggestTables();
-     suggestDatabases({ appendDot: true });
-     $$ = { cursorOrPartialIdentifier: true };
-   }
- ;
-
-// ===================================== DROP Statement =====================================
-
-DropStatement
- : DropDatabaseStatement
- | DropTableStatement
- ;
-
-DropStatement_EDIT
- : 'DROP' 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['DATABASE', 'FUNCTION', 'INDEX', 'MACRO', 'ROLE', 'SCHEMA', 'TABLE', 'TEMPORARY FUNCTION', 'TEMPORARY MACRO', 'VIEW']);
-     } else if (isImpala()) {
-       suggestKeywords(['AGGREGATE FUNCTION', 'DATABASE', 'FUNCTION', 'INCREMENTAL STATS', 'ROLE', 'SCHEMA', 'STATS', 'TABLE', 'VIEW']);
-     } else {
-       suggestKeywords(['ROLE', 'SCHEMA', 'TABLE', 'VIEW']);
-     }
-   }
- | DropDatabaseStatement_EDIT
- | DropTableStatement_EDIT
- ;
-
-DropDatabaseStatement
- : 'DROP' DatabaseOrSchema OptionalIfExists RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
- ;
-
-DropDatabaseStatement_EDIT
- : 'DROP' DatabaseOrSchema OptionalIfExists
- | 'DROP' DatabaseOrSchema OptionalIfExists_EDIT
- | 'DROP' DatabaseOrSchema OptionalIfExists 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['IF EXISTS']);
-     }
-     suggestDatabases();
-   }
- | 'DROP' DatabaseOrSchema OptionalIfExists RegularOrBacktickedIdentifier 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['CASCADE', 'RESTRICT']);
-     }
-   }
- | 'DROP' DatabaseOrSchema OptionalIfExists_EDIT RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
- | 'DROP' DatabaseOrSchema OptionalIfExists 'CURSOR' RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
-   {
-     if (!$3) {
-       suggestKeywords(['IF EXISTS']);
-     }
-   }
- ;
-
-DropTableStatement
- : 'DROP' AnyTable OptionalIfExists TablePrimary
- ;
-
-DropTableStatement_EDIT
- : 'DROP' AnyTable OptionalIfExists_EDIT
- | 'DROP' AnyTable OptionalIfExists 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['IF EXISTS']);
-     }
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-   }
- | 'DROP' AnyTable OptionalIfExists TablePrimary_EDIT
-   {
-     if ($4.identifierChain && $4.identifierChain.length === 1) {
-       suggestTablesOrColumns($4.identifierChain[0].name);
-     } else if ($4.identifierChain && $4.identifierChain.length === 0) {
-       suggestTables();
-       suggestDatabases({ appendDot: true });
-     }
-   }
- | 'DROP' AnyTable OptionalIfExists_EDIT TablePrimary
- | 'DROP' AnyTable OptionalIfExists TablePrimary 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['PURGE']);
-     }
-   }
- ;
-
-// ===================================== LOAD statement =====================================
-
-LoadStatement
- : HiveOrImpalaLoad HiveOrImpalaData HiveOrImpalaInpath HdfsPath 'INTO' AnyTable RegularIdentifier
- ;
-
-LoadStatement_EDIT
- : HiveOrImpalaLoad HiveOrImpalaData HiveOrImpalaInpath HdfsPath_EDIT 'INTO' AnyTable RegularIdentifier
- | HiveOrImpalaLoad HiveOrImpalaData HiveOrImpalaInpath HdfsPath 'INTO' 'CURSOR'
-   {
-     suggestKeywords([ 'TABLE' ]);
-   }
- | HiveOrImpalaLoad HiveOrImpalaData HiveOrImpalaInpath HdfsPath 'CURSOR'
-   {
-     suggestKeywords([ 'INTO' ]);
-   }
- | HiveOrImpalaLoad HiveOrImpalaData HiveOrImpalaInpath HdfsPath_EDIT
- | HiveOrImpalaLoad HiveOrImpalaData 'CURSOR'
-   {
-     suggestKeywords([ 'INPATH' ]);
-   }
- | HiveOrImpalaLoad 'CURSOR'
-   {
-     suggestKeywords([ 'DATA' ]);
-   }
- ;
-
-
-// ===================================== SELECT statement =====================================
-
-QuerySpecification
- : 'SELECT' OptionalAllOrDistinct SelectList                  -> { selectList: $3 }
- | 'SELECT' OptionalAllOrDistinct SelectList TableExpression  -> { selectList: $3, tableExpression: $4 }
- ;
-
-QuerySpecification_EDIT
- : 'SELECT' OptionalAllOrDistinct SelectList_EDIT
-   {
-     if ($3.cursorAtStart) {
-       if ($2) {
-         suggestKeywords(['*']);
-       } else {
-         suggestKeywords(['*', 'ALL', 'DISTINCT']);
-       }
-     } else {
-       checkForSelectListKeywords($3);
-     }
-
-     if ($3.suggestAggregateFunctions && (!$2 || $2 === 'ALL')) {
-       suggestAggregateFunctions();
-       suggestAnalyticFunctions();
-     }
-   }
- | 'SELECT' OptionalAllOrDistinct 'CURSOR'
-   {
-     if ($2) {
-       suggestKeywords(['*']);
-       if ($2 === 'ALL') {
-         suggestAggregateFunctions();
-         suggestAnalyticFunctions();
-       }
-     } else {
-       suggestKeywords(['*', 'ALL', 'DISTINCT']);
-       suggestAggregateFunctions();
-       suggestAnalyticFunctions();
-     }
-     suggestFunctions();
-     suggestColumns();
-     suggestTables({ prependQuestionMark: true, prependFrom: true });
-     suggestDatabases({ prependQuestionMark: true, prependFrom: true, appendDot: true });
-   }
- | 'SELECT' OptionalAllOrDistinct SelectList TableExpression_EDIT
- | 'SELECT' OptionalAllOrDistinct SelectList_EDIT error TableExpression
- | 'SELECT' OptionalAllOrDistinct SelectList_EDIT TableExpression
-   {
-     if ($3.cursorAtStart) {
-       if ($2) {
-         suggestKeywords(['*']);
-       } else {
-         suggestKeywords(['*', 'ALL', 'DISTINCT']);
-       }
-     } else {
-       checkForKeywords($3);
-     }
-
-     if ($3.suggestAggregateFunctions && (!$2 || $2 === 'ALL')) {
-       suggestAggregateFunctions();
-       suggestAnalyticFunctions();
-     }
-   }
- | 'SELECT' OptionalAllOrDistinct 'CURSOR' TableExpression
-   {
-     if ($2) {
-       suggestKeywords(['*']);
-       if ($2 === 'ALL') {
-         suggestAggregateFunctions();
-         suggestAnalyticFunctions();
-       }
-     } else {
-       suggestKeywords(['*', 'ALL', 'DISTINCT']);
-       suggestAggregateFunctions();
-       suggestAnalyticFunctions();
-     }
-     suggestFunctions();
-     suggestColumns();
-     suggestTables({ prependQuestionMark: true, prependFrom: true });
-     suggestDatabases({ prependQuestionMark: true, prependFrom: true, appendDot: true });
-   }
- | 'SELECT' OptionalAllOrDistinct error TableExpression
- | 'SELECT' OptionalAllOrDistinct error TableExpression_EDIT
- | 'SELECT' OptionalAllOrDistinct SelectList error TableExpression        // Causes conflict but solves issue
- | 'SELECT' OptionalAllOrDistinct SelectList error TableExpression_EDIT   // with SELECT a, b, cos(| c AS d
- | 'SELECT' OptionalAllOrDistinct SelectList 'CURSOR' TableExpression
-   {
-     checkForSelectListKeywords($3);
-   }
- | 'SELECT' OptionalAllOrDistinct SelectList 'CURSOR' ',' TableExpression
-   {
-     checkForSelectListKeywords($3);
-   }
- | 'SELECT' OptionalAllOrDistinct SelectList 'CURSOR' ',' error TableExpression
-   {
-     checkForSelectListKeywords($3);
-   }
- | 'SELECT' OptionalAllOrDistinct SelectList 'CURSOR'
-   {
-     checkForSelectListKeywords($3);
-     suggestTables({ prependFrom: true });
-     suggestDatabases({ prependFrom: true, appendDot: true });
-   }
- ;
-
-OptionalAllOrDistinct
- :
- | '<hive>ALL'
- | 'ALL'
- | 'DISTINCT'
- ;
-
-TableExpression
- : FromClause OptionalSelectConditions
- ;
-
-TableExpression_EDIT
- : FromClause OptionalSelectConditions_EDIT
- | FromClause_EDIT OptionalSelectConditions
- | FromClause OptionalSelectConditions 'CURSOR' OptionalJoins
-   {
-     // A couple of things are going on here:
-     // - If there are no SelectConditions (WHERE, GROUP BY, etc.) we should suggest complete join options
-     // - If there's an OptionalJoin at the end, i.e. 'SELECT * FROM foo | JOIN ...' we should suggest
-     //   different join types
-     // - The FromClause could end with a valueExpression, in which case we should suggest keywords like '='
-     //   or 'AND' based on type
-     // The reason for the join mess is because for "SELECT * FROM foo | JOIN bar" the parts surrounding the
-     // cursor are complete and not in _EDIT rules.
-
-     if (!$2) {
-       var keywords = [];
-       if (typeof $1.hasJoinCondition !== 'undefined' && ! $1.hasJoinCondition) {
-         keywords.push('ON');
-         if (isImpala()) {
-           keywords.push('USING');
-         }
-       }
-       if (isHive()) {
-         if ($4 && $4.joinType.toUpperCase() === 'JOIN') {
-           keywords = keywords.concat(['CROSS', 'FULL', 'FULL OUTER', 'LEFT', 'LEFT OUTER', 'LEFT SEMI', 'RIGHT', 'RIGHT OUTER']);
-         } else {
-           keywords = keywords.concat(['CROSS JOIN', 'FULL JOIN', 'FULL OUTER JOIN', 'GROUP BY', 'JOIN', 'LATERAL VIEW', 'LEFT JOIN', 'LEFT OUTER JOIN', 'LEFT SEMI JOIN', 'LIMIT', 'ORDER BY', 'RIGHT JOIN', 'RIGHT OUTER JOIN', 'WHERE', 'WINDOW']);
-         }
-       } else if (isImpala()) {
-         if ($4 && $4.joinType.toUpperCase() === 'JOIN') {
-           keywords = keywords.concat(['FULL', 'FULL OUTER', 'INNER', 'LEFT ANTI', 'LEFT', 'LEFT OUTER', 'LEFT SEMI', 'RIGHT ANTI', 'RIGHT', 'RIGHT OUTER', 'RIGHT SEMI']);
-         } else {
-           keywords = keywords.concat(['FULL JOIN', 'FULL OUTER JOIN', 'GROUP BY', 'INNER JOIN', 'JOIN', 'LEFT ANTI JOIN', 'LEFT JOIN', 'LEFT OUTER JOIN', 'LEFT SEMI JOIN', 'LIMIT', 'ORDER BY', 'RIGHT ANTI JOIN', 'RIGHT JOIN', 'RIGHT OUTER JOIN', 'RIGHT SEMI JOIN', 'WHERE']);
-         }
-       } else {
-         if ($4 && $4.joinType.toUpperCase() === 'JOIN') {
-           keywords = keywords.concat(['FULL', 'FULL OUTER', 'INNER', 'LEFT', 'LEFT OUTER', 'RIGHT', 'RIGHT OUTER']);
-         } else {
-           keywords = keywords.concat(['FULL JOIN', 'FULL OUTER JOIN', 'GROUP BY', 'INNER JOIN', 'JOIN', 'LEFT JOIN', 'LEFT OUTER JOIN', 'LIMIT', 'ORDER BY', 'RIGHT JOIN', 'RIGHT OUTER JOIN', 'WHERE']);
-         }
-       }
-       if ($1.suggestKeywords) {
-         keywords = keywords.concat($1.suggestKeywords);
-         suggestKeywords(keywords);
-       } else if ($1.types) {
-        // Checks if valueExpression could happen when there's no OptionalJoinCondition
-         suggestValueExpressionKeywords($1, keywords);
-       } else {
-         suggestKeywords(keywords);
-       }
-     } else {
-       checkForKeywords($2);
-     }
-   }
- ;
-
-OptionalJoins
- :
- | Joins
- | Joins_INVALID
- ;
-
-FromClause
- : 'FROM' TableReferenceList  -> $2
- ;
-
-FromClause_EDIT
- : 'FROM' TableReferenceList_EDIT
- | 'FROM' 'CURSOR'
-   {
-       suggestTables();
-       suggestDatabases({ appendDot: true });
-   }
- ;
-
-OptionalSelectConditions
- : OptionalWhereClause OptionalGroupByClause OptionalWindowClause OptionalOrderByClause OptionalLimitClause
-   {
-     if ($1 && !$2 && !$3 && !$4 && !$5) {
-       if (isHive()) {
-         $$ = getValueExpressionKeywords($1, ['GROUP BY', 'WINDOW', 'ORDER BY', 'LIMIT']);
-       } else {
-         $$ = getValueExpressionKeywords($1, ['GROUP BY', 'ORDER BY', 'LIMIT']);
-       }
-       if ($1.columnReference) {
-         $$.columnReference = $1.columnReference
-       }
-     } else if ($2 && !$3 && !$4 && !$5) {
-       if (isHive()) {
-         $$ = { suggestKeywords: ['WINDOW', 'ORDER BY', 'LIMIT'] };
-       } else {
-         $$ = { suggestKeywords: ['ORDER BY', 'LIMIT'] };
-       }
-     } else if ($3 && !$4 && !$5) {
-       $$ = { suggestKeywords: ['ORDER BY', 'LIMIT'] };
-     } else if ($4 && !$5) {
-       if ($4.suggestKeywords) {
-         $$ = { suggestKeywords: $4.suggestKeywords.concat(['LIMIT']) };
-       } else {
-         $$ = { suggestKeywords: ['LIMIT'] };
-       }
-     }
-   }
- ;
-
-OptionalSelectConditions_EDIT
- : OptionalWhereClause_EDIT OptionalGroupByClause OptionalWindowClause OptionalOrderByClause OptionalLimitClause
- | OptionalWhereClause OptionalGroupByClause_EDIT OptionalWindowClause OptionalOrderByClause OptionalLimitClause
- | OptionalWhereClause OptionalGroupByClause OptionalWindowClause_EDIT OptionalOrderByClause OptionalLimitClause
- | OptionalWhereClause OptionalGroupByClause OptionalWindowClause OptionalOrderByClause_EDIT OptionalLimitClause
- | OptionalWhereClause OptionalGroupByClause OptionalWindowClauseOptionalOrderByClause OptionalLimitClause_EDIT
- ;
-
-OptionalWhereClause
- :
- | 'WHERE' SearchCondition  -> $2
- ;
-
-OptionalWhereClause_EDIT
- : 'WHERE' SearchCondition_EDIT
- | 'WHERE' 'CURSOR'
-   {
-     suggestFunctions();
-     suggestColumns();
-     suggestKeywords(['EXISTS', 'NOT EXISTS']);
-   }
- ;
-
-OptionalGroupByClause
- :
- | AnyGroup 'BY' GroupByColumnList
- ;
-
-OptionalGroupByClause_EDIT
- : AnyGroup 'BY' GroupByColumnList_EDIT
- | AnyGroup 'BY' 'CURSOR'
-   {
-     suggestColumns();
-     suggestTables({ prependQuestionMark: true, prependFrom: true });
-     suggestDatabases({ prependQuestionMark: true, prependFrom: true, appendDot: true });
-   }
- | AnyGroup 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- ;
-
-GroupByColumnList
- : DerivedColumnOrUnsignedInteger
- | GroupByColumnList ',' DerivedColumnOrUnsignedInteger
- ;
-
-GroupByColumnList_EDIT
- : DerivedColumnOrUnsignedInteger_EDIT
- | 'CURSOR' DerivedColumnOrUnsignedInteger
-   {
-     suggestColumns();
-   }
- | GroupByColumnList ',' GroupByColumnListPartTwo_EDIT
- | GroupByColumnList ',' GroupByColumnListPartTwo_EDIT ','
- | GroupByColumnList ',' GroupByColumnListPartTwo_EDIT ',' GroupByColumnList
- ;
-
-GroupByColumnListPartTwo_EDIT
- : DerivedColumnOrUnsignedInteger_EDIT
- | AnyCursor
-   {
-     suggestColumns();
-   }
- ;
-
-OptionalOrderByClause
- :
- | OrderByClause
- ;
-
-OptionalOrderByClause_EDIT
- : OrderByClause_EDIT
- ;
-
-OrderByClause
- : 'ORDER' 'BY' OrderByColumnList  -> $3
- ;
-
-OrderByClause_EDIT
- :'ORDER' 'BY' OrderByColumnList_EDIT
- | 'ORDER' 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- ;
-
-OrderByColumnList
- : OrderByIdentifier
- | OrderByColumnList ',' OrderByIdentifier  -> $3
- ;
-
-OrderByColumnList_EDIT
- : OrderByIdentifier_EDIT
- | 'CURSOR' OrderByIdentifier
-   {
-     suggestColumns();
-     suggestAnalyticFunctions();
-   }
- | OrderByColumnList ',' OrderByIdentifier_EDIT
- | OrderByColumnList ',' OrderByIdentifier_EDIT ','
- | OrderByColumnList ',' OrderByIdentifier_EDIT ',' OrderByColumnList
- ;
-
-OrderByIdentifier
- : DerivedColumnOrUnsignedInteger OptionalAscOrDesc OptionalImpalaNullsFirstOrLast  -> mergeSuggestKeywords($2, $3)
- ;
-
-OrderByIdentifier_EDIT
- : DerivedColumnOrUnsignedInteger_EDIT OptionalAscOrDesc OptionalImpalaNullsFirstOrLast
- | DerivedColumnOrUnsignedInteger OptionalAscOrDesc OptionalImpalaNullsFirstOrLast_EDIT
- | AnyCursor OptionalAscOrDesc OptionalImpalaNullsFirstOrLast
-   {
-     suggestColumns();
-     suggestAnalyticFunctions();
-   }
- ;
-
-DerivedColumnOrUnsignedInteger
- : DerivedColumn_TWO
- | 'UNSIGNED_INTEGER'
- ;
-
-DerivedColumnOrUnsignedInteger_EDIT
- : DerivedColumn_EDIT_TWO
- ;
-
-OptionalAscOrDesc
- :
-  {
-    $$ = { suggestKeywords: ['ASC', 'DESC'] };
-  }
- | 'ASC'
- | '<hive>ASC'
- | 'DESC'
- | '<hive>DESC'
- ;
-
-OptionalImpalaNullsFirstOrLast
- :
-  {
-    if (isImpala()) {
-      $$ = { suggestKeywords: ['NULLS FIRST', 'NULLS LAST'] };
-    } else {
-      $$ = {};
-    }
-  }
- | '<impala>NULLS' '<impala>FIRST'
- | '<impala>NULLS' '<impala>LAST'
- ;
-
-OptionalImpalaNullsFirstOrLast_EDIT
- : '<impala>NULLS' 'CURSOR'
-   {
-     suggestKeywords(['FIRST', 'LAST']);
-   }
- ;
-
-AnyLimit
- : 'LIMIT'
- | '<hive>LIMIT'
- ;
-
-OptionalLimitClause
- :
- | AnyLimit 'UNSIGNED_INTEGER'
- ;
-
-OptionalLimitClause_EDIT
- : AnyLimit 'CURSOR'
-   {
-     suggestNumbers([1, 5, 10]);
-   }
- ;
-
-SearchCondition
- : ValueExpression
- ;
-
-SearchCondition_EDIT
- : ValueExpression_EDIT
- ;
-
-ValueExpression
- : NonParenthesizedValueExpressionPrimary
- ;
-
-ValueExpression_EDIT
- : NonParenthesizedValueExpressionPrimary_EDIT
- ;
-
-ValueExpression_EDIT
- : ValueExpression 'NOT' 'CURSOR'
-   {
-     suggestKeywords(['BETWEEN', 'EXISTS', 'IN', 'LIKE']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- ;
-
-ValueExpressionList
- : ValueExpression
-   {
-     $1.position = 1;
-   }
- | ValueExpressionList ',' ValueExpression
-   {
-     $3.position = $1.position + 1;
-     $$ = $3;
-   }
- ;
-
-ValueExpressionList_EDIT
- : ValueExpression_EDIT
-   {
-     $1.position = 1;
-   }
- | ValueExpressionList ',' ValueExpression_EDIT
-   {
-     $1.position += 1;
-   }
- | ValueExpression_EDIT ',' ValueExpressionList
-   {
-     $1.position = 1;
-   }
- | ValueExpressionList ',' ValueExpression_EDIT ',' ValueExpressionList
-   {
-     // $3.position = $1.position + 1;
-     // $$ = $3
-     $1.position += 1;
-   }
- | ValueExpressionList ',' AnyCursor
-   {
-     valueExpressionSuggest();
-     $1.position += 1;
-   }
- | ValueExpressionList ',' AnyCursor ',' ValueExpressionList
-   {
-     valueExpressionSuggest();
-     $1.position += 1;
-   }
- | ValueExpressionList 'CURSOR' ',' ValueExpressionList
-   {
-     suggestValueExpressionKeywords($1);
-   }
- | AnyCursor ',' ValueExpressionList
-   {
-     valueExpressionSuggest();
-     $$ = { cursorAtStart : true, position: 1 };
-   }
- | AnyCursor ','
-   {
-     valueExpressionSuggest();
-     $$ = { cursorAtStart : true, position: 1 };
-   }
- | ',' AnyCursor
-   {
-     valueExpressionSuggest();
-     $$ = { position: 2 };
-   }
- | ',' AnyCursor ',' ValueExpressionList
-   {
-     valueExpressionSuggest();
-     $$ = { position: 2 };
-   }
- ;
-
-InValueList
- : NonParenthesizedValueExpressionPrimary
- | InValueList ',' NonParenthesizedValueExpressionPrimary
- ;
-
-InValueList_EDIT
- : NonParenthesizedValueExpressionPrimary_EDIT
- | InValueList ',' AnyCursor
- | InValueList ',' NonParenthesizedValueExpressionPrimary_EDIT
- | InValueList ',' NonParenthesizedValueExpressionPrimary_EDIT ',' InValueList
- | NonParenthesizedValueExpressionPrimary_EDIT ',' InValueList
- ;
-
-NonParenthesizedValueExpressionPrimary
- : UnsignedValueSpecification
- | ColumnReference             -> { types: ['COLREF'], columnReference: $1 }
- | UserDefinedFunction
- | 'NULL'                      -> { types: [ 'NULL' ] }
- ;
-
-NonParenthesizedValueExpressionPrimary_EDIT
- : ColumnReference_EDIT
-   {
-     if ($1.suggestKeywords) {
-       $$ = { types: ['COLREF'], columnReference: $1, suggestKeywords: $1.suggestKeywords };
-     } else {
-       $$ = { types: ['COLREF'], columnReference: $1 };
-     }
-   }
- | UserDefinedFunction_EDIT
- ;
-
-UnsignedValueSpecification
- : UnsignedLiteral
- ;
-
-UnsignedLiteral
- : UnsignedNumericLiteral  -> { types: [ 'NUMBER' ] }
- | GeneralLiteral
- ;
-
-UnsignedNumericLiteral
- : ExactNumericLiteral
- | ApproximateNumericLiteral
- ;
-
-ExactNumericLiteral
- : 'UNSIGNED_INTEGER'
- | 'UNSIGNED_INTEGER' '.'
- | 'UNSIGNED_INTEGER' '.' 'UNSIGNED_INTEGER'
- | '.' 'UNSIGNED_INTEGER'
- ;
-
-ApproximateNumericLiteral
- : UNSIGNED_INTEGER_E 'UNSIGNED_INTEGER'
- | '.' UNSIGNED_INTEGER_E 'UNSIGNED_INTEGER'
- | 'UNSIGNED_INTEGER' '.' UNSIGNED_INTEGER_E 'UNSIGNED_INTEGER'
- ;
-
-GeneralLiteral
- : SingleQuotedValue  -> { types: [ 'STRING' ] }
- | DoubleQuotedValue  -> { types: [ 'STRING' ] }
- | TruthValue         -> { types: [ 'BOOLEAN' ] }
- ;
-
-TruthValue
- : 'TRUE'
- | 'FALSE'
- ;
-
-OptionalNot
- :
- | 'NOT'
- ;
-
-SelectSubList
- : ValueExpression OptionalCorrelationName
-   {
-     if ($2) {
-       $$ = { valueExpression: $1, alias: $2 };
-     } else {
-       $$ = { valueExpression: $1 }
-     }
-   }
- | '*'
-   {
-     $$ = { asterisk: true }
-   }
- ;
-
-SelectSubList_EDIT
- : ValueExpression_EDIT OptionalCorrelationName
- | ValueExpression OptionalCorrelationName_EDIT  -> $2
- ;
-
-SelectList
- : SelectSubList                 -> [ $1 ]
- | SelectList ',' SelectSubList
-   {
-     $1.push($3);
-   }
- ;
-
-SelectList_EDIT
- : SelectSubList_EDIT
- | 'CURSOR' SelectList
-   {
-     suggestFunctions();
-     suggestColumns();
-     suggestFunctions();
-     $$ = { cursorAtStart : true, suggestAggregateFunctions: true };
-   }
- | SelectList 'CURSOR' SelectList
-   {
-     if ($1.suggestKeywords) {
-       suggestKeywords($1.suggestKeywords);
-     }
-   }
- | SelectList ',' AnyCursor SelectList
-   {
-     suggestFunctions();
-     suggestColumns();
-     $$ = { suggestAggregateFunctions: true, suggestKeywords: ['*'] };
-   }
- | SelectList ',' SelectListPartTwo_EDIT                 -> $3
- | SelectList ',' SelectListPartTwo_EDIT ','             -> $3
- | SelectList ',' SelectListPartTwo_EDIT ',' SelectList  -> $3
- ;
-
-SelectListPartTwo_EDIT
- : SelectSubList_EDIT
- | AnyCursor
-   {
-     suggestFunctions();
-     suggestColumns();
-     // TODO: Only if there's no FROM
-     suggestTables({ prependQuestionMark: true, prependFrom: true });
-     suggestDatabases({ prependQuestionMark: true, prependFrom: true, appendDot: true });
-     $$ = { suggestKeywords: ['*'], suggestAggregateFunctions: true };
-   }
- ;
-
-DerivedColumn_TWO
- : ColumnIdentifier
-   {
-     addColumnLocation(@1, [$1]);
-   }
- | ColumnIdentifier AnyDot '*'
-   {
-     addColumnLocation(@1, [$1]);
-   }
- | ColumnIdentifier AnyDot DerivedColumnChain
-   {
-     addColumnLocation(@2, [$1].concat($3));
-   }
- ;
-
-DerivedColumn_EDIT_TWO
- : ColumnIdentifier AnyDot PartialBacktickedOrPartialCursor
-   {
-     // TODO: Check if valid: SELECT testMap["key"].* FROM foo
-     if (typeof $1.key === 'undefined') {
-       parser.yy.result.suggestStar = true;
-     }
-     suggestColumns({
-       identifierChain: [ $1 ]
-     });
-   }
- | ColumnIdentifier AnyDot DerivedColumnChain '<impala>.' 'PARTIAL_CURSOR'
-   {
-      $3.unshift($1);
-      suggestColumns({
-        identifierChain: $3
-      });
-    }
- | ColumnIdentifier AnyDot DerivedColumnChain '<hive>.' 'PARTIAL_CURSOR'
-   {
-      $3.unshift($1);
-      suggestColumns({
-        identifierChain: $3
-      });
-    }
- ;
-
-TableReferenceList
- : TableReference
- | TableReferenceList ',' TableReference  -> $3
- ;
-
-TableReferenceList_EDIT
- : TableReference_EDIT
- | TableReferenceList_EDIT ',' TableReference
- | TableReferenceList ',' TableReference_EDIT
- | TableReferenceList ',' 'CURSOR'
-   {
-       suggestTables();
-       suggestDatabases({ appendDot: true });
-   }
- ;
-
-TableReference
- : TablePrimaryOrJoinedTable
- ;
-
-TableReference_EDIT
- : TablePrimaryOrJoinedTable_EDIT
- ;
-
-TablePrimaryOrJoinedTable
- : TablePrimary
- | JoinedTable
- ;
-
-TablePrimaryOrJoinedTable_EDIT
- : TablePrimary_EDIT
- | JoinedTable_EDIT
- ;
-
-JoinedTable
- : TablePrimary Joins  -> $2
- ;
-
-JoinedTable_EDIT
- : TablePrimary Joins_EDIT
- | TablePrimary_EDIT Joins
- ;
-
-Joins
- : JoinTypes OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
-   {
-     $4.joinType = $1;
-     $$ = $4;
-   }
- | Joins JoinTypes OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
-   {
-     $5.joinType = $1;
-     $$ = $5;
-   }
- ;
-
-Joins_INVALID
- : JoinTypes OptionalImpalaBroadcastOrShuffle                                           -> { joinType: $1 }
- | JoinTypes OptionalImpalaBroadcastOrShuffle Joins                                     -> { joinType: $1 }
- ;
-OptionalImpalaBroadcastOrShuffle
- :
- | '<impala>BROADCAST'
- | '<impala>SHUFFLE'
- ;
-
-Join_EDIT
- : JoinTypes_EDIT OptionalImpalaBroadcastOrShuffle TablePrimary OptionalJoinCondition
- | JoinTypes_EDIT OptionalImpalaBroadcastOrShuffle
- | JoinTypes OptionalImpalaBroadcastOrShuffle TablePrimary_EDIT OptionalJoinCondition
- | JoinTypes OptionalImpalaBroadcastOrShuffle TablePrimary JoinCondition_EDIT
- | JoinTypes OptionalImpalaBroadcastOrShuffle 'CURSOR' OptionalJoinCondition
-   {
-     if (!$2 && isImpala()) {
-       suggestKeywords(['[BROADCAST]', '[SHUFFLE]']);
-     }
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-   }
- ;
-
-Joins_EDIT
- : Join_EDIT
- | Join_EDIT Joins
- | Joins Join_EDIT
- | Joins Join_EDIT Joins
- ;
-
-JoinTypes
- : 'JOIN'
- | '<hive>CROSS' 'JOIN'
- | 'INNER' 'JOIN'
- | 'FULL' 'JOIN'
- | 'FULL' 'OUTER' 'JOIN'
- | 'LEFT' 'JOIN'
- | 'LEFT' '<impala>ANTI' 'JOIN'
- | 'LEFT' 'OUTER' 'JOIN'
- | 'LEFT' 'SEMI' 'JOIN'
- | 'RIGHT' 'JOIN'
- | 'RIGHT' '<impala>ANTI' 'JOIN'
- | 'RIGHT' 'OUTER' 'JOIN'
- | 'RIGHT' 'SEMI' 'JOIN'
- ;
-
-JoinTypes_EDIT
- : '<hive>CROSS' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'INNER' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'FULL' 'CURSOR' error
-   {
-     suggestKeywords(['JOIN', 'OUTER JOIN']);
-   }
- | 'FULL' 'OUTER' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'FULL' 'CURSOR' 'JOIN'
-   {
-     suggestKeywords(['OUTER']);
-   }
- | 'LEFT' 'CURSOR' error
-   {
-     if (isHive()) {
-       suggestKeywords(['JOIN', 'OUTER JOIN', 'SEMI JOIN']);
-     } else if (isImpala()) {
-       suggestKeywords(['ANTI JOIN', 'JOIN', 'OUTER JOIN', 'SEMI JOIN']);
-     } else {
-       suggestKeywords(['JOIN', 'OUTER JOIN']);
-     }
-   }
- | 'LEFT' 'SEMI' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'LEFT' 'OUTER' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'LEFT' '<impala>ANTI' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'LEFT' 'CURSOR' 'JOIN'
-   {
-     if (isImpala()) {
-       suggestKeywords(['ANTI', 'OUTER', 'SEMI']);
-     } else if (isHive()) {
-       suggestKeywords(['OUTER', 'SEMI']);
-     } else {
-       suggestKeywords(['OUTER']);
-     }
-   }
- | 'RIGHT' 'CURSOR' error
-   {
-     if (isImpala()) {
-       suggestKeywords(['ANTI JOIN', 'JOIN', 'OUTER JOIN', 'SEMI JOIN']);
-     } else {
-       suggestKeywords(['JOIN', 'OUTER JOIN']);
-     }
-   }
- | 'RIGHT' '<impala>ANTI' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'RIGHT' 'OUTER' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'RIGHT' 'SEMI' 'CURSOR'
-   {
-     suggestKeywords(['JOIN']);
-   }
- | 'RIGHT' 'CURSOR' 'JOIN'
-   {
-     if (isImpala()) {
-       suggestKeywords(['ANTI', 'SEMI', 'OUTER']);
-     } else {
-       suggestKeywords(['OUTER']);
-     }
-   }
- ;
-
-OptionalJoinCondition
- :                       -> { suggestKeywords: isImpala() ? ['ON', 'USING'] : ['ON'] }
- | 'ON' ValueExpression  -> $2
- | '<impala>USING' '(' UsingColList ')'
- ;
-
-UsingColList
- : RegularOrBacktickedIdentifier
- | UsingColList ',' RegularOrBacktickedIdentifier
- ;
-
-JoinCondition_EDIT
- : 'ON' ValueExpression_EDIT
- | 'ON' 'CURSOR'
-   {
-     valueExpressionSuggest();
-   }
- ;
-
-TablePrimary
- : TableOrQueryName OptionalCorrelationName OptionalLateralViews
-   {
-     if ($1.identifierChain) {
-       if ($2) {
-         $1.alias = $2
-       }
-       if ($3 && $3.length > 0) {
-         $1.lateralViews = $3;
-       }
-       addTablePrimary($1);
-     }
-   }
- | DerivedTable OptionalCorrelationName
-   {
-      if ($2) {
-       $1.alias = $2;
-       addTablePrimary({ subQueryAlias: $2 });
-     }
-   }
- ;
-
-TablePrimary_EDIT
- : TableOrQueryName_EDIT OptionalCorrelationName OptionalLateralViews
- | TableOrQueryName OptionalCorrelationName OptionalLateralViews_EDIT
-   {
-     if ($2) {
-       $1.alias = $2;
-     }
-     addTablePrimary($1);
-   }
- | DerivedTable_EDIT OptionalCorrelationName
-   {
-     if ($2) {
-       // TODO: Potentially add columns for SELECT bla.| FROM (SELECT * FROM foo) AS bla;
-       addTablePrimary({ subQueryAlias: $2 });
-     }
-   }
- | DerivedTable OptionalCorrelationName_EDIT // TODO: OptionalLateralViews?
- ;
-
-TableOrQueryName
- : SchemaQualifiedTableIdentifier
- ;
-
-TableOrQueryName_EDIT
- : SchemaQualifiedTableIdentifier_EDIT
- ;
-
-DerivedTable
- : TableSubQuery
- ;
-
-DerivedTable_EDIT
- : TableSubQuery_EDIT
- ;
-
-PushQueryState
- :
-   {
-     if (typeof parser.yy.locationsStack === 'undefined') {
-       parser.yy.locationsStack = [];
-     }
-     if (typeof parser.yy.primariesStack === 'undefined') {
-       parser.yy.primariesStack = [];
-     }
-     if (typeof parser.yy.subQueriesStack === 'undefined') {
-       parser.yy.subQueriesStack = [];
-     }
-
-     if (typeof parser.yy.resultStack === 'undefined') {
-       parser.yy.resultStack = [];
-     }
-     parser.yy.primariesStack.push(parser.yy.latestTablePrimaries);
-     parser.yy.resultStack.push(parser.yy.result);
-     parser.yy.locationsStack.push(parser.yy.locations);
-     parser.yy.subQueriesStack.push(parser.yy.subQueries);
-
-     parser.yy.result = {};
-     parser.yy.locations = [];
-     if (parser.yy.correlatedSubQuery) {
-       parser.yy.latestTablePrimaries = parser.yy.latestTablePrimaries.concat();
-       parser.yy.subQueries = parser.yy.subQueries.concat();
-     } else {
-       parser.yy.latestTablePrimaries = [];
-       parser.yy.subQueries = [];
-     }
-   }
- ;
-
-PopQueryState
- :
-   {
-     popQueryState();
-   }
- ;
-
-TableSubQuery
- : '(' TableSubQueryInner ')'  -> $2
- | '(' DerivedTable OptionalCorrelationName ')'
-   {
-     if ($3) {
-       $2.alias = $3;
-       addTablePrimary({ subQueryAlias: $3 });
-     }
-     $$ = $2;
-   }
- ;
-
-TableSubQuery_EDIT
- : '(' TableSubQueryInner_EDIT RightParenthesisOrError
- | '(' AnyCursor RightParenthesisOrError
-   {
-     suggestKeywords(['SELECT']);
-   }
- ;
-
-TableSubQueryInner
- : PushQueryState SubQuery
-   {
-     var subQuery = getSubQuery($2);
-     subQuery.columns.forEach(function (column) {
-       expandIdentifierChain(column);
-       delete column.linked;
-     });
-     popQueryState(subQuery);
-     $$ = subQuery;
-   }
- ;
-
-TableSubQueryInner_EDIT
- : PushQueryState SubQuery_EDIT PopQueryState
- ;
-
-SubQuery
- : QueryExpression
- ;
-
-SubQuery_EDIT
- : QueryExpression_EDIT
- ;
-
-QueryExpression
- : QueryExpressionBody
- ;
-
-QueryExpression_EDIT
- : QueryExpressionBody_EDIT
- ;
-
-QueryExpressionBody
- : NonJoinQueryExpression
- ;
-
-QueryExpressionBody_EDIT
- : NonJoinQueryExpression_EDIT
- ;
-
-NonJoinQueryExpression
- : NonJoinQueryTerm
- ;
-
-NonJoinQueryExpression_EDIT
- : NonJoinQueryTerm_EDIT
- ;
-
-NonJoinQueryTerm
- : NonJoinQueryPrimary
- ;
-
-NonJoinQueryTerm_EDIT
- : NonJoinQueryPrimary_EDIT
- ;
-
-NonJoinQueryPrimary
- : SimpleTable
- ;
-
-NonJoinQueryPrimary_EDIT
- : SimpleTable_EDIT
- ;
-
-SimpleTable
- : QuerySpecification
- ;
-
-SimpleTable_EDIT
- : QuerySpecification_EDIT
- ;
-
-OptionalCorrelationName
- :
- | RegularOrBacktickedIdentifier
- | AnyAs RegularOrBacktickedIdentifier  -> $2
- ;
-
-OptionalCorrelationName_EDIT
- : PartialBacktickedIdentifier
- | AnyAs PartialBacktickedIdentifier
- | AnyAs 'CURSOR'
- ;
-
-OptionalLateralViews
- :
- | OptionalLateralViews LateralView
-   {
-     if ($1) {
-       $$ = $1.concat($2);
-     } else {
-       $$ = $2;
-     }
-   }
- ;
-
-OptionalLateralViews_EDIT
- : OptionalLateralViews LateralView_EDIT OptionalLateralViews
- ;
-
-UserDefinedFunction
- : ArbitraryFunction
- | AggregateFunction OptionalOverClause
-   {
-     if (!$2) {
-       $1.suggestKeywords = ['OVER'];
-     }
-   }
- | AnalyticFunction OverClause
- | CastFunction
- | ExtractFunction
- ;
-
-UserDefinedFunction_EDIT
- : ArbitraryFunction_EDIT
- | AggregateFunction_EDIT
- | AggregateFunction OptionalOverClause_EDIT
- | AnalyticFunction_EDIT
- | AnalyticFunction_EDIT OverClause
- | AnalyticFunction 'CURSOR'
-   {
-     suggestKeywords(['OVER']);
-   }
- | AnalyticFunction OverClause_EDIT
- | CastFunction_EDIT
- | ExtractFunction_EDIT
- ;
-
-ArbitraryFunction
- : 'REGULAR_IDENTIFIER' '(' ')'
-   {
-     addFunctionLocation(@1, $1);
-     $$ = { types: findReturnTypes($1) }
-   }
- | 'REGULAR_IDENTIFIER' '(' ValueExpressionList ')'
-   {
-     addFunctionLocation(@1, $1);
-     $$ = { function: $1, expression: $3, types: findReturnTypes($1) }
-   }
- ;
-
-ArbitraryFunction_EDIT
- : 'REGULAR_IDENTIFIER' '(' AnyCursor RightParenthesisOrError
-   {
-     addFunctionLocation(@1, $1);
-     valueExpressionSuggest();
-     applyArgumentTypesToSuggestions($1, 1);
-     $$ = { types: findReturnTypes($1) };
-   }
- | 'REGULAR_IDENTIFIER' '(' ValueExpressionList 'CURSOR' RightParenthesisOrError
-   {
-     addFunctionLocation(@1, $1);
-     suggestValueExpressionKeywords($3);
-     $$ = { types: findReturnTypes($1) };
-   }
- | 'REGULAR_IDENTIFIER' '(' ValueExpressionList_EDIT RightParenthesisOrError
-   {
-     addFunctionLocation(@1, $1);
-     applyArgumentTypesToSuggestions($1, $3.position);
-     $$ = { types: findReturnTypes($1) };
-   }
- ;
-
-AggregateFunction
- : CountFunction
- | SumFunction
- | OtherAggregateFunction
- ;
-
-AggregateFunction_EDIT
- : CountFunction_EDIT
- | SumFunction_EDIT
- | OtherAggregateFunction_EDIT
- ;
-
-AnalyticFunction
- : 'ANALYTIC' '(' ')'                      -> { types: findReturnTypes($1) }
- | 'ANALYTIC' '(' ValueExpressionList ')'  -> { function: $1, expression: $2, types: findReturnTypes($1) }
- ;
-
-AnalyticFunction_EDIT
- : 'ANALYTIC' '(' AnyCursor RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     applyArgumentTypesToSuggestions($1, 1);
-     $$ = { types: findReturnTypes($1) };
-   }
- | 'ANALYTIC' '(' ValueExpressionList 'CURSOR' RightParenthesisOrError
-   {
-     suggestValueExpressionKeywords($3);
-     $$ = { types: findReturnTypes($1) };
-   }
- | 'ANALYTIC' '(' ValueExpressionList_EDIT RightParenthesisOrError
-   {
-     applyArgumentTypesToSuggestions($1, $3.position);
-     $$ = { types: findReturnTypes($1) };
-   }
- ;
-
-OptionalOverClause
- :
- | OverClause
- ;
-
-OptionalOverClause_EDIT
- : OverClause_EDIT
- ;
-
-OverClause
- : 'OVER' RegularOrBacktickedIdentifier
- | 'OVER' WindowExpression
- ;
-
-OverClause_EDIT
- : 'OVER' WindowExpression_EDIT
- ;
-
-WindowExpression
- : '(' OptionalPartitionBy OptionalOrderByAndWindow ')'
- ;
-
-WindowExpression_EDIT
- : '(' OptionalPartitionBy_EDIT  RightParenthesisOrError
- | '(' AnyCursor RightParenthesisOrError
-   {
-     suggestKeywords(['PARTITION BY', 'ORDER BY']);
-   }
- | '(' OptionalPartitionBy OptionalOrderByAndWindow_EDIT RightParenthesisOrError
- ;
-
-OptionalPartitionBy
- :
- | 'PARTITION' 'BY' ValueExpressionList
- ;
-
-OptionalPartitionBy_EDIT
- : 'PARTITION' 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- | 'PARTITION' 'BY' 'CURSOR'
-   {
-     valueExpressionSuggest();
-   }
- | 'PARTITION' 'BY' ValueExpressionList_EDIT
- ;
-
-OptionalOrderByAndWindow
- :
- | OrderByClause OptionalWindowSpec
- ;
-
-OptionalOrderByAndWindow_EDIT
-  : OrderByClause_EDIT
-    {
-      // Only allowed in last order by
-      delete parser.yy.result.suggestAnalyticFunctions;
-    }
-  | OrderByClause OptionalWindowSpec 'CURSOR'
-    {
-      if (!$2) {
-        if ($1.suggestKeywords) {
-          suggestKeywords($1.suggestKeywords.concat(['RANGE BETWEEN', 'ROWS BETWEEN']));
-        } else {
-          suggestKeywords(['RANGE BETWEEN', 'ROWS BETWEEN']);
-        }
-      }
-    }
-  | OrderByClause OptionalWindowSpec_EDIT
-  ;
-
-OptionalWindowSpec
- :
- | RowsOrRange 'BETWEEN' PopBetweenState OptionalCurrentOrPreceding OptionalAndFollowing
- ;
-
-OptionalWindowSpec_EDIT
- : RowsOrRange 'CURSOR'
-   {
-     suggestKeywords(['BETWEEN']);
-   }
- | RowsOrRange 'BETWEEN' PopBetweenState OptionalCurrentOrPreceding OptionalAndFollowing 'CURSOR'
-   {
-     if (!$4 && !$5) {
-       suggestKeywords(['CURRENT ROW', 'UNBOUNDED PRECEDING']);
-     } else if (!$5) {
-       suggestKeywords(['AND']);
-     }
-   }
- | RowsOrRange 'BETWEEN' PopBetweenState OptionalCurrentOrPreceding_EDIT OptionalAndFollowing
- | RowsOrRange 'BETWEEN' PopBetweenState OptionalCurrentOrPreceding OptionalAndFollowing_EDIT
- ;
-
-PopBetweenState
- :
-  {
-    lexer.popState();
-  }
- ;
-
-RowsOrRange
- : 'ROWS'
- | 'RANGE'
- ;
-
-OptionalCurrentOrPreceding
- :
- | IntegerOrUnbounded 'PRECEDING'
- | AnyCurrent 'ROW'
- ;
-
-OptionalCurrentOrPreceding_EDIT
- : IntegerOrUnbounded 'CURSOR'
-   {
-     suggestKeywords(['PRECEDING']);
-   }
- | AnyCurrent 'CURSOR'
-   {
-     suggestKeywords(['ROW']);
-   }
- ;
-
-AnyCurrent
- : 'CURRENT'
- | '<hive>CURRENT'
- | '<impala>CURRENT'
- ;
-
-OptionalAndFollowing
- :
- | 'AND' AnyCurrent 'ROW'
- | 'AND' IntegerOrUnbounded 'FOLLOWING'
- ;
-
-OptionalAndFollowing_EDIT
- : 'AND' 'CURSOR'
-   {
-     suggestKeywords(['CURRENT ROW', 'UNBOUNDED FOLLOWING']);
-   }
- | 'AND' AnyCurrent 'CURSOR'
-   {
-     suggestKeywords(['ROW']);
-   }
- | 'AND' IntegerOrUnbounded 'CURSOR'
-   {
-     suggestKeywords(['FOLLOWING']);
-   }
- ;
-
-IntegerOrUnbounded
- : 'UNSIGNED_INTEGER'
- | 'UNBOUNDED'
- ;
-
-// Group by, window, order by, limit
-OptionalWindowClause
- :
- | '<hive>WINDOW' RegularOrBacktickedIdentifier '<hive>AS' WindowExpression
- ;
-
-OptionalWindowClause_EDIT
- : '<hive>WINDOW' RegularOrBacktickedIdentifier 'CURSOR'
-   {
-     suggestKeywords(['AS']);
-   }
- | '<hive>WINDOW' RegularOrBacktickedIdentifier '<hive>AS' WindowExpression_EDIT
- ;
-
-CastFunction
- : 'CAST' '(' ValueExpression AnyAs PrimitiveType ')'  -> { types: [ $5.toUpperCase() ] }
- | 'CAST' '(' ')'                                      -> { types: [ 'T' ] }
- ;
-
-CastFunction_EDIT
- : 'CAST' '(' AnyCursor AnyAs PrimitiveType RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ $5.toUpperCase() ] };
-   }
- | 'CAST' '(' AnyCursor AnyAs RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ 'T' ] };
-   }
- | 'CAST' '(' AnyCursor RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ 'T' ] };
-   }
- | 'CAST' '(' ValueExpression_EDIT AnyAs PrimitiveType RightParenthesisOrError  -> { types: [ $5.toUpperCase() ] }
- | 'CAST' '(' ValueExpression_EDIT AnyAs RightParenthesisOrError                -> { types: [ 'T' ] }
- | 'CAST' '(' ValueExpression_EDIT RightParenthesisOrError                      -> { types: [ 'T' ] }
- | 'CAST' '(' ValueExpression 'CURSOR' PrimitiveType RightParenthesisOrError
-   {
-     suggestValueExpressionKeywords($3, ['AS']);
-     $$ =  { types: [ $5.toUpperCase() ] };
-   }
- | 'CAST' '(' ValueExpression 'CURSOR' RightParenthesisOrError
-   {
-     suggestValueExpressionKeywords($3, ['AS']);
-     $$ = { types: [ 'T' ] };
-   }
- | 'CAST' '(' ValueExpression AnyAs 'CURSOR' RightParenthesisOrError
-   {
-     suggestKeywords(getTypeKeywords());
-     $$ = { types: [ 'T' ] };
-   }
- | 'CAST' '(' AnyAs 'CURSOR' RightParenthesisOrError
-   {
-     suggestKeywords(getTypeKeywords());
-     $$ = { types: [ 'T' ] };
-   }
- ;
-
-CountFunction
- : 'COUNT' '(' '*' ')'                                        -> { types: findReturnTypes($1) }
- | 'COUNT' '(' ')'                                            -> { types: findReturnTypes($1) }
- | 'COUNT' '(' OptionalAllOrDistinct ValueExpressionList ')'  -> { types: findReturnTypes($1) }
- ;
-
-CountFunction_EDIT
- : 'COUNT' '(' OptionalAllOrDistinct AnyCursor RightParenthesisOrError
-   {
-     suggestColumns();
-     if (!$3) {
-       if (isImpala()) {
-         suggestKeywords(['*', 'ALL', 'DISTINCT']);
-       } else {
-         suggestKeywords(['*', 'DISTINCT']);
-       }
-     }
-     $$ = { types: findReturnTypes($1) };
-   }
- | 'COUNT' '(' OptionalAllOrDistinct ValueExpressionList 'CURSOR' RightParenthesisOrError
-   {
-     suggestValueExpressionKeywords($4);
-     $$ = { types: findReturnTypes($1) };
-   }
- | 'COUNT' '(' OptionalAllOrDistinct ValueExpressionList_EDIT RightParenthesisOrError
-   {
-     if ($4.cursorAtStart && !$3) {
-       if (isImpala()) {
-         suggestKeywords(['ALL', 'DISTINCT']);
-       } else {
-         suggestKeywords(['DISTINCT']);
-       }
-     }
-     $$ = { types: findReturnTypes($1) };
-   }
- ;
-
-OtherAggregateFunction
- : OtherAggregateFunction_Type '(' OptionalAllOrDistinct ')'                      -> { types: findReturnTypes($1) }
- | OtherAggregateFunction_Type '(' OptionalAllOrDistinct ValueExpressionList ')'  -> { types: findReturnTypes($1) }
- ;
-
-OtherAggregateFunction_EDIT
- : OtherAggregateFunction_Type '(' OptionalAllOrDistinct AnyCursor RightParenthesisOrError
-   {
-     suggestFunctions();
-     suggestColumns();
-     if (!$3) {
-       if ($1.toLowerCase() === 'group_concat') {
-         suggestKeywords(['ALL' ]);
-       } else if (isImpala()) {
-         suggestKeywords(['ALL', 'DISTINCT']);
-       } else {
-         suggestKeywords(['DISTINCT']);
-       }
-     }
-     applyArgumentTypesToSuggestions($1, 1);
-     $$ = { types: findReturnTypes($1) };
-   }
- | OtherAggregateFunction_Type '(' OptionalAllOrDistinct ValueExpressionList 'CURSOR' RightParenthesisOrError
-   {
-     suggestValueExpressionKeywords($4);
-     $$ = { types: findReturnTypes($1) };
-   }
- | OtherAggregateFunction_Type '(' OptionalAllOrDistinct ValueExpressionList_EDIT RightParenthesisOrError
-   {
-     if ($4.cursorAtStart && !$3) {
-       if ($1.toLowerCase() === 'group_concat') {
-         suggestKeywords(['ALL' ]);
-       } else if (isImpala()) {
-         suggestKeywords(['ALL', 'DISTINCT']);
-       } else {
-         suggestKeywords(['DISTINCT']);
-       }
-     }
-     if (parser.yy.result.suggestFunctions && !parser.yy.result.suggestFunctions.types) {
-       applyArgumentTypesToSuggestions($1, $4.position);
-     }
-     $$ = { types: findReturnTypes($1) };
-   }
- ;
-
-OtherAggregateFunction_Type
- : '<impala>APPX_MEDIAN'
- | 'AVG'
- | '<hive>COLLECT_SET'
- | '<hive>COLLECT_LIST'
- | '<hive>CORR'
- | '<hive>COVAR_POP'
- | '<hive>COVAR_SAMP'
- | '<impala>GROUP_CONCAT'
- | '<hive>HISTOGRAM_NUMERI'
- | '<impala>STDDEV'
- | 'STDDEV_POP'
- | 'STDDEV_SAMP'
- | 'MAX'
- | 'MIN'
- | '<hive>NTILE'
- | '<hive>PERCENTILE'
- | '<hive>PERCENTILE_APPROX'
- | 'VARIANCE'
- | '<impala>VARIANCE_POP'
- | '<impala>VARIANCE_SAMP'
- | 'VAR_POP'
- | 'VAR_SAMP'
- ;
-
-ExtractFunction
- : '<impala>EXTRACT' '(' ValueExpression FromOrComma ValueExpression ')'
- | '<impala>EXTRACT' '(' ')'
- ;
-
-ExtractFunction_EDIT
- : '<impala>EXTRACT' '(' AnyCursor FromOrComma ValueExpression RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions($4.toLowerCase() === 'from' ? ['STRING'] : ['TIMESTAMP']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' AnyCursor FromOrComma RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions($4.toLowerCase() === 'from' ? ['STRING'] : ['TIMESTAMP']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' AnyCursor RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions(['STRING', 'TIMESTAMP']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' ValueExpression_EDIT FromOrComma ValueExpression RightParenthesisOrError
-   {
-     applyTypeToSuggestions($4.toLowerCase() === 'from' ? ['STRING'] : ['TIMESTAMP']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' ValueExpression_EDIT FromOrComma RightParenthesisOrError
-   {
-     applyTypeToSuggestions($4.toLowerCase() === 'from' ? ['STRING'] : ['TIMESTAMP']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' ValueExpression_EDIT RightParenthesisOrError
-   {
-     applyTypeToSuggestions(['STRING', 'TIMESTAMP']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' ValueExpression FromOrComma AnyCursor RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions($4.toLowerCase() === 'from' ? ['TIMESTAMP'] : ['STRING']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' FromOrComma AnyCursor RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions($4.toLowerCase() === 'from' ? ['TIMESTAMP'] : ['STRING']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' ValueExpression FromOrComma ValueExpression_EDIT RightParenthesisOrError
-   {
-     applyTypeToSuggestions($4.toLowerCase() === 'from' ? ['TIMESTAMP'] : ['STRING']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' FromOrComma ValueExpression_EDIT RightParenthesisOrError
-   {
-    applyTypeToSuggestions($4.toLowerCase() === 'from' ? ['TIMESTAMP'] : ['STRING']);
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' ValueExpression 'CURSOR' ValueExpression RightParenthesisOrError
-   {
-     if ($3.types[0] === 'STRING') {
-       suggestValueExpressionKeywords($3, ['FROM']);
-     } else {
-       suggestValueExpressionKeywords($3);
-     }
-     $$ = { types: findReturnTypes($1) };
-   }
- | '<impala>EXTRACT' '(' ValueExpression 'CURSOR' RightParenthesisOrError
-   {
-     if ($3.types[0] === 'STRING') {
-       suggestValueExpressionKeywords($3, ['FROM']);
-     } else {
-       suggestValueExpressionKeywords($3);
-     }
-     $$ = { types: findReturnTypes($1) };
-   }
- ;
-
-FromOrComma
- : 'FROM'
- | ','
- ;
-
-SumFunction
- : 'SUM' '(' OptionalAllOrDistinct ValueExpression ')'  -> { types: findReturnTypes($1) }
- | 'SUM' '(' ')'                                        -> { types: findReturnTypes($1) }
- ;
-
-SumFunction_EDIT
- : 'SUM' '(' OptionalAllOrDistinct AnyCursor RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     applyArgumentTypesToSuggestions($1, 1);
-     if (!$3) {
-       if (isImpala()) {
-         suggestKeywords(['ALL', 'DISTINCT']);
-       } else {
-         suggestKeywords(['DISTINCT']);
-       }
-     }
-     $$ = { types: findReturnTypes($1) };
-   }
- | 'SUM' '(' OptionalAllOrDistinct ValueExpression 'CURSOR' RightParenthesisOrError
-   {
-     suggestValueExpressionKeywords($4);
-     $$ = { types: findReturnTypes($1) };
-   }
- | 'SUM' '(' OptionalAllOrDistinct ValueExpression_EDIT RightParenthesisOrError
-   {
-     if (parser.yy.result.suggestFunctions && ! parser.yy.result.suggestFunctions.types) {
-       applyArgumentTypesToSuggestions($1, 1);
-     }
-     $$ = { types: findReturnTypes($1) };
-   }
- ;
-
-LateralView
- : '<hive>LATERAL' '<hive>VIEW' UserDefinedFunction RegularIdentifier LateralViewColumnAliases  -> [{ udtf: $3, tableAlias: $4, columnAliases: $5 }]
- | '<hive>LATERAL' '<hive>VIEW' UserDefinedFunction LateralViewColumnAliases                    -> [{ udtf: $3, columnAliases: $4 }]
- | LateralView_INVALID
- ;
-
-LateralView_INVALID
- : '<hive>LATERAL' '<hive>VIEW' UserDefinedFunction RegularIdentifier error                     -> []
- | '<hive>LATERAL' '<hive>VIEW' UserDefinedFunction error                                       -> []
- | '<hive>LATERAL' '<hive>VIEW' error                                                           -> []
- | '<hive>LATERAL' error                                                                        -> []
- ;
-
-LateralView_EDIT
- : '<hive>LATERAL' '<hive>VIEW' UserDefinedFunction_EDIT
- | '<hive>LATERAL' '<hive>VIEW' UserDefinedFunction_EDIT LateralViewColumnAliases
- | '<hive>LATERAL' '<hive>VIEW' UserDefinedFunction RegularIdentifier 'CURSOR'
-   {
-     suggestKeywords(['AS']);
-     $$ = [];
-   }
- | '<hive>LATERAL' '<hive>VIEW' UserDefinedFunction 'CURSOR'
-   {
-     suggestKeywords(['AS']);
-     $$ = [];
-   }
- | '<hive>LATERAL' '<hive>VIEW' 'CURSOR'
-   {
-     suggestKeywords(['explode', 'posexplode']);
-     $$ = [];
-   }
- | '<hive>LATERAL' 'CURSOR'
-   {
-     suggestKeywords(['VIEW']);
-     $$ = [];
-   }
- ;
-
-LateralViewColumnAliases
- : '<hive>AS' RegularIdentifier                                -> [ $2 ]
- | '<hive>AS' '(' RegularIdentifier ',' RegularIdentifier ')'  -> [ $3, $5 ]
- ;// 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.
-
-ValueExpression
- : 'NOT' ValueExpression
-   {
-     // verifyType($2, 'BOOLEAN');
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | '!' ValueExpression
-   {
-     // verifyType($2, 'BOOLEAN');
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | '~' ValueExpression                                                              -> $2
- | '-' ValueExpression %prec NEGATION
-   {
-     // verifyType($2, 'NUMBER');
-     $$ = $2;
-     $2.types = ['NUMBER'];
-   }
- | ValueExpression 'IS' OptionalNot 'NULL'              -> { types: [ 'BOOLEAN' ] }
- ;
-
-ValueExpression_EDIT
- : 'NOT' ValueExpression_EDIT                           -> { types: [ 'BOOLEAN' ] }
- | 'NOT' 'CURSOR'
-   {
-     suggestFunctions();
-     suggestColumns();
-     suggestKeywords(['EXISTS']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | '!' ValueExpression_EDIT                             -> { types: [ 'BOOLEAN' ] }
- | '!' AnyCursor
-   {
-     suggestFunctions({ types: [ 'BOOLEAN' ] });
-     suggestColumns({ types: [ 'BOOLEAN' ] });
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | '~' ValueExpression_EDIT                             -> { types: [ 'T' ] }
- | '~' 'PARTIAL_CURSOR'
-   {
-     suggestFunctions();
-     suggestColumns();
-     $$ = { types: [ 'T' ] };
-   }
- | '-' ValueExpression_EDIT %prec NEGATION
-   {
-     applyTypeToSuggestions('NUMBER')
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | '-' 'PARTIAL_CURSOR' %prec NEGATION
-   {
-     suggestFunctions({ types: [ 'NUMBER' ] });
-     suggestColumns({ types: [ 'NUMBER' ] });
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression 'IS' 'NOT' 'CURSOR'
-    {
-      suggestKeywords(['NULL']);
-      $$ = { types: [ 'BOOLEAN' ] };
-    }
- | ValueExpression 'IS' 'CURSOR'
-   {
-     suggestKeywords(['NOT NULL', 'NULL']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'IS' 'CURSOR' 'NULL'
-   {
-     suggestKeywords(['NOT']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- ;
-
-// ------------------  EXISTS and parenthesized ------------------
-ValueExpression
- : 'EXISTS' TableSubQuery
-   {
-     $$ = { types: [ 'BOOLEAN' ] };
-     // clear correlated flag after completed sub-query (set by lexer)
-     parser.yy.correlatedSubQuery = false;
-   }
- | '(' ValueExpression ')'                                -> $2
- ;
-
-ValueExpression_EDIT
- : 'EXISTS' TableSubQuery_EDIT                               -> { types: [ 'BOOLEAN' ] }
- | '(' ValueExpression_EDIT RightParenthesisOrError          -> $2
- | '(' AnyCursor RightParenthesisOrError
-   {
-     valueExpressionSuggest();
-     $$ = { types: ['T'] };
-   }
- ;
-
-// ------------------  COMPARISON ------------------
-
-ValueExpression
- : ValueExpression '=' ValueExpression                    -> { types: [ 'BOOLEAN' ] }
- | ValueExpression '<' ValueExpression  -> { types: [ 'BOOLEAN' ] }
- | ValueExpression '>' ValueExpression  -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'COMPARISON_OPERATOR' ValueExpression  -> { types: [ 'BOOLEAN' ] }
- ;
-
-ValueExpression_EDIT
- : 'CURSOR' '=' ValueExpression
-   {
-     valueExpressionSuggest($3);
-     applyTypeToSuggestions($3.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | 'CURSOR' '<' ValueExpression
-   {
-     valueExpressionSuggest($3);
-     applyTypeToSuggestions($3.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | 'CURSOR' '>' ValueExpression
-   {
-     valueExpressionSuggest($3);
-     applyTypeToSuggestions($3.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | 'CURSOR' 'COMPARISON_OPERATOR' ValueExpression
-   {
-     valueExpressionSuggest($3);
-     applyTypeToSuggestions($3.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression_EDIT '=' ValueExpression
-   {
-     applyTypeToSuggestions($3.types);
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression_EDIT '<' ValueExpression
-   {
-     applyTypeToSuggestions($3.types);
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression_EDIT '>' ValueExpression
-   {
-     applyTypeToSuggestions($3.types);
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression_EDIT 'COMPARISON_OPERATOR' ValueExpression
-   {
-     applyTypeToSuggestions($3.types);
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression '=' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest($1);
-     applyTypeToSuggestions($1.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression '<' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest($1);
-     applyTypeToSuggestions($1.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression '>' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest($1);
-     applyTypeToSuggestions($1.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'COMPARISON_OPERATOR' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest($1);
-     applyTypeToSuggestions($1.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression '=' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions($1.types);
-     addColRefIfExists($1);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression '<' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions($1.types);
-     addColRefIfExists($1);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression '>' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions($1.types);
-     addColRefIfExists($1);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression 'COMPARISON_OPERATOR' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions($1.types);
-     addColRefIfExists($1);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- ;
-
-
-// ------------------  IN ------------------
-
-ValueExpression
- : ValueExpression 'NOT' 'IN' '(' TableSubQueryInner ')'  -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'NOT' 'IN' '(' InValueList ')'         -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'IN' '(' TableSubQueryInner ')'        -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'IN' '(' InValueList ')'               -> { types: [ 'BOOLEAN' ] }
- ;
-
-ValueExpression_EDIT
- : ValueExpression 'NOT' 'IN' ValueExpressionInSecondPart_EDIT
-   {
-     if ($4.inValueEdit) {
-       valueExpressionSuggest($1);
-       applyTypeToSuggestions($1.types);
-     }
-     if ($4.cursorAtStart) {
-       suggestKeywords(['SELECT']);
-     }
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'IN' ValueExpressionInSecondPart_EDIT
-   {
-     if ($3.inValueEdit) {
-       valueExpressionSuggest($1);
-       applyTypeToSuggestions($1.types);
-     }
-     if ($3.cursorAtStart) {
-       suggestKeywords(['SELECT']);
-     }
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression_EDIT 'NOT' 'IN' '(' InValueList RightParenthesisOrError         -> { types: [ 'BOOLEAN' ] }
- | ValueExpression_EDIT 'NOT' 'IN' '(' TableSubQueryInner RightParenthesisOrError  -> { types: [ 'BOOLEAN' ] }
- | ValueExpression_EDIT 'IN' '(' InValueList RightParenthesisOrError               -> { types: [ 'BOOLEAN' ] }
- | ValueExpression_EDIT 'IN' '(' TableSubQueryInner RightParenthesisOrError        -> { types: [ 'BOOLEAN' ] }
- ;
-
-ValueExpressionInSecondPart_EDIT
- : '(' TableSubQueryInner_EDIT RightParenthesisOrError
- | '(' InValueList_EDIT RightParenthesisOrError         -> { inValueEdit: true }
- | '(' AnyCursor RightParenthesisOrError                -> { inValueEdit: true, cursorAtStart: true }
- ;
-
-// ------------------  BETWEEN ------------------
-
-ValueExpression
- : ValueExpression 'NOT' 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression  -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression        -> { types: [ 'BOOLEAN' ] }
- ;
-
-ValueExpression_EDIT
- : ValueExpression_EDIT 'NOT' 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression
-   {
-     if ($4.types[0] === $6.types[0]) {
-       applyTypeToSuggestions($4.types);
-     }
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'NOT' 'BETWEEN' ValueExpression_EDIT 'BETWEEN_AND' ValueExpression
-   {
-     if ($1.types[0] === $6.types[0]) {
-       applyTypeToSuggestions($1.types);
-     }
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'NOT' 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression_EDIT
-   {
-     if ($1.types[0] === $4.types[0]) {
-       applyTypeToSuggestions($1.types);
-     }
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'NOT' 'BETWEEN' ValueExpression 'BETWEEN_AND' 'CURSOR'
-   {
-     valueExpressionSuggest($1);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'NOT' 'BETWEEN' ValueExpression 'CURSOR'
-   {
-     suggestValueExpressionKeywords($4, ['AND']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'NOT' 'BETWEEN' 'CURSOR'
-   {
-     valueExpressionSuggest($1);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression_EDIT 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression
-   {
-     if ($1.types[0] === $3.types[0]) {
-       applyTypeToSuggestions($1.types)
-     }
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'BETWEEN' ValueExpression_EDIT 'BETWEEN_AND' ValueExpression
-   {
-     if ($1.types[0] === $3.types[0]) {
-       applyTypeToSuggestions($1.types)
-     }
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'BETWEEN' ValueExpression 'BETWEEN_AND' ValueExpression_EDIT
-   {
-     if ($1.types[0] === $3.types[0]) {
-       applyTypeToSuggestions($1.types)
-     }
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'BETWEEN' ValueExpression 'BETWEEN_AND' 'CURSOR'
-   {
-     valueExpressionSuggest($1);
-     applyTypeToSuggestions($1.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'BETWEEN' ValueExpression 'CURSOR'
-   {
-     suggestValueExpressionKeywords($3, ['AND']);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'BETWEEN' 'CURSOR'
-   {
-     valueExpressionSuggest($1);
-     applyTypeToSuggestions($1.types);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- ;
-
-// ------------------  BOOLEAN ------------------
-
-ValueExpression
- : ValueExpression 'OR' ValueExpression
-   {
-     // verifyType($1, 'BOOLEAN');
-     // verifyType($3, 'BOOLEAN');
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'AND' ValueExpression
-   {
-     // verifyType($1, 'BOOLEAN');
-     // verifyType($3, 'BOOLEAN');
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- ;
-
-ValueExpression_EDIT
- : 'CURSOR' 'OR' ValueExpression
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression_EDIT 'OR' ValueExpression
-   {
-     addColRefIfExists();
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression 'OR' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'OR' ValueExpression_EDIT
-   {
-     addColRefIfExists($1);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | 'CURSOR' 'AND' ValueExpression
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression_EDIT 'AND' ValueExpression
-   {
-     addColRefIfExists($3);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- | ValueExpression 'AND' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'AND' ValueExpression_EDIT
-   {
-     addColRefIfExists($1);
-     $$ = { types: [ 'BOOLEAN' ] }
-   }
- ;
-
-// ------------------  ARITHMETIC ------------------
-
-ValueExpression
- : ValueExpression '-' ValueExpression
-   {
-     // verifyType($1, 'NUMBER');
-     // verifyType($3, 'NUMBER');
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression '*' ValueExpression
-   {
-     // verifyType($1, 'NUMBER');
-     // verifyType($3, 'NUMBER');
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression 'ARITHMETIC_OPERATOR' ValueExpression
-   {
-     // verifyType($1, 'NUMBER');
-     // verifyType($3, 'NUMBER');
-     $$ = { types: [ 'NUMBER' ] };
-   }
- ;
-
-ValueExpression_EDIT
- : 'CURSOR' '*' ValueExpression
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions([ 'NUMBER' ]);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | 'CURSOR' 'ARITHMETIC_OPERATOR' ValueExpression
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions([ 'NUMBER' ]);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression_EDIT '-' ValueExpression
-   {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($3);
-     $$ = { types: [ 'NUMBER' ] }
-   }
- | ValueExpression_EDIT '*' ValueExpression
-   {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($3);
-     $$ = { types: [ 'NUMBER' ] }
-   }
- | ValueExpression_EDIT 'ARITHMETIC_OPERATOR' ValueExpression
-   {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($3);
-     $$ = { types: [ 'NUMBER' ] }
-   }
- | ValueExpression '-' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions(['NUMBER']);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression '*' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions(['NUMBER']);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression 'ARITHMETIC_OPERATOR' PartialBacktickedOrAnyCursor
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions(['NUMBER']);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression '-' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($1);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression '*' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($1);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- | ValueExpression 'ARITHMETIC_OPERATOR' ValueExpression_EDIT
-   {
-     applyTypeToSuggestions(['NUMBER']);
-     addColRefIfExists($1);
-     $$ = { types: [ 'NUMBER' ] };
-   }
- ;
-
-// ------------------  LIKE, RLIKE and REGEXP ------------------
-
-ValueExpression
- : ValueExpression 'NOT' 'LIKE' ValueExpression
-   {
-     // verifyType($1, 'STRING');
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'LIKE' ValueExpression
-   {
-     // verifyType($1, 'STRING');
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'RLIKE' ValueExpression
-   {
-     // verifyType($1, 'STRING');
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'REGEXP' ValueExpression
-   {
-     // verifyType($1, 'STRING');
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- ;
-
-ValueExpression_EDIT
- : ValueExpression_EDIT 'NOT' 'LIKE' ValueExpression         -> { types: [ 'BOOLEAN' ] }
- | ValueExpression_EDIT 'LIKE' ValueExpression               -> { types: [ 'BOOLEAN' ] }
- | ValueExpression_EDIT 'RLIKE' ValueExpression              -> { types: [ 'BOOLEAN' ] }
- | ValueExpression_EDIT 'REGEXP' ValueExpression             -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'NOT' 'LIKE' ValueExpression_EDIT         -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'LIKE' ValueExpression_EDIT               -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'RLIKE' ValueExpression_EDIT              -> { types: [ 'BOOLEAN' ] }
- | ValueExpression 'REGEXP' ValueExpression_EDIT             -> { types: [ 'BOOLEAN' ] }
- | 'CURSOR' 'NOT' 'LIKE' ValueExpression
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions([ 'STRING' ]);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | 'CURSOR' 'LIKE' ValueExpression
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions([ 'STRING' ]);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | 'CURSOR' 'RLIKE' ValueExpression
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions([ 'STRING' ]);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | 'CURSOR' 'REGEXP' ValueExpression
-   {
-     valueExpressionSuggest();
-     applyTypeToSuggestions([ 'STRING' ]);
-     $$ = { types: [ 'BOOLEAN' ] };
-   }
- | ValueExpression 'LIKE' PartialBacktickedOrCursor
-   {
-     suggestFunctions({ types: [ 'STRING' ] });
-     suggestColumns({ types: [ 'STRING' ] });
-     $$ = { types: ['BOOLEAN'] }
-   }
- | ValueExpression 'RLIKE' PartialBacktickedOrCursor
-   {
-     suggestFunctions({ types: [ 'STRING' ] });
-     suggestColumns({ types: [ 'STRING' ] });
-     $$ = { types: ['BOOLEAN'] }
-   }
- | ValueExpression 'REGEXP' PartialBacktickedOrCursor
-   {
-     suggestFunctions({ types: [ 'STRING' ] });
-     suggestColumns({ types: [ 'STRING' ] });
-     $$ = { types: ['BOOLEAN'] }
-   }
- ;
-
-// ------------------  CASE, WHEN, THEN ------------------
-
-ValueExpression
- : 'CASE' CaseRightPart                  -> $2
- | 'CASE' ValueExpression CaseRightPart  -> $3
- ;
-
-ValueExpression_EDIT
- : 'CASE' CaseRightPart_EDIT                         -> $2
- | 'CASE' 'CURSOR' EndOrError
-   {
-     valueExpressionSuggest();
-     suggestKeywords(['WHEN']);
-     $$ = { types: [ 'T' ] };
-   }
- | 'CASE' ValueExpression CaseRightPart_EDIT         -> $3
- | 'CASE' ValueExpression 'CURSOR' EndOrError
-   {
-     suggestValueExpressionKeywords($2, ['WHEN']);
-     $$ = { types: [ 'T' ] };
-   }
- | 'CASE' ValueExpression_EDIT CaseRightPart         -> $3
- | 'CASE' ValueExpression_EDIT EndOrError            -> { types: [ 'T' ] }
- | 'CASE' 'CURSOR' CaseRightPart                     -> { types: [ 'T' ] }
- ;
-
-CaseRightPart
- : CaseWhenThenList 'END'                         -> findCaseType($1)
- | CaseWhenThenList 'ELSE' ValueExpression 'END'
-   {
-     $1.caseTypes.push($3);
-     $$ = findCaseType($1);
-   }
- ;
-
-CaseRightPart_EDIT
- : CaseWhenThenList_EDIT EndOrError                            -> findCaseType($1)
- | CaseWhenThenList 'ELSE' ValueExpression 'CURSOR'
-   {
-     suggestValueExpressionKeywords($3, ['END']);
-     $1.caseTypes.push($3);
-     $$ = findCaseType($1);
-   }
- | CaseWhenThenList_EDIT 'ELSE' ValueExpression EndOrError
-   {
-     $1.caseTypes.push($3);
-     $$ = findCaseType($1);
-   }
- | CaseWhenThenList_EDIT 'ELSE' EndOrError                      -> findCaseType($1)
- | CaseWhenThenList 'CURSOR' ValueExpression EndOrError
-   {
-     if ($4.toLowerCase() !== 'end') {
-       suggestValueExpressionKeywords($1, ['END', 'ELSE', 'WHEN']);
-     } else {
-       suggestValueExpressionKeywords($1, ['ELSE', 'WHEN']);
-     }
-     $$ = findCaseType($1);
-   }
- | CaseWhenThenList 'CURSOR' EndOrError
-   {
-     if ($3.toLowerCase() !== 'end') {
-       suggestValueExpressionKeywords($1, ['END', 'ELSE', 'WHEN']);
-     } else {
-       suggestValueExpressionKeywords($1, ['ELSE', 'WHEN']);
-     }
-     $$ = findCaseType($1);
-   }
- | CaseWhenThenList 'ELSE' ValueExpression_EDIT EndOrError
-   {
-     $1.caseTypes.push($3);
-     $$ = findCaseType($1);
-   }
- | CaseWhenThenList 'ELSE' 'CURSOR' EndOrError
-   {
-     valueExpressionSuggest();
-     $$ = findCaseType($1);
-   }
- | 'ELSE' 'CURSOR' EndOrError
-   {
-     valueExpressionSuggest();
-     $$ = { types: [ 'T' ] };
-   }
- | 'CURSOR' 'ELSE' ValueExpression EndOrError
-   {
-     valueExpressionSuggest();
-     suggestKeywords(['WHEN']);
-     $$ = $3;
-   }
- | 'CURSOR' 'ELSE' EndOrError
-   {
-     valueExpressionSuggest();
-     suggestKeywords(['WHEN']);
-     $$ = { types: [ 'T' ] };
-   }
- ;
-
-EndOrError
- : 'END'
- | error
- ;
-
-CaseWhenThenList
- : CaseWhenThenListPartTwo                   -> { caseTypes: [ $1 ], lastType: $1 }
- | CaseWhenThenList CaseWhenThenListPartTwo
-   {
-     $1.caseTypes.push($2);
-     $$ = { caseTypes: $1.caseTypes, lastType: $2 };
-   }
- ;
-
-CaseWhenThenList_EDIT
- : CaseWhenThenListPartTwo_EDIT
- | CaseWhenThenList CaseWhenThenListPartTwo_EDIT
- | CaseWhenThenList CaseWhenThenListPartTwo_EDIT CaseWhenThenList
- | CaseWhenThenList 'CURSOR' CaseWhenThenList
-   {
-     suggestValueExpressionKeywords($1, ['WHEN']);
-   }
- | CaseWhenThenListPartTwo_EDIT CaseWhenThenList                   -> $2
- ;
-
-CaseWhenThenListPartTwo
- : 'WHEN' ValueExpression 'THEN' ValueExpression  -> $4
- ;
-
-CaseWhenThenListPartTwo_EDIT
- : 'WHEN' ValueExpression_EDIT                         -> { caseTypes: [{ types: ['T'] }] }
- | 'WHEN' ValueExpression_EDIT 'THEN'                  -> { caseTypes: [{ types: ['T'] }] }
- | 'WHEN' ValueExpression_EDIT 'THEN' ValueExpression  -> { caseTypes: [$4] }
- | 'WHEN' ValueExpression 'THEN' ValueExpression_EDIT  -> { caseTypes: [$4] }
- | 'WHEN' 'THEN' ValueExpression_EDIT                  -> { caseTypes: [$3] }
- | 'CURSOR' ValueExpression 'THEN'
-   {
-     suggestKeywords(['WHEN']);
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'CURSOR' ValueExpression 'THEN' ValueExpression
-   {
-     suggestKeywords(['WHEN']);
-     $$ = { caseTypes: [$4] };
-   }
- | 'CURSOR' 'THEN'
-   {
-     valueExpressionSuggest();
-     suggestKeywords(['WHEN']);
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'CURSOR' 'THEN' ValueExpression
-    {
-      valueExpressionSuggest();
-      suggestKeywords(['WHEN']);
-      $$ = { caseTypes: [{ types: ['T'] }] };
-    }
- | 'WHEN' 'CURSOR'
-   {
-     valueExpressionSuggest();
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'WHEN' 'CURSOR' ValueExpression
-   {
-     valueExpressionSuggest();
-     suggestKeywords(['THEN']);
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'WHEN' 'CURSOR' 'THEN'
-   {
-     valueExpressionSuggest();
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'WHEN' 'CURSOR' 'THEN' ValueExpression
-   {
-     valueExpressionSuggest();
-     $$ = { caseTypes: [$4] };
-   }
- | 'WHEN' ValueExpression 'CURSOR'
-   {
-     suggestValueExpressionKeywords($2, ['THEN']);
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'WHEN' ValueExpression 'CURSOR' ValueExpression
-   {
-     suggestValueExpressionKeywords($2, ['THEN']);
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'WHEN' ValueExpression 'THEN' 'CURSOR'
-   {
-     valueExpressionSuggest();
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'WHEN' ValueExpression 'THEN' 'CURSOR' ValueExpression
-   {
-     valueExpressionSuggest();
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'WHEN' 'THEN' 'CURSOR' ValueExpression
-   {
-     valueExpressionSuggest();
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- | 'WHEN' 'THEN' 'CURSOR'
-   {
-     valueExpressionSuggest();
-     $$ = { caseTypes: [{ types: ['T'] }] };
-   }
- ;// 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
- : CreateStatement
- ;
-
-DataDefinition_EDIT
- : CreateStatement_EDIT
- ;
-
-CreateStatement
- : DatabaseDefinition
- | TableDefinition
- ;
-
-CreateStatement_EDIT
- : DatabaseDefinition_EDIT
- | TableDefinition_EDIT
- | AnyCreate OptionalHiveTemporary OptionalExternal 'CURSOR'
-   {
-     if ($3) {
-       suggestKeywords(['TABLE']);
-     } else if (isHive()) {
-       if ($2) {
-         suggestKeywords(['EXTERNAL TABLE', 'TABLE']);
-       } else {
-         suggestKeywords(['DATABASE', 'EXTERNAL TABLE', 'SCHEMA', 'TABLE', 'TEMPORARY EXTERNAL TABLE', 'TEMPORARY TABLE']);
-       }
-     } else if (isImpala()) {
-       suggestKeywords(['DATABASE', 'EXTERNAL TABLE', 'SCHEMA', 'TABLE']);
-     } else {
-       suggestKeywords(['DATABASE', 'SCHEMA', 'TABLE']);
-     }
-   }
- ;
-
-
-DatabaseDefinition
- : AnyCreate DatabaseOrSchema OptionalIfNotExists
- | AnyCreate DatabaseOrSchema OptionalIfNotExists RegularIdentifier DatabaseDefinitionOptionals
- ;
-
-DatabaseDefinition_EDIT
- : AnyCreate DatabaseOrSchema OptionalIfNotExists 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['IF NOT EXISTS']);
-     }
-   }
- | AnyCreate DatabaseOrSchema OptionalIfNotExists_EDIT
- | AnyCreate DatabaseOrSchema OptionalIfNotExists 'CURSOR' RegularIdentifier
-   {
-     if (!$3) {
-       suggestKeywords(['IF NOT EXISTS']);
-     }
-   }
- | AnyCreate DatabaseOrSchema OptionalIfNotExists_EDIT RegularIdentifier
- | AnyCreate DatabaseOrSchema OptionalIfNotExists RegularIdentifier DatabaseDefinitionOptionals_EDIT error
- | AnyCreate DatabaseOrSchema OptionalIfNotExists RegularIdentifier DatabaseDefinitionOptionals 'CURSOR'
- ;
-
-DatabaseDefinitionOptionals
- : OptionalComment OptionalHdfsLocation OptionalHiveDbProperties
-   {
-     var keywords = [];
-     if (!$3 && isHive()) {
-       keywords.push('WITH DBPROPERTIES');
-     }
-     if (!$2 && !$3) {
-       keywords.push('LOCATION');
-     }
-     if (!$1 && !$2 && !$3) {
-       keywords.push('COMMENT');
-     }
-     if (keywords.length > 0) {
-       suggestKeywords(keywords);
-     }
-   }
- ;
-
-DatabaseDefinitionOptionals_EDIT
- : OptionalComment_INVALID OptionalHdfsLocation OptionalHiveDbProperties
- | OptionalComment OptionalHdfsLocation_EDIT OptionalHiveDbProperties
- ;
-
-OptionalComment
- :
- | Comment
- ;
-
-Comment
- : HiveOrImpalaComment SingleQuotedValue
- ;
-
-Comment_INVALID
- : HiveOrImpalaComment SINGLE_QUOTE
- | HiveOrImpalaComment SINGLE_QUOTE VALUE
- ;
-
-OptionalComment_INVALID
- : Comment_INVALID
- ;
-
-OptionalHdfsLocation
- :
- | HdfsLocation
- ;
-
-OptionalHdfsLocation_EDIT
- : HdfsLocation_EDIT
- ;
-
-HdfsLocation
- : HiveOrImpalaLocation HdfsPath
- ;
-
-HdfsLocation_EDIT
- : HiveOrImpalaLocation HdfsPath_EDIT
- ;
-
-HdfsPath
- : 'HDFS_START_QUOTE' 'HDFS_PATH' 'HDFS_END_QUOTE'
- ;
-
-HdfsPath_EDIT
- : 'HDFS_START_QUOTE' 'HDFS_PATH' 'PARTIAL_CURSOR' 'HDFS_PATH' 'HDFS_END_QUOTE'
-    {
-      suggestHdfs({ path: $2 });
-    }
- | 'HDFS_START_QUOTE' 'HDFS_PATH' 'PARTIAL_CURSOR' 'HDFS_END_QUOTE'
-   {
-     suggestHdfs({ path: $2 });
-   }
- | 'HDFS_START_QUOTE' 'HDFS_PATH' 'PARTIAL_CURSOR'
-    {
-      suggestHdfs({ path: $2 });
-    }
- | 'HDFS_START_QUOTE' 'PARTIAL_CURSOR' 'HDFS_END_QUOTE'
-   {
-     suggestHdfs({ path: '' });
-   }
- | 'HDFS_START_QUOTE' 'PARTIAL_CURSOR'
-    {
-      suggestHdfs({ path: '' });
-    }
- ;
-
-OptionalHiveDbProperties
- :
- | HiveDbProperties
- ;
-
-HiveDbProperties
- : '<hive>WITH' 'DBPROPERTIES' ParenthesizedPropertyAssignmentList
- | '<hive>WITH' 'DBPROPERTIES'
- | '<hive>WITH' 'CURSOR'
-   {
-     suggestKeywords(['DBPROPERTIES']);
-   }
- ;
-
-ParenthesizedPropertyAssignmentList
- : '(' PropertyAssignmentList ')'
- ;
-
-PropertyAssignmentList
- : PropertyAssignment
- | PropertyAssignmentList ',' PropertyAssignment
- ;
-
-PropertyAssignment
- : QuotedValue '=' UnsignedValueSpecification
- ;
-
-TableDefinition
- : AnyCreate OptionalHiveTemporary OptionalExternal AnyTable OptionalIfNotExists TableDefinitionRightPart
- ;
-
-TableDefinition_EDIT
- : AnyCreate OptionalHiveTemporary OptionalExternal AnyTable OptionalIfNotExists TableDefinitionRightPart_EDIT
- | AnyCreate OptionalHiveTemporary OptionalExternal AnyTable OptionalIfNotExists 'CURSOR'
-   {
-     if (!$5) {
-       suggestKeywords(['IF NOT EXISTS']);
-     }
-   }
- | AnyCreate OptionalHiveTemporary OptionalExternal AnyTable OptionalIfNotExists_EDIT
- ;
-
-TableDefinitionRightPart
- : TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement
- ;
-
-TableDefinitionRightPart_EDIT
- : TableIdentifierAndOptionalColumnSpecification_EDIT OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy_EDIT OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties_EDIT OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy_EDIT
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy_EDIT OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy_EDIT OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation_EDIT OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn_EDIT OptionalAsSelectStatement
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn OptionalAsSelectStatement_EDIT
- | TableIdentifierAndOptionalColumnSpecification OptionalComment OptionalPartitionedBy OptionalImpalaWithSerdeproperties OptionalHiveClusteredBy
-   OptionalHiveSkewedBy OptionalStoredAsOrBy OptionalHdfsLocation OptionalTblproperties OptionalImpalaCachedIn 'CURSOR'
-   {
-     // TODO: Don't always sort the keywords as order is important
-     var keywords = [];
-     if (!$1 && !$2 && !$3 && !$4 && !$5 && !$6 && !$7 && !$8 && !$9 && !$10) {
-       keywords.push('LIKE');
-       if (isImpala()) {
-         keywords.push('LIKE PARQUET');
-       }
-     } else {
-       keywords.push('AS');
-       if (!$2 && !$3 && !$4 && !$5 && !$6 && !$7 && !$8 && !$9 && !$10) {
-         keywords.push('COMMENT');
-       }
-       if (!$3 && !$4 && !$5 && !$6 && !$7 && !$8 && !$9 && !$10) {
-         keywords.push('PARTITIONED BY');
-       }
-       if (isImpala() && !$4 && !$5 && !$6 && !$7 && !$8 && !$9 && !$10) {
-         keywords.push('WITH SERDEPROPERTIES');
-       }
-       if (isHive() && !$5 && !$6 && !$7 && !$8 && !$9 && !$10) {
-         keywords.push('CLUSTERED BY');
-       }
-       if (isHive() && !$6 && !$7 && !$8 && !$9 && !$10) {
-         keywords.push('SKEWED BY');
-       } else if (isHive() && $6 && $6.suggestKeywords && !$7 && !$8 && !$9 && !$10) {
-         keywords = keywords.concat($6.suggestKeywords); // Get the last optional from SKEWED BY
-       }
-       if (!$7 && !$8 && !$9 && !$10) {
-         keywords.push('ROW FORMAT');
-         keywords.push('STORED AS');
-         if (isHive()) {
-          keywords.push('STORED BY');
-         }
-       } else if ($7 && $7.suggestKeywords && !$8 && !$9 && !$10) {
-         keywords = keywords.concat($7.suggestKeywords);
-       }
-       if (!$8 && !$9 && !$10) {
-         keywords.push('LOCATION');
-       }
-       if (!$9 && !$10) {
-         keywords.push('TBLPROPERTIES');
-       }
-       if (isImpala() && !$10) {
-         keywords.push('CACHED IN');
-       }
-     }
-
-     if (keywords.length > 0) {
-       suggestKeywords(keywords);
-     }
-   }
- ;
-
-TableIdentifierAndOptionalColumnSpecification
- : SchemaQualifiedTableIdentifier OptionalColumnSpecificationsOrLike  -> $2
- ;
-
-TableIdentifierAndOptionalColumnSpecification_EDIT
- : SchemaQualifiedTableIdentifier OptionalColumnSpecificationsOrLike_EDIT
- ;
-
-DropLastLocation
- : /* Empty */
-   {
-     if (parser.yy.locations.length > 0) {
-       parser.yy.locations.pop();
-     }
-   }
- ;
-
-OptionalHiveTemporary
- :
- | '<hive>TEMPORARY'
- ;
-
-OptionalExternal
- :
- | '<hive>EXTERNAL'
- | '<impala>EXTERNAL'
- ;
-
-OptionalColumnSpecificationsOrLike
- :
- | ParenthesizedColumnSpecificationList
- | '<impala>LIKE_PARQUET' HdfsPath
- | 'LIKE' SchemaQualifiedTableIdentifier
- ;
-
-OptionalColumnSpecificationsOrLike_EDIT
- : ParenthesizedColumnSpecificationList_EDIT
- | '<impala>LIKE_PARQUET' HdfsPath_EDIT
- | 'LIKE' 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
-     if (isImpala()) {
-       suggestKeywords(['PARQUET']);
-     }
-   }
- | 'LIKE' SchemaQualifiedTableIdentifier_EDIT
- ;
-
-ParenthesizedColumnSpecificationList
- : '(' ColumnSpecificationList ')'
- ;
-
-ParenthesizedColumnSpecificationList_EDIT
- : '(' ColumnSpecificationList_EDIT RightParenthesisOrError
- ;
-
-ColumnSpecificationList
- : ColumnSpecification
- | ColumnSpecificationList ',' ColumnSpecification
- ;
-
-ColumnSpecificationList_EDIT
- : ColumnSpecification_EDIT
- | ColumnSpecification_EDIT ',' ColumnSpecificationList
- | ColumnSpecificationList ',' ColumnSpecification_EDIT
- | ColumnSpecificationList ',' ColumnSpecification_EDIT ',' ColumnSpecificationList
- ;
-
-ColumnSpecification
- : ColumnIdentifier ColumnDataType OptionalComment
- ;
-
-ColumnSpecification_EDIT
- : ColumnIdentifier 'CURSOR' OptionalComment
-   {
-     suggestKeywords(getColumnDataTypeKeywords());
-   }
- | ColumnIdentifier ColumnDataType_EDIT
- | ColumnIdentifier ColumnDataType OptionalComment 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['COMMENT']);
-     }
-   }
- ;
-
-ColumnDataType
- : PrimitiveType
- | ArrayType
- | MapType
- | StructType
- | UnionType
- | ArrayType_INVALID
- | MapType_INVALID
- | StructType_INVALID
- | UnionType_INVALID
- ;
-
-ColumnDataType_EDIT
- : ArrayType_EDIT
- | MapType_EDIT
- | StructType_EDIT
- | UnionType_EDIT
- ;
-
-ArrayType
- : '<hive>ARRAY' '<' ColumnDataType '>'
- ;
-
-ArrayType_INVALID
- : '<hive>ARRAY' '<' '>'
- ;
-
-ArrayType_EDIT
- : '<hive>ARRAY' '<' AnyCursor GreaterThanOrError
-   {
-     suggestKeywords(getColumnDataTypeKeywords());
-   }
- | '<hive>ARRAY' '<' ColumnDataType_EDIT GreaterThanOrError
- ;
-
-MapType
- : '<hive>MAP' '<' PrimitiveType ',' ColumnDataType '>'
- ;
-
-MapType_INVALID
- : '<hive>MAP' '<' '>'
- ;
-
-MapType_EDIT
- : '<hive>MAP' '<' PrimitiveType ',' ColumnDataType_EDIT GreaterThanOrError
- | '<hive>MAP' '<' AnyCursor GreaterThanOrError
-   {
-     suggestKeywords(getTypeKeywords());
-   }
- | '<hive>MAP' '<' PrimitiveType ',' AnyCursor GreaterThanOrError
-   {
-     suggestKeywords(getColumnDataTypeKeywords());
-   }
- | '<hive>MAP' '<' ',' AnyCursor GreaterThanOrError
-   {
-     suggestKeywords(getColumnDataTypeKeywords());
-   }
- ;
-
-StructType
- : '<hive>STRUCT' '<' StructDefinitionList '>'
- ;
-
-StructType_INVALID
- : '<hive>STRUCT' '<' '>'
- ;
-
-StructType_EDIT
- : '<hive>STRUCT' '<' StructDefinitionList_EDIT GreaterThanOrError
- ;
-
-StructDefinitionList
- : StructDefinition
- | StructDefinitionList ',' StructDefinition
- ;
-
-StructDefinitionList_EDIT
- : StructDefinition_EDIT
- | StructDefinition_EDIT Commas
- | StructDefinition_EDIT Commas StructDefinitionList
- | StructDefinitionList ',' StructDefinition_EDIT
- | StructDefinitionList ',' StructDefinition_EDIT Commas StructDefinitionList
- ;
-
-Commas
- : ','
- | Commas ','
- ;
-
-StructDefinition
- : RegularOrBacktickedIdentifier ':' ColumnDataType OptionalComment
- ;
-
-StructDefinition_EDIT
- : Commas RegularOrBacktickedIdentifier ':' ColumnDataType 'CURSOR'
-   {
-     suggestKeywords(['COMMENT']);
-   }
- | Commas RegularOrBacktickedIdentifier ':' AnyCursor
-   {
-     suggestKeywords(getColumnDataTypeKeywords());
-   }
- | Commas RegularOrBacktickedIdentifier ':' ColumnDataType_EDIT
- | RegularOrBacktickedIdentifier ':' ColumnDataType 'CURSOR'
-   {
-     suggestKeywords(['COMMENT']);
-   }
- | RegularOrBacktickedIdentifier ':' AnyCursor
-   {
-     suggestKeywords(getColumnDataTypeKeywords());
-   }
- | RegularOrBacktickedIdentifier ':' ColumnDataType_EDIT
- ;
-
-UnionType
- : '<hive>UNIONTYPE' '<' ColumnDataTypeList '>'
- ;
-
-UnionType_INVALID
- : '<hive>UNIONTYPE' '<' '>'
- ;
-
-UnionType_EDIT
- : '<hive>UNIONTYPE' '<' ColumnDataTypeList_EDIT GreaterThanOrError
- ;
-
-ColumnDataTypeList
- : ColumnDataType
- | ColumnDataTypeList ',' ColumnDataType
- ;
-
-ColumnDataTypeList_EDIT
- : ColumnDataTypeListInner_EDIT
- | ColumnDataTypeListInner_EDIT Commas
- | ColumnDataTypeList ',' ColumnDataTypeListInner_EDIT
- | ColumnDataTypeListInner_EDIT Commas ColumnDataTypeList
- | ColumnDataTypeList ',' ColumnDataTypeListInner_EDIT Commas ColumnDataTypeList
- ;
-
-ColumnDataTypeListInner_EDIT
- : Commas AnyCursor
-   {
-     suggestKeywords(getColumnDataTypeKeywords());
-   }
- | Commas ColumnDataType_EDIT
- | AnyCursor
-   {
-     suggestKeywords(getColumnDataTypeKeywords());
-   }
- | ColumnDataType_EDIT
- ;
-
-GreaterThanOrError
- : '>'
- | error
- ;
-
-OptionalPartitionedBy
- :
- | HiveOrImpalaPartitioned 'BY' ParenthesizedColumnSpecificationList
- ;
-
-OptionalPartitionedBy_EDIT
- : HiveOrImpalaPartitioned 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- | HiveOrImpalaPartitioned 'CURSOR' ParenthesizedColumnSpecificationList
-   {
-     suggestKeywords(['BY']);
-   }
- | HiveOrImpalaPartitioned 'BY' ParenthesizedColumnSpecificationList_EDIT
- | HiveOrImpalaPartitioned ParenthesizedColumnSpecificationList_EDIT
- ;
-
-ParenthesizedColumnList
- : '(' ColumnList ')'
- ;
-
-ColumnList
- : ColumnIdentifier
- | ColumnList ',' ColumnIdentifier
- ;
-
-OptionalHiveClusteredBy
- :
- | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList OptionalHiveSortedBy 'INTO' 'UNSIGNED_INTEGER' '<hive>BUCKETS'
- ;
-
-OptionalHiveClusteredBy_EDIT
- : '<hive>CLUSTERED' 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList OptionalHiveSortedBy 'CURSOR'
-   {
-     if (!$4) {
-       suggestKeywords(['INTO', 'SORTED BY']);
-     } else {
-       suggestKeywords(['INTO']);
-     }
-   }
- | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList OptionalHiveSortedBy 'INTO' 'UNSIGNED_INTEGER' 'CURSOR'
-   {
-     suggestKeywords(['BUCKETS']);
-   }
- | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList OptionalHiveSortedBy_EDIT 'INTO' 'UNSIGNED_INTEGER' '<hive>BUCKETS'
- | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList OptionalHiveSortedBy_EDIT
- ;
-
-OptionalHiveSortedBy
- :
- | '<hive>SORTED' 'BY' ParenthesizedSortList
- ;
-
-OptionalHiveSortedBy_EDIT
- : '<hive>SORTED' 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- | '<hive>SORTED' 'BY' ParenthesizedSortList_EDIT
- ;
-
-ParenthesizedSortList
- : '(' SortList ')'
- ;
-
-ParenthesizedSortList_EDIT
- : '(' SortList_EDIT RightParenthesisOrError
- ;
-
-SortList
- : SortIdentifier
- | SortList ',' SortIdentifier
- ;
-
-SortList_EDIT
- : SortIdentifier_EDIT
- | SortIdentifier_EDIT ',' SortList
- | SortList ',' SortIdentifier_EDIT
- | SortList ',' SortIdentifier_EDIT ',' SortList
- ;
-
-SortIdentifier
- : ColumnIdentifier OptionalAscOrDesc
- ;
-
-SortIdentifier_EDIT
- : ColumnIdentifier OptionalAscOrDesc 'CURSOR'
-   {
-     checkForKeywords($2);
-   }
- ;
-
-
-OptionalHiveSkewedBy
- :
- | '<hive>SKEWED' 'BY' ParenthesizedColumnList ON ParenthesizedSkewedValueList  -> { suggestKeywords: ['STORED AS DIRECTORIES'] }
- | '<hive>SKEWED' 'BY' ParenthesizedColumnList ON ParenthesizedSkewedValueList '<hive>STORED_AS_DIRECTORIES' // Hack otherwise ambiguous with OptionalHiveStoredAsOrBy
- ;
-
-OptionalHiveSkewedBy_EDIT
- : '<hive>SKEWED' 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- | '<hive>SKEWED' 'BY' ParenthesizedColumnList 'CURSOR'
-   {
-     suggestKeywords(['ON']);
-   }
- ;
-
-ParenthesizedSkewedValueList
- : '(' SkewedValueList ')'
- ;
-
-SkewedValueList
- : ParenthesizedSimpleValueList
- | SkewedValueList ',' ParenthesizedSimpleValueList
- ;
-
-ParenthesizedSimpleValueList
- : '(' SimpleValueList ')'
- ;
-
-SimpleValueList
- : UnsignedValueSpecification
- | SimpleValueList ',' UnsignedValueSpecification
- ;
-
-OptionalStoredAsOrBy
- :
- | StoredAs
- | 'ROW' HiveOrImpalaFormat HiveOrImpalaRowFormat OptionalStoredAs
-   {
-     $$ = mergeSuggestKeywords($3, $4)
-   }
- | '<hive>STORED' 'BY' QuotedValue OptionalHiveWithSerdeproperties
-  {
-    if (!$4) {
-      $$ = { suggestKeywords: ['WITH SERDEPROPERTIES'] };
-    }
-  }
- ;
-
-OptionalStoredAsOrBy_EDIT
- : HiveOrImpalaStored 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['AS', 'BY']);
-     } else {
-       suggestKeywords(['AS']);
-     }
-   }
- | StoredAs_EDIT
- | 'ROW' 'CURSOR'
-   {
-     suggestKeywords(['FORMAT']);
-   }
- | 'ROW' HiveOrImpalaFormat 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['DELIMITED', 'SERDE']);
-     } else {
-       suggestKeywords(['DELIMITED']);
-     }
-   }
- | 'ROW' HiveOrImpalaFormat HiveOrImpalaRowFormat_EDIT
- | 'ROW' HiveOrImpalaFormat HiveOrImpalaRowFormat HiveOrImpalaStored 'CURSOR'
-   {
-     suggestKeywords(['AS']);
-   }
- | 'ROW' HiveOrImpalaFormat HiveOrImpalaRowFormat StoredAs_EDIT
- | '<hive>STORED' 'BY' QuotedValue OptionalHiveWithSerdeproperties_EDIT
- ;
-
-OptionalStoredAs
- :           -> { suggestKeywords: ['STORED AS'] }
- | StoredAs
- ;
-
-StoredAs
- : HiveOrImpalaStored AnyAs FileFormat
- ;
-
-StoredAs_EDIT
- : HiveOrImpalaStored AnyAs 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['AVRO', 'INPUTFORMAT', 'ORC', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
-     } else {
-       suggestKeywords(['AVRO', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
-     }
-   }
- ;
-
-HiveOrImpalaFormat
- : '<hive>FORMAT'
- | '<impala>FORMAT'
- ;
-
-HiveOrImpalaStored
- : '<hive>STORED'
- | '<impala>STORED'
- ;
-
-FileFormat
- : '<hive>AVRO'
- | '<hive>INPUTFORMAT' QuotedValue '<hive>OUTPUTFORMAT' QuotedValue
- | '<hive>ORC'
- | '<hive>PARQUET'
- | '<hive>RCFILE'
- | '<hive>SEQUENCEFILE'
- | '<hive>TEXTFILE'
- | '<impala>AVRO'
- | '<impala>PARQUET'
- | '<impala>RCFILE'
- | '<impala>SEQUENCEFILE'
- | '<impala>TEXTFILE'
- ;
-
-HiveOrImpalaRowFormat
- : HiveRowFormat
- | ImpalaRowFormat
- ;
-
-HiveOrImpalaRowFormat_EDIT
- : ImpalaRowFormat_EDIT
- | HiveRowFormat_EDIT
- ;
-
-HiveRowFormat
- : '<hive>DELIMITED' OptionalFieldsTerminatedBy OptionalCollectionItemsTerminatedBy OptionalMapKeysTerminatedBy
-   OptionalLinesTerminatedBy OptionalNullDefinedAs
-   {
-     if (!$2 && !$3 && !$4 && !$5 && !$6) {
-       $$ = { suggestKeywords: ['COLLECTION ITEMS TERMINATED BY', 'FIELDS TERMINATED BY', 'LINES TERMINATED BY', 'MAP KEYS TERMINATED BY', 'NULL DEFINED AS'] };
-     } else if ($2 && $2.suggestKeywords && !$3 && !$4 && !$5 && !$6) {
-       $$ = { suggestKeywords: $2.suggestKeywords.concat(['COLLECTION ITEMS TERMINATED BY', 'LINES TERMINATED BY', 'MAP KEYS TERMINATED BY', 'NULL DEFINED AS']) };
-     } else if (!$3 && !$4 && !$5 && !$6) {
-       $$ = { suggestKeywords: ['COLLECTION ITEMS TERMINATED BY', 'LINES TERMINATED BY', 'MAP KEYS TERMINATED BY', 'NULL DEFINED AS'] };
-     } else if (!$4 && !$5 && !$6) {
-       $$ = { suggestKeywords: ['LINES TERMINATED BY', 'MAP KEYS TERMINATED BY', 'NULL DEFINED AS'] };
-     } else if (!$5 && !$6) {
-       $$ = { suggestKeywords: ['LINES TERMINATED BY', 'NULL DEFINED AS'] };
-     } else if (!$6) {
-       $$ = { suggestKeywords: ['NULL DEFINED AS'] };
-     }
-   }
- | '<hive>SERDE' QuotedValue OptionalHiveWithSerdeproperties
-   {
-     if (!$3) {
-       $$ = { suggestKeywords: ['WITH SERDEPROPERTIES'] };
-     }
-   }
- ;
-
-HiveRowFormat_EDIT
- : '<hive>DELIMITED' OptionalFieldsTerminatedBy_EDIT OptionalCollectionItemsTerminatedBy OptionalMapKeysTerminatedBy
-   OptionalLinesTerminatedBy OptionalNullDefinedAs
- | '<hive>DELIMITED' OptionalFieldsTerminatedBy OptionalCollectionItemsTerminatedBy_EDIT OptionalMapKeysTerminatedBy
-   OptionalLinesTerminatedBy OptionalNullDefinedAs
- | '<hive>DELIMITED' OptionalFieldsTerminatedBy OptionalCollectionItemsTerminatedBy OptionalMapKeysTerminatedBy_EDIT
-   OptionalLinesTerminatedBy OptionalNullDefinedAs
- | '<hive>DELIMITED' OptionalFieldsTerminatedBy OptionalCollectionItemsTerminatedBy OptionalMapKeysTerminatedBy
-   OptionalLinesTerminatedBy_EDIT OptionalNullDefinedAs
- | '<hive>DELIMITED' OptionalFieldsTerminatedBy OptionalCollectionItemsTerminatedBy OptionalMapKeysTerminatedBy
-   OptionalLinesTerminatedBy OptionalNullDefinedAs_EDIT
- ;
-
-ImpalaRowFormat
- : '<impala>DELIMITED' OptionalFieldsTerminatedBy OptionalLinesTerminatedBy
-   {
-     if (!$2 && !$3) {
-       $$ = { suggestKeywords: ['FIELDS TERMINATED BY', 'LINES TERMINATED BY'] };
-     } else if ($2 && $2.suggestKeywords && !$3) {
-       $$ = { suggestKeywords: $2.suggestKeywords.concat(['LINES TERMINATED BY']) };
-     } else if (!$3) {
-       $$ = { suggestKeywords: ['LINES TERMINATED BY'] };
-     }
-   }
- ;
-
-ImpalaRowFormat_EDIT
- : '<impala>DELIMITED' OptionalFieldsTerminatedBy_EDIT OptionalLinesTerminatedBy
- | '<impala>DELIMITED' OptionalFieldsTerminatedBy OptionalLinesTerminatedBy_EDIT
- ;
-
-OptionalFieldsTerminatedBy
- :
- | HiveOrImpalaFields HiveOrImpalaTerminated 'BY' SingleQuotedValue  -> { suggestKeywords: ['ESCAPED BY'] }
- | HiveOrImpalaFields HiveOrImpalaTerminated 'BY' SingleQuotedValue HiveOrImpalaEscaped 'BY' SingleQuotedValue
- ;
-
-OptionalFieldsTerminatedBy_EDIT
- : HiveOrImpalaFields 'CURSOR'
-   {
-     suggestKeywords(['TERMINATED BY']);
-   }
- | HiveOrImpalaFields HiveOrImpalaTerminated 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- | HiveOrImpalaFields HiveOrImpalaTerminated 'BY' SingleQuotedValue 'ESCAPED' 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- ;
-
-HiveOrImpalaFields
- : '<hive>FIELDS'
- | '<impala>FIELDS'
- ;
-
-HiveOrImpalaTerminated
- : '<hive>TERMINATED'
- | '<impala>TERMINATED'
- ;
-
-HiveOrImpalaEscaped
- : '<hive>ESCAPED'
- | '<impala>ESCAPED'
- ;
-
-OptionalCollectionItemsTerminatedBy
- :
- | '<hive>COLLECTION' '<hive>ITEMS' '<hive>TERMINATED' 'BY' SingleQuotedValue
- ;
-
-OptionalCollectionItemsTerminatedBy_EDIT
- : '<hive>COLLECTION' 'CURSOR'
-   {
-     suggestKeywords(['ITEMS TERMINATED BY']);
-   }
- | '<hive>COLLECTION' '<hive>ITEMS' 'CURSOR'
-   {
-     suggestKeywords(['TERMINATED BY']);
-   }
- | '<hive>COLLECTION' '<hive>ITEMS' '<hive>TERMINATED' 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- ;
-
-OptionalMapKeysTerminatedBy
- :
- | '<hive>MAP' '<hive>KEYS' '<hive>TERMINATED' 'BY' SingleQuotedValue
- ;
-
-OptionalMapKeysTerminatedBy_EDIT
- : '<hive>MAP' 'CURSOR'
-   {
-     suggestKeywords(['KEYS TERMINATED BY']);
-   }
- | '<hive>MAP' '<hive>KEYS' 'CURSOR'
-   {
-     suggestKeywords(['TERMINATED BY']);
-   }
- | '<hive>MAP' '<hive>KEYS' '<hive>TERMINATED' 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- ;
-
-OptionalLinesTerminatedBy
- :
- | HiveOrImpalaLines HiveOrImpalaTerminated 'BY' SingleQuotedValue
- ;
-
-OptionalLinesTerminatedBy_EDIT
- : HiveOrImpalaLines 'CURSOR'
-   {
-     suggestKeywords(['TERMINATED BY']);
-   }
- | HiveOrImpalaLines HiveOrImpalaTerminated 'CURSOR'
-   {
-     suggestKeywords(['BY']);
-   }
- ;
-
-HiveOrImpalaLines
- : '<hive>LINES'
- | '<impala>LINES'
- ;
-
-OptionalNullDefinedAs
- :
- | 'NULL' '<hive>DEFINED' '<hive>AS' SingleQuotedValue
- ;
-
-OptionalNullDefinedAs_EDIT
- : 'NULL' 'CURSOR'
-   {
-     suggestKeywords(['DEFINED AS']);
-   }
- | 'NULL' '<hive>DEFINED' 'CURSOR'
-   {
-     suggestKeywords(['AS']);
-   }
- ;
-
-OptionalHiveWithSerdeproperties
- :
- | 'WITH' '<hive>SERDEPROPERTIES' ParenthesizedPropertyAssignmentList
- ;
-
-OptionalHiveWithSerdeproperties_EDIT
- : OptionalImpalaWithSerdeproperties_EDIT
- ;
-
-OptionalImpalaWithSerdeproperties
- :
- | 'WITH' '<impala>SERDEPROPERTIES' ParenthesizedPropertyAssignmentList
- ;
-
-OptionalImpalaWithSerdeproperties_EDIT
- : 'WITH' 'CURSOR'
-   {
-     suggestKeywords(['SERDEPROPERTIES']);
-   }
- | 'WITH' 'CURSOR' ParenthesizedPropertyAssignmentList
-   {
-     suggestKeywords(['SERDEPROPERTIES']);
-   }
- ;
-
-OptionalTblproperties
- :
- | HiveOrImpalaTblproperties ParenthesizedPropertyAssignmentList
- ;
-
-OptionalAsSelectStatement
- :
- | AnyAs CommitLocations QuerySpecification
- ;
-
-OptionalAsSelectStatement_EDIT
- : AnyAs CommitLocations 'CURSOR'
-   {
-     suggestKeywords(['SELECT']);
-   }
- | AnyAs CommitLocations QuerySpecification_EDIT
- ;
-
-CommitLocations
- : /* empty */
-   {
-     commitLocations();
-   }
- ;
-
-OptionalImpalaCachedIn
- :
- | '<impala>CACHED' 'IN' QuotedValue
- ;
-
-OptionalImpalaCachedIn_EDIT
- : '<impala>CACHED' 'CURSOR'
-   {
-     suggestKeywords(['IN']);
-   }
- ;
-
-QuotedValue
- : SingleQuotedValue
- | DoubleQuotedValue
- ;
-
-HiveOrImpalaTblproperties
- : '<hive>TBLPROPERTIES'
- | '<impala>TBLPROPERTIES'
- ;
-
-HiveOrImpalaPartitioned
- : '<hive>PARTITIONED'
- | '<impala>PARTITIONED'
- ;// 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
- : ShowStatement
- ;
-
-DataDefinition_EDIT
- : ShowStatement_EDIT
- ;
-
-ShowStatement
- : ShowColumnStatsStatement
- | ShowColumnsStatement
- | ShowCompactionsStatement
- | ShowConfStatement
- | ShowCreateTableStatement
- | ShowCurrentRolesStatement
- | ShowDatabasesStatement
- | ShowFunctionsStatement
- | ShowGrantStatement
- | ShowIndexStatement
- | ShowLocksStatement
- | ShowPartitionsStatement
- | ShowRoleStatement
- | ShowRolesStatement
- | ShowTableStatement
- | ShowTablesStatement
- | ShowTblPropertiesStatement
- | ShowTransactionsStatement
- ;
-
-AnyShow
- : 'SHOW'
- | '<hive>SHOW'
- ;
-
-ShowStatement_EDIT
- : AnyShow 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['COLUMNS', 'COMPACTIONS', 'CONF', 'CREATE TABLE', 'CURRENT ROLES', 'DATABASES', 'FORMATTED', 'FUNCTIONS', 'GRANT', 'INDEX', 'INDEXES', 'LOCKS', 'PARTITIONS', 'PRINCIPALS', 'ROLE GRANT', 'ROLES', 'SCHEMAS', 'TABLE EXTENDED', 'TABLES', 'TBLPROPERTIES', 'TRANSACTIONS']);
-     } else if (isImpala()) {
-       suggestKeywords(['AGGREGATE FUNCTIONS', 'ANALYTIC FUNCTIONS', 'COLUMN STATS', 'CREATE TABLE', 'CURRENT ROLES', 'DATABASES', 'FUNCTIONS', 'GRANT ROLE', 'PARTITIONS', 'ROLE GRANT GROUP', 'ROLES', 'SCHEMAS', 'TABLE STATS', 'TABLES']);
-     } else {
-       suggestKeywords(['COLUMNS', 'DATABASES', 'TABLES']);
-     }
-   }
- | AnyShow 'CURSOR' RegularOrBackTickedSchemaQualifiedName
-   {
-     // ROLES is considered a non-reserved keywords so we can't match it in ShowCurrentRolesStatement_EDIT
-     if ($3.identifierChain && $3.identifierChain.length === 1 && $3.identifierChain[0].name.toLowerCase() === 'roles') {
-       suggestKeywords(['CURRENT']);
-     } else {
-       addTablePrimary($3);
-       if (isImpala()) {
-         suggestKeywords(['COLUMN STATS', 'CREATE TABLE', 'PARTITIONS', 'TABLE STATS']);
-       }
-     }
-   }
- | AnyShow 'CURSOR' LIKE SingleQuotedValue
-   {
-     if (isImpala()) {
-       suggestKeywords(['AGGREGATE FUNCTIONS', 'ANALYTIC FUNCTIONS', 'DATABASES', 'FUNCTIONS', 'SCHEMAS', 'TABLES']);
-     } else if (isHive()) {
-       suggestKeywords(['DATABASES', 'SCHEMAS', 'TABLE EXTENDED']);
-     }
-   }
- | ShowColumnStatsStatement_EDIT
- | ShowColumnsStatement_EDIT
- | ShowCreateTableStatement_EDIT
- | ShowCurrentRolesStatement_EDIT
- | ShowDatabasesStatement_EDIT
- | ShowFunctionsStatement_EDIT
- | ShowGrantStatement_EDIT
- | ShowIndexStatement_EDIT
- | ShowLocksStatement_EDIT
- | ShowPartitionsStatement_EDIT
- | ShowRoleStatement_EDIT
- | ShowTableStatement_EDIT
- | ShowTablesStatement_EDIT
- | ShowTblPropertiesStatement_EDIT
- ;
-
-ShowColumnStatsStatement
- : AnyShow '<impala>COLUMN' '<impala>STATS' RegularOrBackTickedSchemaQualifiedName
-   {
-     addTablePrimary($4);
-   }
- ;
-
-ShowColumnStatsStatement_EDIT
- : AnyShow '<impala>COLUMN' 'CURSOR'
-   {
-     suggestKeywords(['STATS']);
-   }
- | AnyShow '<impala>COLUMN' '<impala>STATS' 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-   }
- | AnyShow '<impala>COLUMN' '<impala>STATS' RegularOrBackTickedSchemaQualifiedName_EDIT
- ;
-
-ShowColumnsStatement
- : AnyShow '<hive>COLUMNS' AnyFromOrIn RegularOrBacktickedIdentifier
- | AnyShow '<hive>COLUMNS' AnyFromOrIn RegularOrBacktickedIdentifier AnyFromOrIn RegularOrBacktickedIdentifier
- ;
-
-ShowColumnsStatement_EDIT
- : AnyShow '<hive>COLUMNS' 'CURSOR'
-   {
-     suggestKeywords(['FROM', 'IN']);
-   }
- | AnyShow '<hive>COLUMNS' 'CURSOR' RegularOrBacktickedIdentifier
-   {
-     suggestKeywords(['FROM', 'IN']);
-   }
- | AnyShow '<hive>COLUMNS' AnyFromOrIn 'CURSOR'
-   {
-     suggestTables();
-   }
- | AnyShow '<hive>COLUMNS' AnyFromOrIn 'CURSOR' AnyFromOrIn
-   {
-     suggestTables();
-   }
- | AnyShow '<hive>COLUMNS' AnyFromOrIn 'CURSOR' AnyFromOrIn RegularOrBacktickedIdentifier
-   {
-     suggestTables();
-   }
- | AnyShow '<hive>COLUMNS' AnyFromOrIn RegularOrBacktickedIdentifier 'CURSOR'
-   {
-     suggestKeywords(['FROM', 'IN']);
-   }
- | AnyShow '<hive>COLUMNS' AnyFromOrIn RegularOrBacktickedIdentifier 'CURSOR' RegularOrBacktickedIdentifier
-   {
-     suggestKeywords(['FROM', 'IN']);
-   }
- | AnyShow '<hive>COLUMNS' AnyFromOrIn RegularOrBacktickedIdentifier AnyFromOrIn 'CURSOR'
-   {
-     suggestDatabases();
-   }
- ;
-
-ShowCompactionsStatement
- : AnyShow '<hive>COMPACTIONS'
- ;
-
-ShowConfStatement
- : AnyShow '<hive>CONF' ConfigurationName
- ;
-
-ShowCreateTableStatement
- : AnyShow HiveOrImpalaCreate AnyTable RegularOrBackTickedSchemaQualifiedName
-   {
-     addTablePrimary($4);
-   }
- ;
-
-ShowCreateTableStatement_EDIT
- : AnyShow HiveOrImpalaCreate 'CURSOR'
-   {
-     suggestKeywords(['TABLE']);
-   }
- | AnyShow HiveOrImpalaCreate AnyTable 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-   }
- | AnyShow HiveOrImpalaCreate AnyTable RegularOrBackTickedSchemaQualifiedName_EDIT
- | AnyShow HiveOrImpalaCreate 'CURSOR' RegularOrBackTickedSchemaQualifiedName
-   {
-     addTablePrimary($4);
-     suggestKeywords(['TABLE']);
-   }
- ;
-
-ShowCurrentRolesStatement
- : AnyShow '<hive>CURRENT' '<hive>ROLES'
- | AnyShow '<impala>CURRENT' '<impala>ROLES'
- ;
-
-ShowCurrentRolesStatement_EDIT
- : AnyShow '<hive>CURRENT' 'CURSOR'
-   {
-     suggestKeywords([ 'ROLES' ]);
-   }
- | AnyShow '<impala>CURRENT' 'CURSOR'
-   {
-     suggestKeywords([ 'ROLES' ]);
-   }
- ;
-
-ShowDatabasesStatement
- : AnyShow HiveOrImpalaDatabasesOrSchemas 'LIKE' SingleQuotedValue
- | AnyShow '<impala>DATABASES' SingleQuotedValue
- ;
-
-ShowDatabasesStatement_EDIT
- : AnyShow HiveOrImpalaDatabasesOrSchemas 'CURSOR'
-   {
-     suggestKeywords(['LIKE']);
-   }
- ;
-
-ShowFunctionsStatement
- : AnyShow '<hive>FUNCTIONS'
- | AnyShow '<hive>FUNCTIONS' DoubleQuotedValue
- | AnyShow OptionalAggregateOrAnalytic '<impala>FUNCTIONS' OptionalInDatabase
- | AnyShow OptionalAggregateOrAnalytic '<impala>FUNCTIONS' OptionalInDatabase 'LIKE' SingleQuoteValue
- ;
-
-ShowFunctionsStatement_EDIT
- : AnyShow AggregateOrAnalytic 'CURSOR'
-   {
-     suggestKeywords(['FUNCTIONS']);
-   }
- | AnyShow 'CURSOR' '<impala>FUNCTIONS' OptionalInDatabase
-   {
-     suggestKeywords(['AGGREGATE', 'ANALYTICAL']);
-   }
- | AnyShow OptionalAggregateOrAnalytic '<impala>FUNCTIONS' OptionalInDatabase 'CURSOR'
-   {
-     if (!$4) {
-       suggestKeywords(['IN', 'LIKE']);
-     } else {
-       suggestKeywords(['LIKE']);
-     }
-   }
- | AnyShow AggregateOrAnalytic 'CURSOR' OptionalInDatabase 'LIKE' SingleQuoteValue
-   {
-     suggestKeywords(['FUNCTIONS']);
-   }
- | AnyShow 'CURSOR' '<impala>FUNCTIONS' OptionalInDatabase 'LIKE' SingleQuoteValue
-   {
-     suggestKeywords(['AGGREGATE', 'ANALYTICAL']);
-   }
- | AnyShow OptionalAggregateOrAnalytic '<impala>FUNCTIONS' OptionalInDatabase 'CURSOR' SingleQuoteValue
-   {
-     if (!$4) {
-       suggestKeywords(['IN', 'LIKE']);
-     } else {
-       suggestKeywords(['LIKE']);
-     }
-   }
- ;
-
-ShowGrantStatement
- : AnyShow '<hive>GRANT' OptionalPrincipalName
- | AnyShow '<hive>GRANT' OptionalPrincipalName 'ON' '<hive>ALL'
- | AnyShow '<hive>GRANT' OptionalPrincipalName 'ON' RegularOrBacktickedIdentifier
- | AnyShow '<hive>GRANT' OptionalPrincipalName 'ON' AnyTable RegularOrBacktickedIdentifier
- ;
-
-ShowGrantStatement_EDIT
- : AnyShow '<hive>GRANT' OptionalPrincipalName_EDIT
-   {
-     suggestKeywords(['ON']);
-   }
- | AnyShow '<hive>GRANT' OptionalPrincipalName_EDIT 'ON' '<hive>ALL'
- | AnyShow '<hive>GRANT' OptionalPrincipalName 'ON' 'CURSOR'
-   {
-     suggestKeywords(['ALL', 'TABLE']);
-     suggestTables();
-   }
- | AnyShow  '<hive>GRANT' OptionalPrincipalName 'ON' AnyTable 'CURSOR'
-   {
-     suggestTables();
-   }
- | AnyShow '<hive>GRANT' OptionalPrincipalName 'ON' 'CURSOR' RegularOrBacktickedIdentifier
-   {
-     suggestKeywords(['TABLE']);
-   }
- | AnyShow '<impala>GRANT' 'CURSOR'
-   {
-     suggestKeywords(['ROLE']);
-   }
- ;
-
-OptionalPrincipalName
- :
- | RegularIdentifier
- ;
-
-OptionalPrincipalName_EDIT
- : 'CURSOR'
- | RegularIdentifier 'CURSOR'
- ;
-
-ShowIndexStatement
- : AnyShow OptionallyFormattedIndex 'ON' RegularOrBacktickedIdentifier
- | AnyShow OptionallyFormattedIndex 'ON' RegularOrBacktickedIdentifier AnyFromOrIn RegularOrBacktickedIdentifier
- ;
-
-ShowIndexStatement_EDIT
- : AnyShow OptionallyFormattedIndex
- | AnyShow OptionallyFormattedIndex_EDIT
- | AnyShow OptionallyFormattedIndex_EDIT 'ON' RegularOrBacktickedIdentifier
- | AnyShow OptionallyFormattedIndex_EDIT 'ON' RegularOrBacktickedIdentifier AnyFromOrIn RegularOrBacktickedIdentifier
- | AnyShow OptionallyFormattedIndex 'CURSOR'
-   {
-     suggestKeywords(['ON']);
-   }
- | AnyShow OptionallyFormattedIndex 'ON' 'CURSOR'
-   {
-     suggestTables();
-   }
- | AnyShow OptionallyFormattedIndex 'CURSOR' RegularOrBacktickedIdentifier
-   {
-     suggestKeywords(['ON']);
-   }
- | AnyShow OptionallyFormattedIndex 'ON' RegularOrBacktickedIdentifier 'CURSOR'
-   {
-     suggestKeywords(['FROM', 'IN']);
-   }
- | AnyShow OptionallyFormattedIndex 'ON' RegularOrBacktickedIdentifier 'CURSOR' RegularOrBacktickedIdentifier
-   {
-     suggestKeywords(['FROM', 'IN']);
-   }
- | AnyShow OptionallyFormattedIndex 'ON' RegularOrBacktickedIdentifier AnyFromOrIn 'CURSOR'
-   {
-     suggestDatabases();
-   }
- | AnyShow OptionallyFormattedIndex 'ON' 'CURSOR' AnyFromOrIn RegularOrBacktickedIdentifier
-   {
-     suggestTablesOrColumns($6);
-   }
- ;
-
-ShowLocksStatement
- : AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName
-   {
-     addTablePrimary($3);
-   }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName '<hive>EXTENDED'
-   {
-     addTablePrimary($3);
-   }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName 'PARTITION' '(' PartitionSpecList ')'
-   {
-     addTablePrimary($3);
-   }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName 'PARTITION' '(' PartitionSpecList ')' '<hive>EXTENDED'
-   {
-     addTablePrimary($3);
-   }
- | AnyShow '<hive>LOCKS' DatabaseOrSchema RegularOrBacktickedIdentifier
- ;
-
-ShowLocksStatement_EDIT
- : AnyShow '<hive>LOCKS' 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-     suggestKeywords(['DATABASE', 'SCHEMA']);
-   }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName 'CURSOR'
-    {
-      addTablePrimary($3);
-      suggestKeywords(['EXTENDED', 'PARTITION']);
-    }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT '<hive>EXTENDED'
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT 'PARTITION' '(' PartitionSpecList ')'
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName 'PARTITION' '(' PartitionSpecList ')' 'CURSOR'
-   {
-     addTablePrimary($3);
-     suggestKeywords(['EXTENDED']);
-   }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT 'PARTITION' '(' PartitionSpecList ')' '<hive>EXTENDED'
- | AnyShow '<hive>LOCKS' DatabaseOrSchema 'CURSOR'
-   {
-     suggestDatabases();
-   }
- ;
-
-ShowPartitionsStatement
- : AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName
-   {
-     addTablePrimary($3);
-   }
- | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName 'PARTITION' PartitionSpecList
-   {
-     addTablePrimary($3);
-   }
- | AnyShow '<impala>PARTITIONS' RegularOrBackTickedSchemaQualifiedName
-   {
-     addTablePrimary($3);
-   }
- ;
-
-ShowPartitionsStatement_EDIT
- : AnyShow '<hive>PARTITIONS' 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-   }
- | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName_EDIT
- | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName 'CURSOR'
-   {
-     addTablePrimary($3);
-     suggestKeywords(['PARTITION']);
-   }
- | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName_EDIT 'PARTITION' PartitionSpecList
- | AnyShow '<impala>PARTITIONS' 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-   }
- | AnyShow '<impala>PARTITIONS' RegularOrBackTickedSchemaQualifiedName_EDIT
- ;
-
-ShowRoleStatement
- : AnyShow '<hive>ROLE' '<hive>GRANT' HiveRoleOrUser RegularIdentifier
- | AnyShow '<impala>ROLE' '<impala>GRANT' '<impala>GROUP' RegularIdentifier
- ;
-
-ShowRoleStatement_EDIT
- : AnyShow '<hive>ROLE' 'CURSOR'
-   {
-     suggestKeywords(['GRANT']);
-   }
- | AnyShow '<impala>ROLE' 'CURSOR'
-   {
-     suggestKeywords(['GRANT']);
-   }
- | AnyShow '<hive>ROLE' 'CURSOR' HiveRoleOrUser RegularIdentifier
-   {
-     suggestKeywords(['GRANT']);
-   }
- | AnyShow '<hive>ROLE' '<hive>GRANT' 'CURSOR'
-   {
-     suggestKeywords(['ROLE', 'USER']);
-   }
- | AnyShow '<hive>ROLE' '<hive>GRANT' 'CURSOR' RegularIdentifier
-   {
-     suggestKeywords(['ROLE', 'USER']);
-   }
- | AnyShow '<impala>ROLE' '<impala>GRANT' 'CURSOR'
-   {
-     suggestKeywords(['GROUP']);
-   }
- | AnyShow '<impala>ROLE' '<impala>GRANT' 'CURSOR' RegularIdentifier
-   {
-     suggestKeywords(['GROUP']);
-   }
- ;
-
-ShowRolesStatement
- : AnyShow '<impala>ROLES'
- | AnyShow '<hive>ROLES'
- ;
-
-ShowTableStatement
- : AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue 'PARTITION' PartitionSpecList
- ;
-
-ShowTableStatement_EDIT
- : AnyShow '<hive>TABLE' 'CURSOR'
-   {
-     suggestKeywords(['EXTENDED']);
-   }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase_EDIT
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'CURSOR'
-    {
-      if ($4) {
-        suggestKeywords(['LIKE']);
-      } else {
-        suggestKeywords(['FROM', 'IN', 'LIKE']);
-      }
-    }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase_EDIT 'LIKE' SingleQuotedValue
- | AnyShow '<hive>TABLE' 'CURSOR' OptionalFromDatabase 'LIKE' SingleQuotedValue
-    {
-      if (isHive()) {
-        suggestKeywords(['EXTENDED']);
-      }
-    }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'CURSOR' SingleQuotedValue
-    {
-      suggestKeywords(['LIKE']);
-    }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue 'CURSOR'
-    {
-      suggestKeywords(['PARTITION']);
-    }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase_EDIT 'LIKE' SingleQuotedValue 'PARTITION' PartitionSpecList
- | AnyShow '<hive>TABLE' 'CURSOR' OptionalFromDatabase 'LIKE' SingleQuotedValue 'PARTITION' PartitionSpecList
-   {
-     suggestKeywords(['EXTENDED']);
-   }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'CURSOR' SingleQuotedValue 'PARTITION' PartitionSpecList
-   {
-     suggestKeywords(['LIKE']);
-   }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue 'CURSOR' PartitionSpecList
-   {
-     suggestKeywords(['PARTITION']);
-   }
- | AnyShow '<impala>TABLE' 'CURSOR'
-   {
-     suggestKeywords(['STATS']);
-   }
- | AnyShow '<impala>TABLE' '<impala>STATS' 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-   }
- | AnyShow '<impala>TABLE' '<impala>STATS' RegularOrBackTickedSchemaQualifiedName
-    {
-      addTablePrimary($4);
-    }
- | AnyShow '<impala>TABLE' '<impala>STATS' RegularOrBackTickedSchemaQualifiedName_EDIT
- ;
-
-ShowTablesStatement
- : AnyShow HiveOrImpalaTables OptionalInDatabase
- | AnyShow HiveOrImpalaTables OptionalInDatabase SingleQuotedValue
- | AnyShow HiveOrImpalaTables OptionalInDatabase 'LIKE' SingleQuotedValue
- ;
-
-ShowTablesStatement_EDIT
- : AnyShow HiveOrImpalaTables OptionalInDatabase 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['IN', 'LIKE']);
-     } else {
-       suggestKeywords(['LIKE']);
-     }
-   }
- ;
-
-ShowTblPropertiesStatement
- : AnyShow '<hive>TBLPROPERTIES' RegularOrBackTickedSchemaQualifiedName
-   {
-     addTablePrimary($3);
-   }
- ;
-
-ShowTblPropertiesStatement_EDIT
- : AnyShow '<hive>TBLPROPERTIES' RegularOrBackTickedSchemaQualifiedName_EDIT
- | AnyShow '<hive>TBLPROPERTIES' 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({ prependDot: true });
-   }
- ;
-
-ShowTransactionsStatement
- : AnyShow '<hive>TRANSACTIONS'
- ;// 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 OptionalWhereClause
- ;
-
-UpdateStatement_EDIT
- : 'UPDATE' TargetTable_EDIT 'SET' SetClauseList OptionalWhereClause
- | 'UPDATE' TargetTable 'SET' SetClauseList_EDIT OptionalWhereClause
- | 'UPDATE' TargetTable 'SET' SetClauseList OptionalWhereClause_EDIT
- | 'UPDATE' TargetTable 'SET' SetClauseList OptionalWhereClause 'CURSOR'
-   {
-     if (!$5) {
-       suggestKeywords([ 'WHERE' ]);
-     }
-   }
- | 'UPDATE' TargetTable 'CURSOR'
-   {
-     suggestKeywords([ 'SET' ]);
-   }
- | 'UPDATE' TargetTable_EDIT
- | 'UPDATE' TargetTable
- | 'UPDATE' 'CURSOR'
-   {
-     suggestTables();
-     suggestDatabases({ appendDot: true });
-   }
- ;
-
-TargetTable
- : TableName
- ;
-
-TargetTable_EDIT
- : TableName_EDIT
- ;
-
-TableName
- : LocalOrSchemaQualifiedName
-   {
-     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'
-   {
-     suggestKeywords([ '=' ]);
-   }
- | 'CURSOR'
-   {
-     suggestColumns();
-   }
- ;
-
-SetTarget
- : ColumnReference
- ;
-
-UpdateSource
- : ValueExpression
- ;
-
-UpdateSource_EDIT
- : ValueExpression_EDIT
- ;// 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
- : UseStatement
- ;
-
-DataDefinition_EDIT
- : UseStatement_EDIT
- ;
-
-AnyUse
- : 'USE'
- | '<hive>USE'
- ;
-
-UseStatement
- : AnyUse RegularIdentifier
-   {
-     if (! parser.yy.cursorFound) {
-       parser.yy.result.useDatabase = $2;
-     }
-   }
- ;
-
-UseStatement_EDIT
- : AnyUse 'CURSOR'
-   {
-     suggestDatabases();
-   }
- ;
-
-
-// ===================================== Fin =====================================
-%%
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-var prepareNewStatement = function () {
-  linkTablePrimaries();
-  commitLocations();
-
-  delete parser.yy.latestTablePrimaries;
-  delete parser.yy.correlatedSubQuery;
-  parser.yy.subQueries = [];
-
-  parser.parseError = function (message, error) {
-    parser.yy.errors.push(error);
-    return message;
-  };
-};
-
-var popQueryState = function (subQuery) {
-  linkTablePrimaries();
-  commitLocations();
-
-  if (Object.keys(parser.yy.result).length === 0) {
-    parser.yy.result = parser.yy.resultStack.pop();
-  } else {
-    parser.yy.resultStack.pop();
-  }
-  var oldSubQueries = parser.yy.subQueries;
-  parser.yy.subQueries = parser.yy.subQueriesStack.pop();
-  if (subQuery) {
-    if (oldSubQueries.length > 0) {
-      subQuery.subQueries = oldSubQueries;
-    }
-    parser.yy.subQueries.push(subQuery);
-  }
-
-  parser.yy.latestTablePrimaries = parser.yy.primariesStack.pop();
-  parser.yy.locations = parser.yy.locationsStack.pop();
-};
-
-var isHive = function () {
-  return parser.yy.activeDialect === 'hive';
-};
-
-var isImpala = function () {
-  return parser.yy.activeDialect === 'impala';
-};
-
-var mergeSuggestKeywords = function () {
-  var result = [];
-  Array.prototype.slice.call(arguments).forEach(function (suggestion) {
-    if (typeof suggestion !== 'undefined' && typeof suggestion.suggestKeywords !== 'undefined') {
-      result = result.concat(suggestion.suggestKeywords);
-    }
-  });
-  if (result.length > 0) {
-    return {suggestKeywords: result};
-  }
-  return {};
-};
-
-var suggestValueExpressionKeywords = function (valueExpression, extras) {
-  var expressionKeywords = getValueExpressionKeywords(valueExpression, extras);
-  suggestKeywords(expressionKeywords.suggestKeywords);
-  if (expressionKeywords.suggestColRefKeywords) {
-    suggestColRefKeywords(expressionKeywords.suggestColRefKeywords);
-  }
-  if (valueExpression.lastType) {
-    addColRefIfExists(valueExpression.lastType);
-  } else {
-    addColRefIfExists(valueExpression);
-  }
-};
-
-var getValueExpressionKeywords = function (valueExpression, extras) {
-  var types = valueExpression.lastType ? valueExpression.lastType.types : valueExpression.types;
-  // We could have valueExpression.columnReference to suggest based on column type
-  var keywords = ['<', '<=', '<>', '=', '>', '>=', 'BETWEEN', 'IN', 'IS NOT NULL', 'IS NULL', 'NOT BETWEEN', 'NOT IN'];
-  if (isHive()) {
-    keywords.push('<=>');
-  }
-  if (extras) {
-    keywords = keywords.concat(extras);
-  }
-  if (valueExpression.suggestKeywords) {
-    keywords = keywords.concat(valueExpression.suggestKeywords);
-  }
-  if (types.length === 1 && types[0] === 'COLREF') {
-    return {
-      suggestKeywords: keywords,
-      suggestColRefKeywords: {
-        BOOLEAN: ['AND', 'OR'],
-        NUMBER: ['+', '-', '*', '/', '%'],
-        STRING: ['LIKE', 'NOT LIKE', 'REGEX', 'RLIKE']
-      }
-    }
-  }
-  if (parser.yy.sqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
-    keywords = keywords.concat(['AND', 'OR']);
-  }
-  if (parser.yy.sqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
-    keywords = keywords.concat(['+', '-', '*', '/', '%']);
-  }
-  if (parser.yy.sqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)) {
-    keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEX', 'RLIKE']);
-  }
-  return {suggestKeywords: keywords};
-};
-
-var getTypeKeywords = function () {
-  if (isHive()) {
-    return ['BIGINT', 'BINARY', 'BOOLEAN', 'CHAR', 'DATE', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
-  }
-  if (isImpala()) {
-    return ['BIGINT', 'BOOLEAN', 'CHAR', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'REAL', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
-  }
-  return ['BIGINT', 'BOOLEAN', 'CHAR', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR'];
-};
-
-var getColumnDataTypeKeywords = function () {
-  if (isHive()) {
-    return getTypeKeywords().concat(['ARRAY<>', 'MAP<>', 'STRUCT<>', 'UNIONTYPE<>']);
-  }
-  return getTypeKeywords();
-};
-
-var addColRefIfExists = function (valueExpression) {
-  if (valueExpression.columnReference) {
-    parser.yy.result.colRef = {identifierChain: valueExpression.columnReference};
-  }
-};
-
-var valueExpressionSuggest = function (oppositeValueExpression) {
-  if (oppositeValueExpression && oppositeValueExpression.columnReference) {
-    suggestValues();
-    parser.yy.result.colRef = {identifierChain: oppositeValueExpression.columnReference};
-  }
-  suggestColumns();
-  suggestFunctions();
-  if (oppositeValueExpression && oppositeValueExpression.types[0] === 'NUMBER') {
-    applyTypeToSuggestions(['NUMBER']);
-  }
-};
-
-var applyTypeToSuggestions = function (types) {
-  if (types[0] === 'BOOLEAN') {
-    return;
-  }
-  if (parser.yy.result.suggestFunctions) {
-    parser.yy.result.suggestFunctions.types = types;
-  }
-  if (parser.yy.result.suggestColumns) {
-    parser.yy.result.suggestColumns.types = types;
-  }
-};
-
-var findCaseType = function (whenThenList) {
-  var types = {};
-  whenThenList.caseTypes.forEach(function (valueExpression) {
-    valueExpression.types.forEach(function (type) {
-      types[type] = true;
-    });
-  });
-  if (Object.keys(types).length === 1) {
-    return {types: [Object.keys(types)[0]]};
-  }
-  return {types: ['T']};
-};
-
-findReturnTypes = function (functionName) {
-  return parser.yy.sqlFunctions.getReturnTypes(parser.yy.activeDialect, functionName.toLowerCase());
-};
-
-var applyArgumentTypesToSuggestions = function (functionName, position) {
-  var foundArguments = parser.yy.sqlFunctions.getArgumentTypes(parser.yy.activeDialect, functionName.toLowerCase(), position);
-  if (foundArguments.length == 0 && parser.yy.result.suggestColumns) {
-    delete parser.yy.result.suggestColumns;
-    delete parser.yy.result.suggestKeyValues;
-    delete parser.yy.result.suggestValues;
-    delete parser.yy.result.suggestFunctions;
-    delete parser.yy.result.suggestIdentifiers;
-  } else {
-    applyTypeToSuggestions(foundArguments);
-  }
-};
-
-var commitLocations = function () {
-  var i = parser.yy.locations.length;
-  while (i--) {
-    var location = parser.yy.locations[i];
-    expandIdentifierChain(location);
-    // 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) {
-      location.type = 'column';
-    }
-    if (location.type === 'table' && typeof location.table === 'undefined') {
-      parser.yy.locations.splice(i, 1);
-    }
-    if (location.type === 'column' && (typeof location.table === 'undefined' || typeof location.identifierChain === 'undefined')) {
-      parser.yy.locations.splice(i, 1);
-    }
-  }
-  if (parser.yy.locations.length > 0) {
-    parser.yy.allLocations = parser.yy.allLocations.concat(parser.yy.locations);
-    parser.yy.locations = [];
-  }
-};
-
-var prioritizeSuggestions = function () {
-  parser.yy.result.lowerCase = parser.yy.lowerCase || false;
-  if (typeof parser.yy.result.colRef !== 'undefined') {
-    if (typeof parser.yy.result.colRef.table === 'undefined') {
-      delete parser.yy.result.colRef;
-      if (typeof parser.yy.result.suggestColRefKeywords !== 'undefined') {
-        Object.keys(parser.yy.result.suggestColRefKeywords).forEach(function (type) {
-          parser.yy.result.suggestKeywords = parser.yy.result.suggestKeywords.concat(parser.yy.result.suggestColRefKeywords[type]);
-        });
-        delete parser.yy.result.suggestColRefKeywords;
-      }
-      if (parser.yy.result.suggestColumns && parser.yy.result.suggestColumns.types.length === 1 && parser.yy.result.suggestColumns.types[0] === 'COLREF') {
-        parser.yy.result.suggestColumns.types = ['T'];
-      }
-      delete parser.yy.result.suggestValues;
-    }
-  }
-
-  if (typeof parser.yy.result.colRef !== 'undefined') {
-    if (!parser.yy.result.suggestValues && !parser.yy.result.suggestColRefKeywords &&
-        (!parser.yy.result.suggestColumns ||
-        parser.yy.result.suggestColumns.types[0] !== 'COLREF')) {
-      delete parser.yy.result.colRef;
-    }
-  }
-  if (typeof parser.yy.result.suggestIdentifiers !== 'undefined' && parser.yy.result.suggestIdentifiers.length > 0) {
-    delete parser.yy.result.suggestTables;
-    delete parser.yy.result.suggestDatabases;
-  } else if (typeof parser.yy.result.suggestColumns !== 'undefined') {
-    if (typeof parser.yy.result.suggestColumns.table === 'undefined' && typeof parser.yy.result.suggestColumns.subQuery === 'undefined') {
-      delete parser.yy.result.suggestColumns;
-      delete parser.yy.result.subQueries;
-    } else {
-      if (typeof parser.yy.result.suggestColumns.subQuery === 'undefined') {
-        delete parser.yy.result.subQueries;
-      }
-      delete parser.yy.result.suggestTables;
-      delete parser.yy.result.suggestDatabases;
-      if (typeof parser.yy.result.suggestColumns.identifierChain !== 'undefined' && parser.yy.result.suggestColumns.identifierChain.length === 0) {
-        delete parser.yy.result.suggestColumns.identifierChain;
-      }
-    }
-  } else {
-    delete parser.yy.result.subQueries;
-  }
-};
-
-/**
- * Impala supports referencing maps and arrays in the the table reference list i.e.
- *
- *  SELECT m['foo'].bar.| FROM someDb.someTable t, t.someMap m;
- *
- * From this the tablePrimaries would look like:
- *
- * [ { alias: 't', identifierChain: [ { name: 'someDb' }, { name: 'someTable' } ] },
- *   { alias: 'm', identifierChain: [ { name: 't' }, { name: 'someMap' } ] } ]
- *
- * with an identifierChain from the select list:
- *
- * [ { name: 'm', keySet: true }, { name: 'bar' } ]
- *
- * Calling this would return an expanded identifierChain, given the above it would be:
- *
- * [ { name: 't' }, { name: 'someMap', keySet: true }, { name: 'bar' } ]
- */
-parser.expandImpalaIdentifierChain = function (tablePrimaries, identifierChain) {
-  var expandedChain = identifierChain.concat(); // Clone in case it's called multiple times.
-  if (typeof expandedChain === 'undefined' || expandedChain.length === 0) {
-    return identifierChain;
-  }
-
-  var expand = function (identifier, expandedChain) {
-    var foundPrimary = tablePrimaries.filter(function (tablePrimary) {
-      return tablePrimary.alias === identifier;
-    });
-
-    if (foundPrimary.length === 1 && foundPrimary[0].identifierChain) {
-      var parentPrimary = tablePrimaries.filter(function (tablePrimary) {
-        return tablePrimary.alias === foundPrimary[0].identifierChain[0].name;
-      });
-      if (parentPrimary.length === 1) {
-        var keySet = expandedChain[0].keySet;
-        var secondPart = expandedChain.slice(1);
-        var firstPart = [];
-        // Clone to make sure we don't add keySet to the primaries
-        foundPrimary[0].identifierChain.forEach(function (identifier) {
-          firstPart.push({name: identifier.name});
-        });
-        if (keySet && firstPart.length > 0) {
-          firstPart[firstPart.length - 1].keySet = true;
-        }
-
-        var result = firstPart.concat(secondPart);
-        if (result.length > 0) {
-          return expand(firstPart[0].name, result);
-        } else {
-          return result;
-        }
-      }
-    }
-    return expandedChain;
-  };
-  return expand(expandedChain[0].name, expandedChain);
-};
-
-parser.identifyPartials = function (beforeCursor, afterCursor) {
-  var beforeMatch = beforeCursor.match(/[0-9a-zA-Z_]*$/);
-  var afterMatch = afterCursor.match(/^[0-9a-zA-Z_]*/);
-  return {left: beforeMatch ? beforeMatch[0].length : 0, right: afterMatch ? afterMatch[0].length : 0};
-};
-
-parser.expandLateralViews = function (tablePrimaries, originalIdentifierChain) {
-  var identifierChain = originalIdentifierChain.concat(); // Clone in case it's re-used
-  var firstIdentifier = identifierChain[0];
-  tablePrimaries.forEach(function (tablePrimary) {
-    if (typeof tablePrimary.lateralViews !== 'undefined') {
-      tablePrimary.lateralViews.concat().reverse().forEach(function (lateralView) {
-        if (!lateralView.udtf.expression.columnReference) {
-          return;
-        }
-        if (firstIdentifier.name === lateralView.tableAlias && identifierChain.length > 1) {
-          identifierChain.shift();
-          firstIdentifier = identifierChain[0];
-        } else if (firstIdentifier.name === lateralView.tableAlias && identifierChain.length === 1 && typeof parser.yy.result.suggestColumns !== 'undefined') {
-          if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
-            parser.yy.result.suggestIdentifiers = [];
-          }
-          lateralView.columnAliases.forEach(function (columnAlias) {
-            parser.yy.result.suggestIdentifiers.push({name: columnAlias, type: 'alias'});
-          });
-          delete parser.yy.result.suggestColumns;
-          return identifierChain;
-        }
-        if (lateralView.columnAliases.indexOf(firstIdentifier.name) !== -1) {
-          if (lateralView.columnAliases.length === 2 && lateralView.udtf.function.toLowerCase() === 'explode' && firstIdentifier.name === lateralView.columnAliases[0]) {
-            identifierChain[0] = {name: 'key'};
-          } else if (lateralView.columnAliases.length === 2 && lateralView.udtf.function.toLowerCase() === 'explode' && firstIdentifier.name === lateralView.columnAliases[1]) {
-            identifierChain[0] = {name: 'value'};
-          } else {
-            identifierChain[0] = {name: 'item'};
-          }
-          identifierChain = lateralView.udtf.expression.columnReference.concat(identifierChain);
-          firstIdentifier = identifierChain[0];
-        }
-      });
-    }
-  });
-  return identifierChain;
-};
-
-var expandIdentifierChain = function (wrapper) {
-  if (typeof wrapper.identifierChain === 'undefined' || typeof parser.yy.latestTablePrimaries === 'undefined') {
-    return;
-  }
-
-  var identifierChain = wrapper.identifierChain.concat();
-  var tablePrimaries = parser.yy.latestTablePrimaries;
-
-  if (identifierChain.length > 0 && identifierChain[identifierChain.length - 1].asterisk) {
-    var tables = [];
-    tablePrimaries.forEach(function (tablePrimary) {
-      if (tablePrimary.identifierChain && tablePrimary.identifierChain.length == 1) {
-        tables.push({table: tablePrimary.identifierChain[0].name});
-      } else if (tablePrimary.identifierChain && tablePrimary.identifierChain.length == 2) {
-        tables.push({database: tablePrimary.identifierChain[0].name, table: tablePrimary.identifierChain[1].name});
-      }
-    });
-    // Possible Joins
-    if (tables.length > 1) {
-      wrapper.tables = tables;
-      delete wrapper.identifierChain;
-      return;
-    } else if (tables.length === 1) {
-      if (tables[0].database) {
-        wrapper.database = tables[0].database;
-      }
-      wrapper.table = tables[0].table;
-      delete wrapper.identifierChain;
-      return;
-    }
-  }
-
-  // Impala can have references to maps or array, i.e. FROM table t, t.map m
-  // We need to replace those in the identifierChain
-  if (isImpala()) {
-    identifierChain = parser.expandImpalaIdentifierChain(tablePrimaries, identifierChain);
-    wrapper.identifierChain = identifierChain;
-  }
-  // Expand exploded views in the identifier chain
-  if (isHive() && identifierChain.length > 0) {
-    identifierChain = parser.expandLateralViews(tablePrimaries, identifierChain);
-    wrapper.identifierChain = identifierChain;
-  }
-
-  // IdentifierChain contains a possibly started identifier or empty, example: a.b.c = ['a', 'b', 'c']
-  // Reduce the tablePrimaries to the one that matches the first identifier if found
-  if (identifierChain.length > 0) {
-    var foundTable = tablePrimaries.filter(function (tablePrimary) {
-      return identifierChain[0].name === tablePrimary.alias || identifierChain[0].name === tablePrimary.subQueryAlias;
-    });
-
-    var dbAndTable = false;
-    if (foundTable.length === 0) {
-      // Give priority to the ones that match both DB and table
-      if (identifierChain.length > 1) {
-        foundTable = tablePrimaries.filter(function (tablePrimary) {
-          return tablePrimary.identifierChain && tablePrimary.identifierChain.length > 1 &&
-              tablePrimary.identifierChain[0].name === identifierChain[0].name &&
-              tablePrimary.identifierChain[1].name === identifierChain[1].name;
-        });
-        dbAndTable = foundTable.length > 0;
-      }
-      if (foundTable.length == 0) {
-        foundTable = tablePrimaries.filter(function (tablePrimary) {
-          return tablePrimary.identifierChain && tablePrimary.identifierChain.length > 0 &&
-              tablePrimary.identifierChain[0].name === identifierChain[0].name;
-        });
-      }
-    }
-
-    if (foundTable.length === 1) {
-      tablePrimaries = foundTable;
-      identifierChain.shift();
-      if (dbAndTable) {
-        identifierChain.shift();
-      }
-      wrapper.identifierChain = identifierChain;
-    }
-  }
-
-  if (identifierChain.length == 0) {
-    delete wrapper.identifierChain;
-  }
-
-  if (tablePrimaries.length === 1) {
-    if (typeof tablePrimaries[0].identifierChain !== 'undefined') {
-      if (tablePrimaries[0].identifierChain.length == 2) {
-        wrapper.database = tablePrimaries[0].identifierChain[0].name;
-        wrapper.table = tablePrimaries[0].identifierChain[1].name;
-      } else {
-        wrapper.table = tablePrimaries[0].identifierChain[0].name;
-      }
-    } else if (tablePrimaries[0].subQueryAlias !== 'undefined') {
-      wrapper.subQuery = tablePrimaries[0].subQueryAlias;
-    }
-  }
-  wrapper.linked = true;
-};
-
-var suggestTablePrimariesAsIdentifiers = function () {
-  if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
-    parser.yy.result.suggestIdentifiers = [];
-  }
-  parser.yy.latestTablePrimaries.forEach(function (tablePrimary) {
-    if (typeof tablePrimary.alias !== 'undefined') {
-      parser.yy.result.suggestIdentifiers.push({name: tablePrimary.alias + '.', type: 'alias'});
-    } else if (typeof tablePrimary.identifierChain !== 'undefined' && tablePrimary.identifierChain.length == 2) {
-      parser.yy.result.suggestIdentifiers.push({
-        name: tablePrimary.identifierChain[0].name + '.' + tablePrimary.identifierChain[1].name + '.',
-        type: 'table'
-      });
-    } else if (typeof tablePrimary.identifierChain !== 'undefined') {
-      parser.yy.result.suggestIdentifiers.push({name: tablePrimary.identifierChain[0].name + '.', type: 'table'});
-    } else if (typeof tablePrimary.subQueryAlias !== 'undefined') {
-      parser.yy.result.suggestIdentifiers.push({name: tablePrimary.subQueryAlias + '.', type: 'sub-query'});
-    }
-  });
-  if (parser.yy.result.suggestIdentifiers.length === 0) {
-    delete parser.yy.result.suggestIdentifiers;
-  }
-};
-
-var suggestLateralViewAliasesAsIdentifiers = function () {
-  if (typeof parser.yy.result.suggestIdentifiers === 'undefined') {
-    parser.yy.result.suggestIdentifiers = [];
-  }
-  parser.yy.latestTablePrimaries.forEach(function (tablePrimary) {
-    if (typeof tablePrimary.lateralViews !== 'undefined') {
-      tablePrimary.lateralViews.forEach(function (lateralView) {
-        if (typeof lateralView.tableAlias !== 'undefined') {
-          parser.yy.result.suggestIdentifiers.push({name: lateralView.tableAlias + '.', type: 'alias'});
-        }
-        lateralView.columnAliases.forEach(function (columnAlias) {
-          parser.yy.result.suggestIdentifiers.push({name: columnAlias, type: 'alias'});
-        });
-      });
-    }
-  });
-  if (parser.yy.result.suggestIdentifiers.length === 0) {
-    delete parser.yy.result.suggestIdentifiers;
-  }
-};
-
-var linkTablePrimaries = function () {
-  if (!parser.yy.cursorFound || typeof parser.yy.latestTablePrimaries === 'undefined') {
-    return;
-  }
-  if (typeof parser.yy.result.suggestColumns !== 'undefined' && !parser.yy.result.suggestColumns.linked) {
-    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) {
-        suggestTablePrimariesAsIdentifiers();
-        delete parser.yy.result.suggestColumns;
-      } else {
-        suggestLateralViewAliasesAsIdentifiers();
-        if (parser.yy.latestTablePrimaries.length == 1 && (parser.yy.latestTablePrimaries[0].alias || parser.yy.latestTablePrimaries[0].subQueryAlias)) {
-          suggestTablePrimariesAsIdentifiers();
-        }
-        expandIdentifierChain(parser.yy.result.suggestColumns);
-      }
-    } else {
-      expandIdentifierChain(parser.yy.result.suggestColumns);
-    }
-  }
-  if (typeof parser.yy.result.colRef !== 'undefined' && !parser.yy.result.colRef.linked) {
-    expandIdentifierChain(parser.yy.result.colRef);
-  }
-  if (typeof parser.yy.result.suggestKeyValues !== 'undefined' && !parser.yy.result.suggestKeyValues.linked) {
-    expandIdentifierChain(parser.yy.result.suggestKeyValues);
-  }
-};
-
-var getSubQuery = function (cols) {
-  var columns = [];
-  cols.selectList.forEach(function (col) {
-    var result = {};
-    if (col.alias) {
-      result.alias = col.alias;
-    }
-    if (col.valueExpression && col.valueExpression.columnReference) {
-      result.identifierChain = col.valueExpression.columnReference
-    } else if (col.asterisk) {
-      result.identifierChain = [{asterisk: true}];
-    }
-    if (col.valueExpression && col.valueExpression.types && col.valueExpression.types.length === 1) {
-      result.type = col.valueExpression.types[0];
-    }
-
-    columns.push(result);
-  });
-
-  return {
-    columns: columns
-  };
-};
-
-var addTablePrimary = function (ref) {
-  if (typeof parser.yy.latestTablePrimaries === 'undefined') {
-    parser.yy.latestTablePrimaries = [];
-  }
-  parser.yy.latestTablePrimaries.push(ref);
-};
-
-var suggestNumbers = function (numbers) {
-  parser.yy.result.suggestNumbers = numbers;
-};
-
-var suggestDdlAndDmlKeywords = function () {
-  var keywords = ['ALTER', 'CREATE', 'DELETE', 'DESCRIBE', 'DROP', 'EXPLAIN', 'INSERT', 'REVOKE', 'SELECT', 'SET', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE'];
-
-  if (isHive()) {
-    keywords = keywords.concat(['ANALYZE', 'EXPORT', 'IMPORT', 'LOAD', 'MSCK', 'RESET']);
-  }
-
-  if (isImpala()) {
-    keywords = keywords.concat(['COMPUTE', 'INVALIDATE', 'LOAD', 'REFRESH']);
-  }
-
-  suggestKeywords(keywords);
-};
-
-var checkForSelectListKeywords = function (selectList) {
-  if (selectList.length === 0) {
-    return;
-  }
-  var last = selectList[selectList.length - 1];
-  if (!last || !last.valueExpression) {
-    return;
-  }
-  var valueExpressionKeywords = getValueExpressionKeywords(last.valueExpression);
-  var keywords = [];
-  if (last.suggestKeywords) {
-    keywords = keywords.concat(last.suggestKeywords);
-  }
-  if (valueExpressionKeywords.suggestKeywords) {
-    keywords = keywords.concat(valueExpressionKeywords.suggestKeywords);
-  }
-  if (valueExpressionKeywords.suggestColRefKeywords) {
-    suggestColRefKeywords(valueExpressionKeywords.suggestColRefKeywords);
-    addColRefIfExists(last.valueExpression);
-  }
-  if (!last.alias) {
-    keywords.push('AS');
-  }
-  if (keywords.length > 0) {
-    suggestKeywords(keywords);
-  }
-};
-
-var checkForKeywords = function (expression) {
-  if (expression) {
-    if (expression.suggestKeywords && expression.suggestKeywords.length > 0) {
-      suggestKeywords(expression.suggestKeywords);
-    }
-    if (expression.suggestColRefKeywords) {
-      suggestColRefKeywords(expression.suggestColRefKeywords)
-      addColRefIfExists(expression);
-    }
-  }
-};
-
-var suggestKeywords = function (keywords) {
-  parser.yy.result.suggestKeywords = keywords.sort();
-};
-
-var suggestColRefKeywords = function (colRefKeywords) {
-  parser.yy.result.suggestColRefKeywords = colRefKeywords;
-};
-
-var suggestTablesOrColumns = function (identifier) {
-  if (typeof parser.yy.latestTablePrimaries == 'undefined') {
-    suggestTables({database: identifier});
-    return;
-  }
-  var tableRef = parser.yy.latestTablePrimaries.filter(function (tablePrimary) {
-    return tablePrimary.alias === identifier;
-  });
-  if (tableRef.length > 0) {
-    suggestColumns({identifierChain: [{name: identifier}]});
-  } else {
-    suggestTables({database: identifier});
-  }
-};
-
-var suggestFunctions = function (details) {
-  parser.yy.result.suggestFunctions = details || {};
-};
-
-var suggestAggregateFunctions = function () {
-  parser.yy.result.suggestAggregateFunctions = true;
-};
-
-var suggestAnalyticFunctions = function () {
-  parser.yy.result.suggestAnalyticFunctions = true;
-};
-
-var suggestColumns = function (details) {
-  if (typeof details === 'undefined') {
-    details = {identifierChain: []};
-  } else if (typeof details.identifierChain === 'undefined') {
-    details.identifierChain = [];
-  }
-  parser.yy.result.suggestColumns = details;
-};
-
-var suggestKeyValues = function (details) {
-  parser.yy.result.suggestKeyValues = details || {};
-};
-
-var suggestTables = function (details) {
-  parser.yy.result.suggestTables = details || {};
-};
-
-var adjustLocationForCursor = function (location) {
-  // columns are 0-based and lines not, so add 1 to cols
-  var newLocation = {
-    first_line: location.first_line,
-    last_line: location.last_line,
-    first_column: location.first_column + 1,
-    last_column: location.last_column + 1
-  };
-  if (parser.yy.cursorFound) {
-    if (parser.yy.cursorFound.first_line === newLocation.first_line && parser.yy.cursorFound.last_column <= newLocation.first_column) {
-      var additionalSpace = parser.yy.partialLengths.left + parser.yy.partialLengths.right;
-      additionalSpace -= parser.yy.partialCursor ? 1 : 3; // For some reason the normal cursor eats 3 positions.
-      newLocation.first_column = newLocation.first_column + additionalSpace;
-      newLocation.last_column = newLocation.last_column + additionalSpace;
-    }
-  }
-  return newLocation;
-};
-
-var addFunctionLocation = function (location, functionName) {
-  // Remove trailing '(' from location
-  var adjustedLocation = {
-    first_line: location.first_line,
-    last_line: location.last_line,
-    first_column: location.first_column,
-    last_column: location.last_column - 1
-  };
-  parser.yy.locations.push({
-    type: 'function',
-    location: adjustLocationForCursor(adjustedLocation),
-    function: functionName.toLowerCase()
-  });
-};
-
-var addDatabaseLocation = function (location, database) {
-  parser.yy.locations.push({type: 'database', location: adjustLocationForCursor(location), database: database});
-};
-
-var addTableLocation = function (location, identifierChain) {
-  parser.yy.locations.push({
-    type: 'table',
-    location: adjustLocationForCursor(location),
-    identifierChain: identifierChain
-  });
-};
-
-var addColumnLocation = function (location, identifierChain) {
-  parser.yy.locations.push({
-    type: 'column',
-    location: adjustLocationForCursor(location),
-    identifierChain: identifierChain
-  });
-};
-
-var suggestDatabases = function (details) {
-  parser.yy.result.suggestDatabases = details || {};
-};
-
-var suggestHdfs = function (details) {
-  parser.yy.result.suggestHdfs = details || {};
-};
-
-var suggestValues = function (details) {
-  parser.yy.result.suggestValues = true;
-};
-
-var determineCase = function (text) {
-  parser.yy.lowerCase = text.toLowerCase() === text;
-};
-
-var lexerModified = false;
-
-/**
- * Main parser function
- */
-parser.parseSql = function (beforeCursor, afterCursor, dialect, sqlFunctions, debug) {
-  parser.yy.sqlFunctions = sqlFunctions;
-  parser.yy.result = {locations: []};
-  parser.yy.lowerCase = false;
-  parser.yy.locations = [];
-  parser.yy.allLocations = [];
-  parser.yy.subQueries = [];
-  parser.yy.errors = [];
-
-  delete parser.yy.cursorFound;
-  delete parser.yy.partialCursor;
-
-  prepareNewStatement();
-
-  parser.yy.partialLengths = parser.identifyPartials(beforeCursor, afterCursor);
-
-  if (parser.yy.partialLengths.left > 0) {
-    beforeCursor = beforeCursor.substring(0, beforeCursor.length - parser.yy.partialLengths.left);
-  }
-
-  if (parser.yy.partialLengths.right > 0) {
-    afterCursor = afterCursor.substring(parser.yy.partialLengths.right);
-  }
-
-  parser.yy.activeDialect = (dialect !== 'hive' && dialect !== 'impala') ? undefined : dialect;
-
-  // Hack to set the inital state of the lexer without first having to hit a token
-  // has to be done as the first token found can be dependant on dialect
-  if (!lexerModified) {
-    var originalSetInput = parser.lexer.setInput;
-    parser.lexer.setInput = function (input, yy) {
-      var lexer = originalSetInput.bind(parser.lexer)(input, yy);
-      if (typeof parser.yy.activeDialect !== 'undefined') {
-        lexer.begin(parser.yy.activeDialect);
-      }
-      return lexer;
-    };
-    lexerModified = true;
-  }
-
-  var result;
-  try {
-    // Add |CURSOR| or |PARTIAL_CURSOR| to represent the different cursor states in the lexer
-    result = parser.parse(beforeCursor + (beforeCursor.length == 0 || /.*\s+$/.test(beforeCursor) ? ' \u2020 ' : '\u2021') + afterCursor);
-  } catch (err) {
-    // On any error try to at least return any existing result
-    if (typeof parser.yy.result === 'undefined') {
-      throw err;
-    }
-    if (debug) {
-      console.log(err);
-      console.error(err.stack);
-    }
-    result = parser.yy.result;
-  }
-  if (parser.yy.errors.length > 0) {
-    parser.yy.result.errors = parser.yy.errors;
-    if (debug) {
-      console.log(parser.yy.errors);
-    }
-  }
-  linkTablePrimaries();
-  commitLocations();
-
-  // Clean up and prioritize
-  parser.yy.allLocations.sort(function (a, b) {
-    if (a.location.first_line !== b.location.first_line) {
-      return a.location.first_line - b.location.first_line;
-    }
-    return a.location.first_column - b.location.first_column;
-  });
-  parser.yy.result.locations = parser.yy.allLocations;
-
-  parser.yy.result.locations.forEach(function (location) {
-    delete location.linked;
-  });
-  if (typeof parser.yy.result.suggestColumns !== 'undefined') {
-    delete parser.yy.result.suggestColumns.linked;
-  }
-  if (typeof parser.yy.result.colRef !== 'undefined') {
-    delete parser.yy.result.colRef.linked;
-  }
-  if (typeof parser.yy.result.suggestKeyValues !== 'undefined') {
-    delete parser.yy.result.suggestKeyValues.linked;
-  }
-
-  prioritizeSuggestions();
-
-  if (typeof result.error !== 'undefined' && typeof result.error.expected !== 'undefined') {
-    // Remove any expected tokens from other dialects, jison doesn't remove tokens from other lexer states.
-    var actualExpected = {};
-    result.error.expected.forEach(function (expected) {
-      var match = expected.match(/\<([a-z]+)\>(.*)/);
-      if (match !== null) {
-        if (typeof parser.yy.activeDialect !== 'undefined' && parser.yy.activeDialect === match[1]) {
-          actualExpected[("'" + match[2])] = true;
-        }
-      } else if (expected.indexOf('CURSOR') == -1) {
-        actualExpected[expected] = true;
-      }
-    });
-    result.error.expected = Object.keys(actualExpected);
-  }
-
-  if (typeof result.error !== 'undefined' && result.error.recoverable) {
-    delete result.error;
-  }
-
-  return result;
-};

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

@@ -31,6 +31,7 @@
 <hive>'ARRAY'                              { return '<hive>ARRAY'; }
 <hive>'AS'                                 { return '<hive>AS'; }
 <hive>'BINARY'                             { return '<hive>BINARY'; }
+<hive>'COLUMN'                             { return '<hive>COLUMN'; }
 <hive>'CONF'                               { return '<hive>CONF'; }
 <hive>'CREATE'                             { determineCase(yytext); return '<hive>CREATE'; }
 <hive>'CROSS'                              { return '<hive>CROSS'; }
@@ -46,44 +47,69 @@
 <hive>'MAP'                                { return '<hive>MAP'; }
 <hive>'TABLE'                              { return '<hive>TABLE'; }
 <hive>'USER'                               { return '<hive>USER'; }
+<hive>'USING'                              { return '<hive>USING'; }
 
 // Non-reserved Keywords
+<hive>'ADD'                                { return '<hive>ADD'; }
+<hive>'AFTER'                              { return '<hive>AFTER'; }
+<hive>'ARCHIVE'                            { return '<hive>ARCHIVE'; }
 <hive>'ASC'                                { return '<hive>ASC'; }
 <hive>'AVRO'                               { return '<hive>AVRO'; }
 <hive>'BUCKETS'                            { return '<hive>BUCKETS'; }
+<hive>'CASCADE'                            { return '<hive>CASCADE'; }
+<hive>'CHANGE'                             { return '<hive>CHANGE'; }
 <hive>'CLUSTERED'                          { return '<hive>CLUSTERED'; }
 <hive>'COLLECTION'                         { return '<hive>COLLECTION'; }
 <hive>'COLUMNS'                            { return '<hive>COLUMNS'; }
 <hive>'COMMENT'                            { return '<hive>COMMENT'; }
+<hive>'COMPACT'                            { return '<hive>COMPACT'; }
 <hive>'COMPACTIONS'                        { return '<hive>COMPACTIONS'; }
+<hive>'CONCATENATE'                        { return '<hive>CONCATENATE'; }
 <hive>'DATA'                               { return '<hive>DATA'; }
 <hive>'DATABASES'                          { return '<hive>DATABASES'; }
+<hive>'DEFERRED'                           { return '<hive>DEFERRED'; }
 <hive>'DEFINED'                            { return '<hive>DEFINED'; }
 <hive>'DELIMITED'                          { return '<hive>DELIMITED'; }
 <hive>'DESC'                               { return '<hive>DESC'; }
-<hive>STORED[ \t\n]+AS[ \t\n]+DIRECTORIES  { return '<hive>STORED_AS_DIRECTORIES'; }
+<hive>'DISABLE'                            { return '<hive>DISABLE'; }
 <hive>'ESCAPED'                            { return '<hive>ESCAPED'; }
+<hive>'ENABLE'                             { return '<hive>ENABLE'; }
+<hive>'EXCHANGE'                           { return '<hive>EXCHANGE'; }
 <hive>'FIELDS'                             { return '<hive>FIELDS'; }
+<hive>'FILE'                               { return '<hive>FILE'; }
+<hive>'FILEFORMAT'                         { return '<hive>FILEFORMAT'; }
+<hive>'FIRST'                              { return '<hive>FIRST'; }
 <hive>'FORMAT'                             { return '<hive>FORMAT'; }
 <hive>'FORMATTED'                          { return '<hive>FORMATTED'; }
+<hive>'FUNCTION'                           { return '<hive>FUNCTION'; }
 <hive>'FUNCTIONS'                          { return '<hive>FUNCTIONS'; }
+<hive>'IDXPROPERTIES'                      { return '<hive>IDXPROPERTIES'; }
 <hive>'INDEX'                              { return '<hive>INDEX'; }
 <hive>'INDEXES'                            { return '<hive>INDEXES'; }
 <hive>'INPATH'                             { this.begin('hdfs'); return '<hive>INPATH'; }
 <hive>'INPUTFORMAT'                        { return '<hive>INPUTFORMAT'; }
 <hive>'ITEMS'                              { return '<hive>ITEMS'; }
+<hive>'JAR'                                { return '<hive>JAR'; }
 <hive>'KEYS'                               { return '<hive>KEYS'; }
 <hive>'LIMIT'                              { return '<hive>LIMIT'; }
 <hive>'LINES'                              { return '<hive>LINES'; }
 <hive>'LOAD'                               { determineCase(yytext); return '<hive>LOAD'; }
 <hive>'LOCATION'                           { this.begin('hdfs'); return '<hive>LOCATION'; }
 <hive>'LOCKS'                              { return '<hive>LOCKS'; }
+<hive>'NO_DROP'                            { return '<hive>NO_DROP'; }
+<hive>'OFFLINE'                            { return '<hive>OFFLINE'; }
 <hive>'ORC'                                { return '<hive>ORC'; }
 <hive>'OUTPUTFORMAT'                       { return '<hive>OUTPUTFORMAT'; }
 <hive>'PARQUET'                            { return '<hive>PARQUET'; }
 <hive>'PARTITIONED'                        { return '<hive>PARTITIONED'; }
 <hive>'PARTITIONS'                         { return '<hive>PARTITIONS'; }
+<hive>'PURGE'                              { return '<hive>PURGE'; }
 <hive>'RCFILE'                             { return '<hive>RCFILE'; }
+<hive>'RECOVER'                            { return '<hive>RECOVER'; }
+<hive>'RENAME'                             { return '<hive>RENAME'; }
+<hive>'REPLACE'                            { return '<hive>REPLACE'; }
+<hive>'RESTRICT'                           { return '<hive>RESTRICT'; }
+<hive>'REBUILD'                            { return '<hive>REBUILD'; }
 <hive>'ROLE'                               { return '<hive>ROLE'; }
 <hive>'ROLES'                              { return '<hive>ROLES'; }
 <hive>'SCHEMA'                             { return '<hive>SCHEMA'; }
@@ -93,8 +119,10 @@
 <hive>'SERDEPROPERTIES'                    { return '<hive>SERDEPROPERTIES'; }
 <hive>'SHOW'                               { determineCase(yytext); return '<hive>SHOW'; }
 <hive>'SKEWED'                             { return '<hive>SKEWED'; }
+<hive>'SKEWED LOCATION'                    { return '<hive>SKEWED_LOCATION'; } // Hack to prevent hdfs lexer state
 <hive>'SORTED'                             { return '<hive>SORTED'; }
 <hive>'STORED'                             { return '<hive>STORED'; }
+<hive>STORED[ \t\n]+AS[ \t\n]+DIRECTORIES  { return '<hive>STORED_AS_DIRECTORIES'; }
 <hive>'STRING'                             { return '<hive>STRING'; }
 <hive>'STRUCT'                             { return '<hive>STRUCT'; }
 <hive>'TABLES'                             { return '<hive>TABLES'; }
@@ -103,21 +131,27 @@
 <hive>'TERMINATED'                         { return '<hive>TERMINATED'; }
 <hive>'TEXTFILE'                           { return '<hive>TEXTFILE'; }
 <hive>'TINYINT'                            { return '<hive>TINYINT'; }
+<hive>'TOUCH'                              { return '<hive>TOUCH'; }
 <hive>'TRANSACTIONS'                       { return '<hive>TRANSACTIONS'; }
+<hive>'UNARCHIVE'                          { return '<hive>UNARCHIVE'; }
 <hive>'UNIONTYPE'                          { return '<hive>UNIONTYPE'; }
 <hive>'USE'                                { determineCase(yytext); return '<hive>USE'; }
 <hive>'VIEW'                               { return '<hive>VIEW'; }
 <hive>'WINDOW'                             { return '<hive>WINDOW'; }
 
-<hive>[.]                                  { return '<hive>.'; }
+<hive>'.'                                  { return '<hive>.'; }
 <hive>'['                                  { return '<hive>['; }
 <hive>']'                                  { return '<hive>]'; }
 
 // Reserved Keywords
+<impala>'ADD'                              { return '<impala>ADD'; }
 <impala>'AGGREGATE'                        { return '<impala>AGGREGATE'; }
 <impala>'AVRO'                             { return '<impala>AVRO'; }
 <impala>'CACHED'                           { return '<impala>CACHED'; }
+<impala>'CHANGE'                           { return '<impala>CHANGE'; }
+<impala>'CLOSE_FN'                         { return '<impala>CLOSE_FN'; }
 <impala>'COLUMN'                           { return '<impala>COLUMN'; }
+<impala>'COLUMNS'                          { return '<impala>COLUMNS'; }
 <impala>'COMMENT'                          { return '<impala>COMMENT'; }
 <impala>'CREATE'                           { determineCase(yytext); return '<impala>CREATE'; }
 <impala>'DATA'                             { return '<impala>DATA'; }
@@ -127,6 +161,8 @@
 <impala>'ESCAPED'                          { return '<impala>ESCAPED'; }
 <impala>'EXTERNAL'                         { return '<impala>EXTERNAL'; }
 <impala>'FIELDS'                           { return '<impala>FIELDS'; }
+<impala>'FILEFORMAT'                       { return '<impala>FILEFORMAT'; }
+<impala>'FINALIZE_FN'                      { return '<impala>FINALIZE_FN'; }
 <impala>'FIRST'                            { return '<impala>FIRST'; }
 <impala>'FORMAT'                           { return '<impala>FORMAT'; }
 <impala>'FORMATTED'                        { return '<impala>FORMATTED'; }
@@ -134,28 +170,38 @@
 <impala>'FUNCTIONS'                        { return '<impala>FUNCTIONS'; }
 <impala>'GROUP'                            { return '<impala>GROUP'; }
 <impala>'INCREMENTAL'                      { return '<impala>INCREMENTAL'; }
+<impala>'INIT_FN'                          { return '<impala>INIT_FN'; }
 <impala>'INPATH'                           { this.begin('hdfs'); return '<impala>INPATH'; }
 <impala>'LAST'                             { return '<impala>LAST'; }
 <impala>LIKE[ \t\n]+PARQUET                { this.begin('hdfs'); return '<impala>LIKE_PARQUET'; }
 <impala>'LINES'                            { return '<impala>LINES'; }
 <impala>'LOAD'                             { determineCase(yytext); return '<impala>LOAD'; }
 <impala>'LOCATION'                         { this.begin('hdfs'); return '<impala>LOCATION'; }
+<impala>'MERGE_FN'                         { return '<impala>MERGE_FN'; }
 <impala>'NULLS'                            { return '<impala>NULLS'; }
 <impala>'PARQUET'                          { return '<impala>PARQUET'; }
 <impala>'PARTITIONED'                      { return '<impala>PARTITIONED'; }
 <impala>'PARTITIONS'                       { return '<impala>PARTITIONS'; }
+<impala>'PREPARE_FN'                       { return '<impala>PREPARE_FN'; }
 <impala>'RCFILE'                           { return '<impala>RCFILE'; }
 <impala>'REAL'                             { return '<impala>REAL'; }
+<impala>'RENAME'                           { return '<impala>RENAME'; }
+<impala>'REPLACE'                          { return '<impala>REPLACE'; }
+<impala>'RETURNS'                          { return '<impala>RETURNS'; }
 <impala>'SEQUENCEFILE'                     { return '<impala>SEQUENCEFILE'; }
 <impala>'SERDEPROPERTIES'                  { return '<impala>SERDEPROPERTIES'; }
 <impala>'SCHEMAS'                          { return '<impala>SCHEMAS'; }
+<impala>'SERIALIZE_FN'                     { return '<impala>SERIALIZE_FN'; }
 <impala>'STATS'                            { return '<impala>STATS'; }
 <impala>'STORED'                           { return '<impala>STORED'; }
+<impala>'SYMBOL'                           { return '<impala>SYMBOL'; }
 <impala>'TABLE'                            { return '<impala>TABLE'; }
 <impala>'TABLES'                           { return '<impala>TABLES'; }
 <impala>'TBLPROPERTIES'                    { return '<impala>TBLPROPERTIES'; }
 <impala>'TERMINATED'                       { return '<impala>TERMINATED'; }
 <impala>'TEXTFILE'                         { return '<impala>TEXTFILE'; }
+<impala>'UNCACHED'                         { return '<impala>UNCACHED'; }
+<impala>'UPDATE_FN'                        { return '<impala>UPDATE_FN'; }
 <impala>'USING'                            { return '<impala>USING'; }
 
 // Non-reserved Keywords
@@ -168,7 +214,8 @@
 
 <impala>\[SHUFFLE\]                        { return '<impala>SHUFFLE'; }
 <impala>\[BROADCAST\]                      { return '<impala>BROADCAST'; }
-<impala>[.]                                { return '<impala>.'; }
+<impala>'...'                              { return '<impala>...'; }
+<impala>'.'                                { return '<impala>.'; }
 <impala>'['                                { return '<impala>['; }
 <impala>']'                                { return '<impala>]'; }
 
@@ -176,6 +223,7 @@
 
 // Reserved Keywords
 'ALL'                                      { return 'ALL'; }
+'ALTER'                                    { determineCase(yytext); return 'ALTER'; }
 'AND'                                      { return 'AND'; }
 'AS'                                       { return 'AS'; }
 'ASC'                                      { return 'ASC'; }
@@ -238,10 +286,12 @@
 'THEN'                                     { return 'THEN'; }
 'TIMESTAMP'                                { return 'TIMESTAMP'; }
 'TINYINT'                                  { return 'TINYINT'; }
+'TO'                                       { return 'TO'; }
 'TRUE'                                     { return 'TRUE'; }
 'UNBOUNDED'                                { return 'UNBOUNDED'; }
 'UPDATE'                                   { determineCase(yytext); return 'UPDATE'; }
 'USE'                                      { determineCase(yytext); return 'USE'; }
+'VIEW'                                     { return 'VIEW'; }
 'VARCHAR'                                  { return 'VARCHAR'; } // Not in Impala
 'WHEN'                                     { return 'WHEN'; }
 'WHERE'                                    { return 'WHERE'; }
@@ -252,45 +302,43 @@
 'ROLE'                                     { return 'ROLE'; }
 
 // --- UDFs ---
-'AVG'                                     { addFunctionLocation(yylloc, 'avg'); return 'AVG'; }
-'CAST'                                    { addFunctionLocation(yylloc, 'cast'); return 'CAST'; }
-'COUNT'                                   { addFunctionLocation(yylloc, 'count'); return 'COUNT'; }
-'MAX'                                     { addFunctionLocation(yylloc, 'max'); return 'MAX'; }
-'MIN'                                     { addFunctionLocation(yylloc, 'min'); return 'MIN'; }
-'STDDEV_POP'                              { addFunctionLocation(yylloc, 'stddev_pop'); return 'STDDEV_POP'; }
-'STDDEV_SAMP'                             { addFunctionLocation(yylloc, 'stddev_samp'); return 'STDDEV_SAMP'; }
-'SUM'                                     { addFunctionLocation(yylloc, 'sum'); return 'SUM'; }
-'VARIANCE'                                { addFunctionLocation(yylloc, 'variance'); return 'VARIANCE'; }
-'VAR_POP'                                 { addFunctionLocation(yylloc, 'var_pop'); return 'VAR_POP'; }
-'VAR_SAMP'                                { addFunctionLocation(yylloc, 'var_samp'); return 'VAR_SAMP'; }
-<hive>'COLLECT_SET'                       { addFunctionLocation(yylloc, 'collect_set'); return '<hive>COLLECT_SET'; }
-<hive>'COLLECT_LIST'                      { addFunctionLocation(yylloc, 'collect_list'); return '<hive>COLLECT_LIST'; }
-<hive>'CORR'                              { addFunctionLocation(yylloc, 'corr'); return '<hive>CORR'; }
-<hive>'COVAR_POP'                         { addFunctionLocation(yylloc, 'covar_pop'); return '<hive>COVAR_POP'; }
-<hive>'COVAR_SAMP'                        { addFunctionLocation(yylloc, 'covar_samp'); return '<hive>COVAR_SAMP'; }
-<hive>'HISTOGRAM_NUMERIC'                 { addFunctionLocation(yylloc, 'histogram_numeric'); return '<hive>HISTOGRAM_NUMERIC'; }
-<hive>'NTILE'                             { addFunctionLocation(yylloc, 'ntile'); return '<hive>NTILE'; }
-<hive>'PERCENTILE'                        { addFunctionLocation(yylloc, 'percentile'); return '<hive>PERCENTILE'; }
-<hive>'PERCENTILE_APPROX'                 { addFunctionLocation(yylloc, 'percentile_approx'); return '<hive>PERCENTILE_APPROX'; }
-<impala>'APPX_MEDIAN'                     { addFunctionLocation(yylloc, 'appx_median'); return '<impala>APPX_MEDIAN'; }
-<impala>'EXTRACT'                         { addFunctionLocation(yylloc, 'extract'); return '<impala>EXTRACT'; }
-<impala>'GROUP_CONCAT'                    { addFunctionLocation(yylloc, 'group_concat'); return '<impala>GROUP_CONCAT'; }
-<impala>'STDDEV'                          { addFunctionLocation(yylloc, 'stddev'); return '<impala>STDDEV'; }
-<impala>'VARIANCE_POP'                    { addFunctionLocation(yylloc, 'variance_pop'); return '<impala>VARIANCE_POP'; }
-<impala>'VARIANCE_SAMP'                   { addFunctionLocation(yylloc, 'variance_samp'); return '<impala>VARIANCE_SAMP'; }
+'AVG'                                      { addFunctionLocation(yylloc, 'avg'); return 'AVG'; }
+'CAST'                                     { addFunctionLocation(yylloc, 'cast'); return 'CAST'; }
+'COUNT'                                    { addFunctionLocation(yylloc, 'count'); return 'COUNT'; }
+'MAX'                                      { addFunctionLocation(yylloc, 'max'); return 'MAX'; }
+'MIN'                                      { addFunctionLocation(yylloc, 'min'); return 'MIN'; }
+'STDDEV_POP'                               { addFunctionLocation(yylloc, 'stddev_pop'); return 'STDDEV_POP'; }
+'STDDEV_SAMP'                              { addFunctionLocation(yylloc, 'stddev_samp'); return 'STDDEV_SAMP'; }
+'SUM'                                      { addFunctionLocation(yylloc, 'sum'); return 'SUM'; }
+'VARIANCE'                                 { addFunctionLocation(yylloc, 'variance'); return 'VARIANCE'; }
+'VAR_POP'                                  { addFunctionLocation(yylloc, 'var_pop'); return 'VAR_POP'; }
+'VAR_SAMP'                                 { addFunctionLocation(yylloc, 'var_samp'); return 'VAR_SAMP'; }
+<hive>'COLLECT_SET'                        { addFunctionLocation(yylloc, 'collect_set'); return '<hive>COLLECT_SET'; }
+<hive>'COLLECT_LIST'                       { addFunctionLocation(yylloc, 'collect_list'); return '<hive>COLLECT_LIST'; }
+<hive>'CORR'                               { addFunctionLocation(yylloc, 'corr'); return '<hive>CORR'; }
+<hive>'COVAR_POP'                          { addFunctionLocation(yylloc, 'covar_pop'); return '<hive>COVAR_POP'; }
+<hive>'COVAR_SAMP'                         { addFunctionLocation(yylloc, 'covar_samp'); return '<hive>COVAR_SAMP'; }
+<hive>'HISTOGRAM_NUMERIC'                  { addFunctionLocation(yylloc, 'histogram_numeric'); return '<hive>HISTOGRAM_NUMERIC'; }
+<hive>'NTILE'                              { addFunctionLocation(yylloc, 'ntile'); return '<hive>NTILE'; }
+<hive>'PERCENTILE'                         { addFunctionLocation(yylloc, 'percentile'); return '<hive>PERCENTILE'; }
+<hive>'PERCENTILE_APPROX'                  { addFunctionLocation(yylloc, 'percentile_approx'); return '<hive>PERCENTILE_APPROX'; }
+<impala>'APPX_MEDIAN'                      { addFunctionLocation(yylloc, 'appx_median'); return '<impala>APPX_MEDIAN'; }
+<impala>'EXTRACT'                          { addFunctionLocation(yylloc, 'extract'); return '<impala>EXTRACT'; }
+<impala>'GROUP_CONCAT'                     { addFunctionLocation(yylloc, 'group_concat'); return '<impala>GROUP_CONCAT'; }
+<impala>'STDDEV'                           { addFunctionLocation(yylloc, 'stddev'); return '<impala>STDDEV'; }
+<impala>'VARIANCE_POP'                     { addFunctionLocation(yylloc, 'variance_pop'); return '<impala>VARIANCE_POP'; }
+<impala>'VARIANCE_SAMP'                    { addFunctionLocation(yylloc, 'variance_samp'); return '<impala>VARIANCE_SAMP'; }
 
 // Analytical functions
-'DENSE_RANK'                              { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-'FIRST_VALUE'                             { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-'LAG'                                     { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-'LAST_VALUE'                              { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-'LEAD'                                    { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-'RANK'                                    { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-'ROW_NUMBER'                              { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-<hive>'CUME_DIST'                         { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-<hive>'PERCENT_RANK'                      { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
-
-// [A-Za-z][A-Za-z0-9_]*\(                    { addFunctionLocation(yylloc, yytext.substring(0, yytext.length - 1)); return 'UDF('; }
+'DENSE_RANK'                               { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
+'FIRST_VALUE'                              { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
+'LAG'                                      { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
+'LAST_VALUE'                               { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
+'LEAD'                                     { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
+'RANK'                                     { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
+'ROW_NUMBER'                               { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
+<hive>'CUME_DIST'                          { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
+<hive>'PERCENT_RANK'                       { addFunctionLocation(yylloc, 'variance_samp'); return 'ANALYTIC'; }
 
 [0-9]+                                     { return 'UNSIGNED_INTEGER'; }
 [0-9]+E                                    { return 'UNSIGNED_INTEGER_E'; }
@@ -298,7 +346,7 @@
 
 <hdfs>'\u2020'                             { parser.yy.cursorFound = true; return 'CURSOR'; }
 <hdfs>'\u2021'                             { parser.yy.cursorFound = true; return 'PARTIAL_CURSOR'; }
-<hdfs>\s+[']                               { return 'HDFS_START_QUOTE'; }
+<hdfs>[ \t\n]+[']                          { return 'HDFS_START_QUOTE'; }
 <hdfs>[^'\u2020\u2021]+                    { return 'HDFS_PATH'; }
 <hdfs>[']                                  { this.popState(); return 'HDFS_END_QUOTE'; }
 <hdfs><<EOF>>                              { return 'EOF'; }
@@ -358,7 +406,13 @@
 <backtickedValue>\`                        { this.popState(); return 'BACKTICK'; }
 
 \'                                         { this.begin('singleQuotedValue'); return 'SINGLE_QUOTE'; }
-<singleQuotedValue>[^']+                   { return 'VALUE'; }
+<singleQuotedValue>[^']+                   {
+                                             if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) {
+                                               this.popState();
+                                               return 'PARTIAL_VALUE';
+                                             }
+                                             return 'VALUE';
+                                           }
 <singleQuotedValue>\'                      { this.popState(); return 'SINGLE_QUOTE'; }
 
 \"                                         { this.begin('doubleQuotedValue'); return 'DOUBLE_QUOTE'; }

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

@@ -0,0 +1,606 @@
+// 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
+ ;
+
+AlterStatement_EDIT
+ : AlterTable_EDIT
+ | 'ALTER' 'CURSOR'
+   {
+     suggestKeywords(['TABLE']);
+   }
+ ;
+
+AlterTable
+ : AlterTableLeftSide AnyAdd OptionalIfNotExists PartitionSpec OptionalHdfsLocation OptionalPartitionSpecs
+ | AlterTableLeftSide AnyRename 'TO' RegularOrBackTickedSchemaQualifiedName
+ | AlterTableLeftSide HiveSpecificOperations
+ | AlterTableLeftSide DropOperations
+ | AlterTableLeftSide OptionalPartitionOperations
+ | AlterTableLeftSide PartitionSpec OptionalPartitionOperations
+ ;
+
+AlterTable_EDIT
+ : AlterTableLeftSide_EDIT
+ | AlterTableLeftSide_EDIT AnyAdd OptionalIfNotExists PartitionSpec OptionalHdfsLocation OptionalPartitionSpecs
+ | AlterTableLeftSide_EDIT AnyRename 'TO' RegularOrBackTickedSchemaQualifiedName
+ | AlterTableLeftSide_EDIT HiveSpecificOperations
+ | AlterTableLeftSide_EDIT DropOperations
+ | AlterTableLeftSide_EDIT OptionalPartitionOperations
+ | AlterTableLeftSide_EDIT PartitionSpec OptionalPartitionOperations
+ | AlterTableLeftSide AnyAdd OptionalIfNotExists 'CURSOR'
+   {
+     if (isHive()) {
+       if (!$3) {
+         suggestKeywords(['COLUMNS', 'IF NOT EXISTS', 'PARTITION']);
+       } else {
+         suggestKeywords(['PARTITION']);
+       }
+     } else if (isImpala()) {
+       suggestKeywords(['COLUMNS', 'PARTITION']);
+     }
+   }
+ | AlterTableLeftSide AnyReplace 'CURSOR'
+   {
+     suggestKeywords(['COLUMNS']);
+   }
+ | AlterTableLeftSide AnyAdd OptionalIfNotExists_EDIT
+ | AlterTableLeftSide AnyAdd OptionalIfNotExists PartitionSpec OptionalHdfsLocation_EDIT OptionalPartitionSpecs
+ | AlterTableLeftSide AnyAdd OptionalIfNotExists PartitionSpec OptionalHdfsLocation OptionalPartitionSpecs_EDIT
+ | AlterTableLeftSide AnyAdd OptionalIfNotExists PartitionSpec OptionalHdfsLocation OptionalPartitionSpecs 'CURSOR'
+   {
+     if (isHive()) {
+       if (!$5 && !$6) {
+         suggestKeywords(['LOCATION', 'PARTITION']);
+       } else if ($6 && $6.suggestKeywords) {
+         suggestKeywords($6.suggestKeywords.concat(['PARTITION']));
+       } else {
+         suggestKeywords(['PARTITION']);
+       }
+     }
+   }
+ | AlterTableLeftSide AnyAdd OptionalIfNotExists PartitionSpec_EDIT OptionalHdfsLocation OptionalPartitionSpecs
+ | AlterTableLeftSide HiveSpecificOperations_EDIT
+ | AlterTableLeftSide OptionalPartitionOperations_EDIT
+ | AlterTableLeftSide DropOperations_EDIT
+ | AlterTableLeftSide 'CURSOR'
+   {
+     if (isHive()) {
+       suggestKeywords(['ADD COLUMNS', 'ADD IF NOT EXISTS', 'ADD PARTITION', 'ARCHIVE PARTITION', 'CHANGE',
+         'CLUSTERED BY', 'CONCATENATE', 'COMPACT', 'DISABLE NO_DROP', 'DISABLE OFFLINE', 'DROP', 'ENABLE NO_DROP',
+         'ENABLE OFFLINE', 'EXCHANGE PARTITION', 'NOT SKEWED', 'NOT STORED AS DIRECTORIES', 'PARTITION',
+         'RECOVER PARTITIONS', 'RENAME TO', 'REPLACE COLUMNS', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDE',
+         'SET SERDEPROPERTIES', 'SET SKEWED LOCATION', 'SET TBLPROPERTIES', 'SKEWED BY', 'TOUCH', 'UNARCHIVE PARTITION']);
+     } else if (isImpala()) {
+       suggestKeywords(['ADD COLUMNS', 'ADD PARTITION', 'CHANGE', 'DROP COLUMN', 'DROP PARTITION', 'PARTITION',
+         'RENAME TO', 'REPLACE COLUMNS', 'SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDEPROPERTIES',
+         'SET TBLPROPERTIES', 'SET UNCACHED']);
+     }
+   }
+ | AlterTableLeftSide PartitionSpec 'CURSOR'
+   {
+     if (isHive()) {
+       suggestKeywords(['ADD COLUMNS', 'CHANGE', 'COMPACT', 'CONCATENATE', 'DISABLE NO_DROP', 'DISABLE OFFLINE',
+         'ENABLE NO_DROP', 'ENABLE OFFLINE', 'RENAME TO PARTITION', 'REPLACE COLUMNS', 'SET FILEFORMAT', 'SET LOCATION',
+         'SET SERDE', 'SET SERDEPROPERTIES']);
+     } else if (isImpala()) {
+       suggestKeywords(['SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDEPROPERTIES', 'SET TBLPROPERTIES',
+         'SET UNCACHED']);
+     }
+   }
+ | AlterTableLeftSide PartitionSpec AddOrReplace 'CURSOR'
+   {
+     suggestKeywords(['COLUMNS']);
+   }
+ | AlterTableLeftSide PartitionSpec 'SET' 'CURSOR'
+    {
+      if (isHive()) {
+        suggestKeywords(['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES']);
+      } else if (isImpala()) {
+        suggestKeywords(['CACHED IN', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES','TBLPROPERTIES', 'UNCACHED']);
+      }
+    }
+ | AlterTableLeftSide 'SET' 'CURSOR'
+    {
+      if (isHive()) {
+        suggestKeywords(['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES', 'SKEWED LOCATION', 'TBLPROPERTIES']);
+      } else if (isImpala()) {
+        suggestKeywords(['CACHED IN', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES', 'TBLPROPERTIES', 'UNCACHED']);
+      }
+    }
+ | AlterTableLeftSide PartitionSpec OptionalPartitionOperations_EDIT
+ | AlterTableLeftSide AnyRename 'CURSOR'
+   {
+     suggestKeywords(['TO']);
+   }
+ ;
+
+HiveSpecificOperations
+ : HiveClusteredBy
+ | '<hive>SKEWED' 'BY' ParenthesizedColumnList 'ON' ParenthesizedSkewedValueList OptionalStoredAsDirectories
+ | HiveExchange
+ | '<hive>RECOVER' '<hive>PARTITIONS'
+ | '<hive>TOUCH' OptionalPartitionSpec
+ | HiveArchiveOrUnArchive PartitionSpec
+ | 'NOT' '<hive>SKEWED'
+ | 'NOT' '<hive>STORED_AS_DIRECTORIES'
+ | 'SET' '<hive>SKEWED_LOCATION' ParenthesizedSkewedLocationList
+ | PartitionSpec '<hive>RENAME' 'TO' PartitionSpec
+ | PartitionSpec AnyChange '<hive>COLUMN' ParenthesizedColumnSpecificationList OptionalHiveCascadeOrRestrict
+ ;
+
+HiveSpecificOperations_EDIT
+ : HiveArchiveOrUnArchive 'CURSOR'
+   {
+     suggestKeywords(['PARTITION']);
+   }
+ | HiveArchiveOrUnArchive PartitionSpec_EDIT
+ | HiveClusteredBy_EDIT
+ | HiveExchange_EDIT
+ | 'NOT' 'CURSOR'
+   {
+     if (isHive()) {
+       suggestKeywords(['SKEWED', 'STORED AS DIRECTORIES']);
+     }
+   }
+ | 'NOT' '<hive>STORED' 'CURSOR'
+   {
+     suggestKeywords(['AS DIRECTORIES']);
+   }
+ | 'NOT' '<hive>STORED' '<hive>AS' 'CURSOR'
+   {
+     suggestKeywords(['DIRECTORIES']);
+   }
+ | PartitionSpec '<hive>RENAME' 'CURSOR'
+   {
+     suggestKeywords(['TO PARTITION']);
+   }
+ | PartitionSpec '<hive>RENAME' 'TO' 'CURSOR'
+   {
+     suggestKeywords(['PARTITION']);
+   }
+ | '<hive>RECOVER' 'CURSOR'
+   {
+     suggestKeywords(['PARTITIONS']);
+   }
+ | 'SET' '<hive>SKEWED' 'CURSOR'
+   {
+     suggestKeywords(['LOCATION']);
+   }
+ | 'SET' '<hive>SKEWED_LOCATION' ParenthesizedSkewedLocationList_EDIT
+ | '<hive>SKEWED' 'CURSOR'
+   {
+     suggestKeywords(['BY']);
+   }
+ | '<hive>SKEWED' 'BY' ParenthesizedColumnList_EDIT
+ | '<hive>SKEWED' 'BY' ParenthesizedColumnList_EDIT 'ON' ParenthesizedSkewedValueList OptionalStoredAsDirectories
+ | '<hive>SKEWED' 'BY' ParenthesizedColumnList 'CURSOR'
+   {
+     suggestKeywords(['ON']);
+   }
+ | '<hive>SKEWED' 'BY' ParenthesizedColumnList 'ON' ParenthesizedSkewedValueList OptionalStoredAsDirectories 'CURSOR'
+   {
+     if (!$6) {
+       suggestKeywords(['STORED AS DIRECTORIES']);
+     }
+   }
+ | '<hive>SKEWED' 'BY' ParenthesizedColumnList 'ON' ParenthesizedSkewedValueList OptionalStoredAsDirectories_EDIT
+ | '<hive>TOUCH' 'CURSOR'
+   {
+     suggestKeywords(['PARTITION']);
+   }
+ | '<hive>TOUCH' OptionalPartitionSpec_EDIT
+ ;
+
+OptionalPartitionOperations
+ : 'SET' AnyFileFormat FileFormat
+ | 'SET' HdfsLocation
+ | 'SET' HiveOrImpalaTblproperties ParenthesizedPropertyAssignmentList
+ | 'SET' '<hive>SERDE' QuotedValue OptionalHiveWithSerdeproperties
+ | 'SET' HiveOrImpalaSerdeproperties ParenthesizedPropertyAssignmentList
+ | 'SET' ImpalaCachedIn
+ | 'SET' '<impala>UNCACHED'
+ | AddReplaceColumns
+ | '<hive>CONCATENATE'
+ | '<hive>COMPACT' QuotedValue
+ | HiveEnableOrDisable HiveNoDropOrOffline
+ | AnyChange OptionalHiveColumn ColumnIdentifier ColumnSpecification OptionalHiveFirstOrAfter OptionalHiveCascadeOrRestrict
+ ;
+
+OptionalPartitionOperations_EDIT
+ : AddReplaceColumns_EDIT
+ | AnyChange OptionalHiveColumn 'CURSOR'
+   {
+     if (isHive() && !$2) {
+       suggestKeywords(['COLUMN']);
+     }
+     suggestColumns();
+   }
+ | AnyChange OptionalHiveColumn ColumnIdentifier ColumnSpecification_EDIT OptionalHiveFirstOrAfter OptionalHiveCascadeOrRestrict
+ | AnyChange OptionalHiveColumn ColumnIdentifier ColumnSpecification OptionalHiveFirstOrAfter OptionalHiveCascadeOrRestrict 'CURSOR'
+   {
+     if (isHive() && !$5 && !$6) {
+       if ($4.suggestKeywords) {
+         suggestKeywords($4.suggestKeywords.concat(['AFTER', 'CASCADE', 'FIRST', 'RESTRICT']));
+       } else {
+         suggestKeywords(['AFTER', 'CASCADE', 'FIRST', 'RESTRICT']);
+       }
+     } else if (isHive() && $5 && !$6) {
+       suggestKeywords(['CASCADE', 'RESTRICT']);
+     }
+   }
+ | AnyChange OptionalHiveColumn ColumnIdentifier ColumnSpecification OptionalHiveFirstOrAfter_EDIT OptionalHiveCascadeOrRestrict
+ | HiveEnableOrDisable 'CURSOR'
+   {
+     suggestKeywords(['NO_DROP', 'OFFLINE']);
+   }
+ | 'SET' AnyFileFormat 'CURSOR'
+   {
+     suggestFileFormats();
+   }
+ | 'SET' HdfsLocation_EDIT
+ | 'SET' ImpalaCachedIn_EDIT
+ | 'SET' '<hive>SERDE' QuotedValue OptionalHiveWithSerdeproperties 'CURSOR'
+   {
+     if (!$4) {
+       suggestKeywords(['WITH SERDEPROPERTIES']);
+     }
+   }
+ | 'SET' '<hive>SERDE' QuotedValue OptionalHiveWithSerdeproperties_EDIT
+ ;
+
+AddReplaceColumns
+ : AddOrReplace AnyColumns ParenthesizedColumnSpecificationList OptionalHiveCascadeOrRestrict
+ ;
+
+AddReplaceColumns_EDIT
+ : AddOrReplace AnyColumns ParenthesizedColumnSpecificationList_EDIT OptionalHiveCascadeOrRestrict
+ | AddOrReplace AnyColumns ParenthesizedColumnSpecificationList OptionalHiveCascadeOrRestrict 'CURSOR'
+   {
+     if (isHive() && !$4) {
+       suggestKeywords(['CASCADE', 'RESTRICT']);
+     }
+   }
+ ;
+
+AnyColumns
+ : '<hive>COLUMNS'
+ | '<impala>COLUMNS'
+ ;
+
+HiveExchange
+ : '<hive>EXCHANGE' ExchangePartitionSpec 'WITH' '<hive>TABLE' RegularOrBackTickedSchemaQualifiedName
+ ;
+
+HiveExchange_EDIT
+ : '<hive>EXCHANGE' 'CURSOR'
+   {
+     suggestKeywords(['PARTITION']);
+   }
+ | '<hive>EXCHANGE' ExchangePartitionSpec 'CURSOR'
+   {
+     suggestKeywords(['WITH TABLE']);
+   }
+ | '<hive>EXCHANGE' ExchangePartitionSpec 'WITH' 'CURSOR'
+   {
+     suggestKeywords(['TABLE']);
+   }
+ | '<hive>EXCHANGE' ExchangePartitionSpec 'WITH' '<hive>TABLE' 'CURSOR'
+   {
+     suggestTables();
+     suggestDatabases({ appendDot: true });
+   }
+ | '<hive>EXCHANGE' ExchangePartitionSpec 'WITH' '<hive>TABLE' RegularOrBackTickedSchemaQualifiedName_EDIT
+ | '<hive>EXCHANGE' ExchangePartitionSpec_EDIT
+ | '<hive>EXCHANGE' ExchangePartitionSpec_EDIT 'WITH' '<hive>TABLE' RegularOrBackTickedSchemaQualifiedName
+ ;
+
+ExchangePartitionSpec
+ : 'PARTITION' '(' OneOrMorePartitionSpecLists ')'
+ ;
+
+ExchangePartitionSpec_EDIT
+ : 'PARTITION' '(' OneOrMorePartitionSpecLists_EDIT RightParenthesisOrError
+ ;
+
+OneOrMorePartitionSpecLists
+ : '(' PartitionSpecList ')'
+ | OneOrMorePartitionSpecLists ',' '(' PartitionSpecList ')'
+ ;
+
+OneOrMorePartitionSpecLists_EDIT
+ : '(' PartitionSpecList_EDIT RightParenthesisOrError
+ | OneOrMorePartitionSpecLists ',' '(' PartitionSpecList_EDIT RightParenthesisOrError
+ ;
+
+DropOperations
+ : 'DROP' OneOrMorePartitionSpecs OptionalHivePurge
+ | 'DROP' 'IF' 'EXISTS' OneOrMorePartitionSpecs OptionalHivePurge
+ | 'DROP' ColumnIdentifier
+ | 'DROP' '<impala>COLUMN' ColumnIdentifier
+ ;
+
+DropOperations
+ : 'DROP' 'CURSOR'
+   {
+     if (isHive()) {
+       suggestKeywords(['PARTITION', 'IF EXISTS']);
+     } else if (isImpala()) {
+       suggestKeywords(['COLUMN', 'PARTITION']);
+       suggestColumns();
+     }
+   }
+ | 'DROP' OneOrMorePartitionSpecs_EDIT OptionalHivePurge
+ | 'DROP' OneOrMorePartitionSpecs OptionalHivePurge 'CURSOR'
+   {
+     if (isHive() && !$3) {
+       suggestKeywords(['PURGE']);
+     }
+   }
+ | 'DROP' 'IF' 'CURSOR'
+   {
+     if (isHive()) {
+       suggestKeywords(['EXISTS']);
+     }
+   }
+ | 'DROP' 'IF' 'EXISTS' 'CURSOR'
+    {
+      if (isHive()) {
+        suggestKeywords(['PARTITION']);
+      }
+    }
+ | 'DROP' 'IF' 'EXISTS' OneOrMorePartitionSpecs_EDIT OptionalHivePurge
+ | 'DROP' 'IF' 'EXISTS' OneOrMorePartitionSpecs OptionalHivePurge 'CURSOR'
+   {
+     if (isHive() && !$3) {
+       suggestKeywords(['PURGE']);
+     }
+   }
+ | 'DROP' ColumnIdentifier_EDIT
+ | 'DROP' '<impala>COLUMN' 'CURSOR'
+   {
+     suggestColumns();
+   }
+ | 'DROP' '<impala>COLUMN' ColumnIdentifier_EDIT
+ ;
+
+AlterTableLeftSide
+ : 'ALTER' AnyTable SchemaQualifiedTableIdentifier
+   {
+     addTablePrimary($3);
+   }
+ ;
+
+AlterTableLeftSide_EDIT
+ : 'ALTER' AnyTable SchemaQualifiedTableIdentifier_EDIT
+ | 'ALTER' AnyTable 'CURSOR'
+   {
+     suggestTables();
+     suggestDatabases({ appendDot: true });
+   }
+ ;
+
+AnyChange
+ : '<hive>CHANGE'
+ | '<impala>CHANGE'
+ ;
+
+AnyFileFormat
+ : '<hive>FILEFORMAT'
+ | '<impala>FILEFORMAT'
+ ;
+
+AnyAdd
+ : '<hive>ADD'
+ | '<impala>ADD'
+ ;
+
+AnyReplace
+ : '<hive>REPLACE'
+ | '<impala>REPLACE'
+ ;
+
+AddOrReplace
+ : AnyAdd
+ | AnyReplace
+ ;
+
+OptionalHiveFirstOrAfter
+ :
+ | HiveAfterOrFirst ColumnIdentifier
+ ;
+
+HiveAfterOrFirst
+ : '<hive>AFTER'
+ | '<hive>FIRST'
+ ;
+
+OptionalHiveFirstOrAfter_EDIT
+ : HiveAfterOrFirst 'CURSOR'
+   {
+     suggestColumns();
+   }
+ | HiveAfterOrFirst ColumnIdentifier_EDIT
+ ;
+
+
+OptionalHiveColumn
+ :
+ | '<hive>COLUMN'
+ ;
+
+AnyRename
+ : '<impala>RENAME'
+ | '<hive>RENAME'
+ ;
+
+HiveEnableOrDisable
+ : '<hive>ENABLE'
+ | '<hive>DISABLE'
+ ;
+
+HiveNoDropOrOffline
+ : '<hive>NO_DROP'
+ | '<hive>OFFLINE'
+ ;
+
+HiveOrImpalaSerdeproperties
+ : '<hive>SERDEPROPERTIES'
+ | '<impala>SERDEPROPERTIES'
+ ;
+
+
+HiveArchiveOrUnArchive
+ : '<hive>ARCHIVE'
+ | '<hive>UNARCHIVE'
+ ;
+
+OneOrMorePartitionSpecs
+ : PartitionSpec
+ | OneOrMorePartitionSpecs ',' PartitionSpec // Only Hive
+ ;
+
+OneOrMorePartitionSpecs_EDIT
+ : PartitionSpec_EDIT
+ | OneOrMorePartitionSpecs ',' AnyCursor
+   {
+     if (isHive()) {
+       suggestKeywords(['PARTITION']);
+     }
+   }
+ | OneOrMorePartitionSpecs ',' AnyCursor ',' OneOrMorePartitionSpecs
+   {
+     if (isHive()) {
+       suggestKeywords(['PARTITION']);
+     }
+   }
+ | AnyCursor ',' OneOrMorePartitionSpecs
+   {
+     if (isHive()) {
+       suggestKeywords(['PARTITION']);
+     }
+   }
+ | OneOrMorePartitionSpecs ',' PartitionSpec_EDIT
+ | PartitionSpec_EDIT ',' OneOrMorePartitionSpecs
+ | OneOrMorePartitionSpecs ',' PartitionSpec_EDIT ',' OneOrMorePartitionSpecs
+ ;
+
+OptionalHivePurge
+ :
+ | '<hive>PURGE'
+ ;
+
+OptionalPartitionSpecs
+ :
+ | PartitionSpecWithLocationList
+ ;
+
+PartitionSpecWithLocationList
+ : PartitionSpecWithLocation
+ | PartitionSpecWithLocationList PartitionSpecWithLocation  -> $2
+ ;
+
+OptionalPartitionSpecs_EDIT
+ : PartitionSpecWithLocation_EDIT
+ | PartitionSpecWithLocation_EDIT PartitionSpecWithLocationList
+ | PartitionSpecWithLocationList PartitionSpecWithLocation_EDIT
+ | PartitionSpecWithLocationList PartitionSpecWithLocation_EDIT PartitionSpecWithLocationList
+ ;
+
+PartitionSpecWithLocation_EDIT
+ : PartitionSpec OptionalHdfsLocation_EDIT
+ | PartitionSpec_EDIT OptionalHdfsLocation
+ ;
+
+PartitionSpecWithLocation
+ : PartitionSpec OptionalHdfsLocation
+   {
+     if (!$2) {
+       $$ = { suggestKeywords: ['LOCATION'] };
+     }
+   }
+ ;
+
+ParenthesizedSkewedLocationList
+ : '(' SkewedLocationList ')'
+ ;
+
+ParenthesizedSkewedLocationList_EDIT
+ : '(' SkewedLocationList_EDIT RightParenthesisOrError
+ ;
+
+SkewedLocationList
+ : SkewedLocation
+ | SkewedLocationList ',' SkewedLocation
+ ;
+
+SkewedLocationList_EDIT
+ : SkewedLocation_EDIT
+ | SkewedLocationList ',' SkewedLocation_EDIT
+ | SkewedLocationList ',' SkewedLocation_EDIT ',' SkewedLocationList
+ | SkewedLocation_EDIT ',' SkewedLocationList
+ ;
+
+SkewedLocation
+ : ColumnReference '=' QuotedValue
+ ;
+
+SkewedLocation_EDIT
+ : AnyCursor
+   {
+     suggestColumns();
+   }
+ | ColumnReference_EDIT
+ | AnyCursor '=' QuotedValue
+   {
+     suggestColumns();
+   }
+ | ColumnReference_EDIT '=' QuotedValue
+ | ColumnReferences '=' QuotedValue
+ ;
+
+OptionalStoredAsDirectories
+ :
+ | '<hive>STORED_AS_DIRECTORIES'
+ ;
+
+OptionalStoredAsDirectories_EDIT
+ : '<hive>STORED' 'CURSOR'
+   {
+     suggestKeywords(['AS DIRECTORIES']);
+   }
+ | '<hive>STORED' '<hive>AS' 'CURSOR'
+   {
+     suggestKeywords(['DIRECTORIES']);
+   }
+ ;
+
+
+OptionalCascadeOrRestrict
+ :
+ | '<hive>CASCADE'
+ | '<hive>RESTRICT'
+ ;

+ 614 - 103
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_create.jison

@@ -25,30 +25,36 @@ DataDefinition_EDIT
 CreateStatement
  : DatabaseDefinition
  | TableDefinition
+ | ViewDefinition
+ | RoleDefinition
+ | FunctionDefinition
+ | IndexDefinition
  ;
 
 CreateStatement_EDIT
  : DatabaseDefinition_EDIT
  | TableDefinition_EDIT
+ | ViewDefinition_EDIT
+ | FunctionDefinition_EDIT
+ | IndexDefinition_EDIT
  | AnyCreate OptionalHiveTemporary OptionalExternal 'CURSOR'
    {
      if ($3) {
        suggestKeywords(['TABLE']);
      } else if (isHive()) {
        if ($2) {
-         suggestKeywords(['EXTERNAL TABLE', 'TABLE']);
+         suggestKeywords(['EXTERNAL TABLE', 'FUNCTION', 'TABLE']);
        } else {
-         suggestKeywords(['DATABASE', 'EXTERNAL TABLE', 'SCHEMA', 'TABLE', 'TEMPORARY EXTERNAL TABLE', 'TEMPORARY TABLE']);
+         suggestKeywords(['DATABASE', 'EXTERNAL TABLE', 'FUNCTION', 'INDEX', 'ROLE', 'SCHEMA', 'TABLE', 'TEMPORARY EXTERNAL TABLE', 'TEMPORARY FUNCTION', 'TEMPORARY TABLE', 'VIEW']);
        }
      } else if (isImpala()) {
-       suggestKeywords(['DATABASE', 'EXTERNAL TABLE', 'SCHEMA', 'TABLE']);
+       suggestKeywords(['AGGREGATE FUNCTION', 'DATABASE', 'EXTERNAL TABLE', 'FUNCTION', 'ROLE', 'SCHEMA', 'TABLE', 'VIEW']);
      } else {
-       suggestKeywords(['DATABASE', 'SCHEMA', 'TABLE']);
+       suggestKeywords(['DATABASE', 'ROLE', 'SCHEMA', 'TABLE', 'VIEW']);
      }
    }
  ;
 
-
 DatabaseDefinition
  : AnyCreate DatabaseOrSchema OptionalIfNotExists
  | AnyCreate DatabaseOrSchema OptionalIfNotExists RegularIdentifier DatabaseDefinitionOptionals
@@ -103,12 +109,14 @@ OptionalComment
  ;
 
 Comment
- : HiveOrImpalaComment SingleQuotedValue
+ : HiveOrImpalaComment QuotedValue
  ;
 
 Comment_INVALID
  : HiveOrImpalaComment SINGLE_QUOTE
+ | HiveOrImpalaComment DOUBLE_QUOTE
  | HiveOrImpalaComment SINGLE_QUOTE VALUE
+ | HiveOrImpalaComment DOUBLE_QUOTE VALUE
  ;
 
 OptionalComment_INVALID
@@ -288,26 +296,6 @@ TableIdentifierAndOptionalColumnSpecification_EDIT
  : SchemaQualifiedTableIdentifier OptionalColumnSpecificationsOrLike_EDIT
  ;
 
-DropLastLocation
- : /* Empty */
-   {
-     if (parser.yy.locations.length > 0) {
-       parser.yy.locations.pop();
-     }
-   }
- ;
-
-OptionalHiveTemporary
- :
- | '<hive>TEMPORARY'
- ;
-
-OptionalExternal
- :
- | '<hive>EXTERNAL'
- | '<impala>EXTERNAL'
- ;
-
 OptionalColumnSpecificationsOrLike
  :
  | ParenthesizedColumnSpecificationList
@@ -339,18 +327,35 @@ ParenthesizedColumnSpecificationList_EDIT
 
 ColumnSpecificationList
  : ColumnSpecification
- | ColumnSpecificationList ',' ColumnSpecification
+ | ColumnSpecificationList ',' ColumnSpecification  -> $3
  ;
 
 ColumnSpecificationList_EDIT
  : ColumnSpecification_EDIT
+ | ColumnSpecification 'CURSOR'
+   {
+     checkForKeywords($1);
+   }
  | ColumnSpecification_EDIT ',' ColumnSpecificationList
+ | ColumnSpecification 'CURSOR' ',' ColumnSpecificationList
+   {
+     checkForKeywords($1);
+   }
  | ColumnSpecificationList ',' ColumnSpecification_EDIT
  | ColumnSpecificationList ',' ColumnSpecification_EDIT ',' ColumnSpecificationList
+ | ColumnSpecificationList ',' ColumnSpecification 'CURSOR' ',' ColumnSpecificationList
+   {
+     checkForKeywords($3);
+   }
  ;
 
 ColumnSpecification
  : ColumnIdentifier ColumnDataType OptionalComment
+   {
+     if (!$3) {
+       $$ = { suggestKeywords: ['COMMENT'] };
+     }
+   }
  ;
 
 ColumnSpecification_EDIT
@@ -358,13 +363,7 @@ ColumnSpecification_EDIT
    {
      suggestKeywords(getColumnDataTypeKeywords());
    }
- | ColumnIdentifier ColumnDataType_EDIT
- | ColumnIdentifier ColumnDataType OptionalComment 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['COMMENT']);
-     }
-   }
+ | ColumnIdentifier ColumnDataType_EDIT OptionalComment
  ;
 
 ColumnDataType
@@ -451,11 +450,6 @@ StructDefinitionList_EDIT
  | StructDefinitionList ',' StructDefinition_EDIT Commas StructDefinitionList
  ;
 
-Commas
- : ','
- | Commas ','
- ;
-
 StructDefinition
  : RegularOrBacktickedIdentifier ':' ColumnDataType OptionalComment
  ;
@@ -542,25 +536,26 @@ OptionalPartitionedBy_EDIT
  | HiveOrImpalaPartitioned ParenthesizedColumnSpecificationList_EDIT
  ;
 
-ParenthesizedColumnList
- : '(' ColumnList ')'
+OptionalHiveClusteredBy
+ :
+ | HiveClusteredBy
  ;
 
-ColumnList
- : ColumnIdentifier
- | ColumnList ',' ColumnIdentifier
+HiveClusteredBy
+ : '<hive>CLUSTERED' 'BY' ParenthesizedColumnList OptionalHiveSortedBy 'INTO' 'UNSIGNED_INTEGER' '<hive>BUCKETS'
  ;
 
-OptionalHiveClusteredBy
- :
- | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList OptionalHiveSortedBy 'INTO' 'UNSIGNED_INTEGER' '<hive>BUCKETS'
+OptionalHiveClusteredBy_EDIT
+ : HiveClusteredBy_EDIT
  ;
 
-OptionalHiveClusteredBy_EDIT
+HiveClusteredBy_EDIT
  : '<hive>CLUSTERED' 'CURSOR'
    {
      suggestKeywords(['BY']);
    }
+ | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList_EDIT OptionalHiveSortedBy
+ | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList_EDIT OptionalHiveSortedBy 'INTO' 'UNSIGNED_INTEGER' '<hive>BUCKETS'
  | '<hive>CLUSTERED' 'BY' ParenthesizedColumnList OptionalHiveSortedBy 'CURSOR'
    {
      if (!$4) {
@@ -619,9 +614,13 @@ SortIdentifier_EDIT
    {
      checkForKeywords($2);
    }
+ | ColumnIdentifier_EDIT OptionalAscOrDesc
+ | AnyCursor OptionalAscOrDesc
+   {
+     suggestColumns();
+   }
  ;
 
-
 OptionalHiveSkewedBy
  :
  | '<hive>SKEWED' 'BY' ParenthesizedColumnList ON ParenthesizedSkewedValueList  -> { suggestKeywords: ['STORED AS DIRECTORIES'] }
@@ -648,15 +647,6 @@ SkewedValueList
  | SkewedValueList ',' ParenthesizedSimpleValueList
  ;
 
-ParenthesizedSimpleValueList
- : '(' SimpleValueList ')'
- ;
-
-SimpleValueList
- : UnsignedValueSpecification
- | SimpleValueList ',' UnsignedValueSpecification
- ;
-
 OptionalStoredAsOrBy
  :
  | StoredAs
@@ -715,24 +705,10 @@ StoredAs
 StoredAs_EDIT
  : HiveOrImpalaStored AnyAs 'CURSOR'
    {
-     if (isHive()) {
-       suggestKeywords(['AVRO', 'INPUTFORMAT', 'ORC', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
-     } else {
-       suggestKeywords(['AVRO', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
-     }
+     suggestFileFormats();
    }
  ;
 
-HiveOrImpalaFormat
- : '<hive>FORMAT'
- | '<impala>FORMAT'
- ;
-
-HiveOrImpalaStored
- : '<hive>STORED'
- | '<impala>STORED'
- ;
-
 FileFormat
  : '<hive>AVRO'
  | '<hive>INPUTFORMAT' QuotedValue '<hive>OUTPUTFORMAT' QuotedValue
@@ -836,21 +812,6 @@ OptionalFieldsTerminatedBy_EDIT
    }
  ;
 
-HiveOrImpalaFields
- : '<hive>FIELDS'
- | '<impala>FIELDS'
- ;
-
-HiveOrImpalaTerminated
- : '<hive>TERMINATED'
- | '<impala>TERMINATED'
- ;
-
-HiveOrImpalaEscaped
- : '<hive>ESCAPED'
- | '<impala>ESCAPED'
- ;
-
 OptionalCollectionItemsTerminatedBy
  :
  | '<hive>COLLECTION' '<hive>ITEMS' '<hive>TERMINATED' 'BY' SingleQuotedValue
@@ -907,11 +868,6 @@ OptionalLinesTerminatedBy_EDIT
    }
  ;
 
-HiveOrImpalaLines
- : '<hive>LINES'
- | '<impala>LINES'
- ;
-
 OptionalNullDefinedAs
  :
  | 'NULL' '<hive>DEFINED' '<hive>AS' SingleQuotedValue
@@ -958,6 +914,11 @@ OptionalTblproperties
  | HiveOrImpalaTblproperties ParenthesizedPropertyAssignmentList
  ;
 
+OptionalHiveTblproperties
+ :
+ | '<hive>TBLPROPERTIES' ParenthesizedPropertyAssignmentList
+ ;
+
 OptionalAsSelectStatement
  :
  | AnyAs CommitLocations QuerySpecification
@@ -980,27 +941,577 @@ CommitLocations
 
 OptionalImpalaCachedIn
  :
- | '<impala>CACHED' 'IN' QuotedValue
+ | ImpalaCachedIn
  ;
 
 OptionalImpalaCachedIn_EDIT
+ : ImpalaCachedIn_EDIT
+ ;
+
+ImpalaCachedIn
+ : '<impala>CACHED' 'IN' SingleQuotedValue
+ ;
+
+ImpalaCachedIn_EDIT
  : '<impala>CACHED' 'CURSOR'
    {
      suggestKeywords(['IN']);
    }
  ;
 
-QuotedValue
+ViewDefinition
+ : AnyCreate AnyView OptionalIfNotExists SchemaQualifiedTableIdentifier OptionalParenthesizedViewColumnList OptionalComment OptionalHiveTblproperties AnyAs QuerySpecification
+ ;
+
+ViewDefinition_EDIT
+ : AnyCreate AnyView OptionalIfNotExists 'CURSOR'
+   {
+     if (!$3) {
+       suggestKeywords(['IF NOT EXISTS']);
+     }
+     suggestDatabases({ appendDot: true });
+   }
+ | AnyCreate AnyView OptionalIfNotExists 'CURSOR' SchemaQualifiedTableIdentifier OptionalParenthesizedViewColumnList OptionalComment OptionalHiveTblproperties AnyAs QuerySpecification
+   {
+     if (!$3) {
+       suggestKeywords(['IF NOT EXISTS']);
+     }
+   }
+ | AnyCreate AnyView OptionalIfNotExists_EDIT
+ | AnyCreate AnyView OptionalIfNotExists SchemaQualifiedTableIdentifier OptionalParenthesizedViewColumnList OptionalComment OptionalHiveTblproperties 'CURSOR'
+   {
+     if (isHive() && !$6 && !$7) {
+       suggestKeywords(['AS', 'COMMENT', 'TBLPROPERTIES']);
+     } else if (isHive() && !$7) {
+       suggestKeywords(['AS', 'TBLPROPERTIES']);
+     } else {
+       suggestKeywords(['AS']);
+     }
+   }
+ | AnyCreate AnyView OptionalIfNotExists SchemaQualifiedTableIdentifier OptionalParenthesizedViewColumnList OptionalComment OptionalHiveTblproperties AnyAs 'CURSOR'
+   {
+     suggestKeywords(['SELECT']);
+   }
+ | AnyCreate AnyView OptionalIfNotExists SchemaQualifiedTableIdentifier OptionalParenthesizedViewColumnList OptionalComment OptionalHiveTblproperties AnyAs QuerySpecification_EDIT
+ ;
+
+// TODO: rename SchemaQualifiedTableIdentifier to SchemaQualifiedIdentifier
+FunctionDefinition
+ : ImpalaFunctionDefinition
+ | ImpalaAggregateFunctionDefinition
+ | HiveFunctionDefinition
+ | HiveTemporaryFunction
+ ;
+
+FunctionDefinition_EDIT
+ : ImpalaFunctionDefinition_EDIT
+ | ImpalaAggregateFunctionDefinition_EDIT
+ | HiveFunctionDefinition_EDIT
+ | HiveTemporaryFunction_EDIT
+ ;
+
+ImpalaFunctionDefinition
+ : AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns HdfsLocation ImpalaSymbol
+ ;
+
+ImpalaFunctionDefinition_EDIT
+ : AnyCreate '<impala>FUNCTION' OptionalIfNotExists 'CURSOR'
+   {
+     if (!$3) {
+       suggestKeywords(['IF NOT EXISTS']);
+     }
+     suggestDatabases({ appendDot: true });
+   }
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists 'CURSOR' SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns HdfsLocation ImpalaSymbol
+   {
+     if (!$3) {
+       suggestKeywords(['IF NOT EXISTS']);
+     }
+   }
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList 'CURSOR'
+   {
+     suggestKeywords(['RETURNS']);
+   }
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns 'CURSOR'
+   {
+     suggestKeywords(['LOCATION']);
+   }
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns HdfsLocation 'CURSOR'
+   {
+     suggestKeywords(['SYMBOL']);
+   }
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists_EDIT
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList_EDIT
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns_EDIT
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns HdfsLocation_EDIT
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists_EDIT SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns HdfsLocation ImpalaSymbol
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList_EDIT ImpalaReturns HdfsLocation ImpalaSymbol
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns_EDIT HdfsLocation ImpalaSymbol
+ | AnyCreate '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns HdfsLocation_EDIT ImpalaSymbol
+ ;
+
+ImpalaAggregateFunctionDefinition
+ : AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ ;
+
+ImpalaAggregateFunctionDefinition
+ : AnyCreate '<impala>AGGREGATE' 'CURSOR'
+   {
+     suggestKeywords(['FUNCTION']);
+   }
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists 'CURSOR' SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+   {
+     if (!$4) {
+       suggestKeywords(['IF NOT EXISTS']);
+     }
+   }
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists 'CURSOR'
+   {
+     if (!$4) {
+       suggestKeywords(['IF NOT EXISTS']);
+     }
+     suggestDatabases({ appendDot: true });
+   }
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists_EDIT
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists_EDIT SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList_EDIT
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList_EDIT ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList 'CURSOR'
+   {
+     suggestKeywords(['RETURNS']);
+   }
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   'CURSOR'
+   {
+     suggestKeywords(['LOCATION']);
+   }
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn 'CURSOR'
+   {
+     if (!$9) {
+       suggestKeywords(['INIT_FN', 'UPDATE_FN']);
+     } else {
+       suggestKeywords(['UPDATE_FN']);
+     }
+   }
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn 'CURSOR'
+   {
+     suggestKeywords(['MERGE_FN']);
+   }
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn 'CURSOR'
+   {
+     if (!$12 && !$13 && !$14 && !$15) {
+       suggestKeywords(['CLOSE_FN', 'FINALIZE_FN', 'PREPARE_FN', 'SERIALIZE_FN']);
+     } else if ($12 && !$13 && !$14 && !$15) {
+       suggestKeywords(['CLOSE_FN', 'FINALIZE_FN', 'SERIALIZE_FN']);
+     } else if ($13 && !$14 && !$15) {
+       suggestKeywords(['FINALIZE_FN', 'SERIALIZE_FN']);
+     } else if ($14 && !$15) {
+       suggestKeywords(['FINALIZE_FN']);
+     }
+   }
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns_EDIT
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation_EDIT OptionalImpalaInitFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn_EDIT
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn_EDIT
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn_EDIT OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn_EDIT OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn_EDIT  OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn_EDIT OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn_EDIT
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns_EDIT
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation_EDIT OptionalImpalaInitFn ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn_EDIT ImpalaUpdateFn ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ | AnyCreate '<impala>AGGREGATE' '<impala>FUNCTION' OptionalIfNotExists SchemaQualifiedTableIdentifier ParenthesizedImpalaArgumentList ImpalaReturns
+   HdfsLocation OptionalImpalaInitFn ImpalaUpdateFn_EDIT ImpalaMergeFn OptionalImpalaPrepareFn OptionalImpalaCloseFn OptionalImpalaSerializeFn OptionalImpalaFinalizeFn
+ ;
+
+HiveFunctionDefinition
+ : AnyCreate '<hive>FUNCTION' SchemaQualifiedTableIdentifier '<hive>AS' SingleQuotedValue OptionalHiveUsing
+ ;
+
+HiveFunctionDefinition_EDIT
+ : AnyCreate '<hive>FUNCTION' SchemaQualifiedTableIdentifier 'CURSOR'
+   {
+     suggestKeywords(['AS']);
+   }
+ | AnyCreate '<hive>FUNCTION' SchemaQualifiedTableIdentifier '<hive>AS' SingleQuotedValue OptionalHiveUsing_EDIT
+ | AnyCreate '<hive>FUNCTION' SchemaQualifiedTableIdentifier '<hive>AS' SingleQuotedValue OptionalHiveUsing 'CURSOR'
+   {
+     if (!$6) {
+       suggestKeywords(['USING']);
+     } else {
+       suggestKeywords(['ARCHIVE', 'FILE', 'JAR']);
+     }
+   }
+ ;
+
+HiveTemporaryFunction
+ : AnyCreate '<hive>TEMPORARY' '<hive>FUNCTION' RegularIdentifier '<hive>AS' SingleQuotedValue
+ ;
+
+HiveTemporaryFunction_EDIT
+ : AnyCreate '<hive>TEMPORARY' '<hive>FUNCTION' RegularIdentifier 'CURSOR'
+   {
+     suggestKeywords(['AS']);
+   }
+ ;
+
+ParenthesizedImpalaArgumentList
+ : '(' ')'
+ | '(' ImpalaArgumentList OptionalVariableArguments')'
+ ;
+
+ParenthesizedImpalaArgumentList_EDIT
+ : '(' ImpalaArgumentList_EDIT RightParenthesisOrError
+   {
+     suggestKeywords(getTypeKeywords());
+   }
+ | '(' ImpalaArgumentList 'CURSOR' RightParenthesisOrError
+   {
+     suggestKeywords(['...']);
+   }
+ ;
+
+ImpalaArgumentList
+ : PrimitiveType
+ | ImpalaArgumentList ',' PrimitiveType
+ ;
+
+ImpalaArgumentList_EDIT
+ : AnyCursor
+ | ImpalaArgumentList ',' AnyCursor
+ | AnyCursor ',' ImpalaArgumentList
+ | ImpalaArgumentList ',' AnyCursor ',' ImpalaArgumentList
+ ;
+
+OptionalVariableArguments
+ :
+ | '<impala>...'
+ ;
+
+ImpalaReturns
+ : '<impala>RETURNS' PrimitiveType
+ ;
+
+ImpalaReturns_EDIT
+ : '<impala>RETURNS' 'CURSOR'
+   {
+     suggestKeywords(getTypeKeywords());
+   }
+ ;
+
+ImpalaSymbol
+ : '<impala>SYMBOL' '=' SingleQuotedValue
+ ;
+
+OptionalImpalaInitFn
+ :
+ | '<impala>INIT_FN' '=' FunctionReference
+ ;
+
+OptionalImpalaInitFn_EDIT
+ : '<impala>INIT_FN' '=' FunctionReference_EDIT
+ ;
+
+ImpalaUpdateFn
+ : '<impala>UPDATE_FN' '=' FunctionReference
+ ;
+
+ImpalaUpdateFn_EDIT
+ : '<impala>UPDATE_FN' '=' FunctionReference_EDIT
+ ;
+
+ImpalaMergeFn
+ : '<impala>MERGE_FN' '=' FunctionReference
+ ;
+
+ImpalaMergeFn_EDIT
+ : '<impala>MERGE_FN' '=' FunctionReference_EDIT
+ ;
+
+OptionalImpalaPrepareFn
+ :
+ | '<impala>PREPARE_FN' '=' FunctionReference
+ ;
+
+OptionalImpalaPrepareFn_EDIT
+ : '<impala>PREPARE_FN' '=' FunctionReference_EDIT
+ ;
+
+OptionalImpalaCloseFn
+ :
+ | '<impala>CLOSE_FN' '=' FunctionReference
+ ;
+
+OptionalImpalaCloseFn_EDIT
+ : '<impala>CLOSE_FN' '=' FunctionReference_EDIT
+ ;
+
+OptionalImpalaSerializeFn
+ :
+ | '<impala>SERIALIZE_FN' '=' FunctionReference
+ ;
+
+OptionalImpalaSerializeFn_EDIT
+ : '<impala>SERIALIZE_FN' '=' FunctionReference_EDIT
+ ;
+
+OptionalImpalaFinalizeFn
+ :
+ | '<impala>FINALIZE_FN' '=' FunctionReference
+ ;
+
+OptionalImpalaFinalizeFn_EDIT
+ : '<impala>FINALIZE_FN' '=' FunctionReference_EDIT
+
+ ;
+
+FunctionReference
  : SingleQuotedValue
- | DoubleQuotedValue
  ;
 
-HiveOrImpalaTblproperties
- : '<hive>TBLPROPERTIES'
- | '<impala>TBLPROPERTIES'
+FunctionReference_EDIT
+ : SingleQuotedValue_EDIT
+   {
+     suggestFunctions();
+     suggestAggregateFunctions();
+     suggestAnalyticFunctions();
+   }
+ ;
+
+OptionalHiveUsing
+ :
+ | '<hive>USING' OneOrMoreFunctionResources
+ ;
+
+OptionalHiveUsing_EDIT
+ : '<hive>USING' 'CURSOR'
+   {
+     suggestKeywords(['ARCHIVE', 'FILE', 'JAR']);
+   }
  ;
 
-HiveOrImpalaPartitioned
- : '<hive>PARTITIONED'
- | '<impala>PARTITIONED'
- ;
+OneOrMoreFunctionResources
+ : FunctionResource
+ | OneOrMoreFunctionResources ',' FunctionResource
+ ;
+
+FunctionResource
+ : FunctionResourceType SingleQuotedValue
+ ;
+
+FunctionResourceType
+ : '<hive>ARCHIVE'
+ | '<hive>FILE'
+ | '<hive>JAR'
+ ;
+
+AnyView
+ : '<hive>VIEW'
+ | 'VIEW'
+ ;
+
+OptionalParenthesizedViewColumnList
+ :
+ | ParenthesizedViewColumnList
+ ;
+
+ParenthesizedViewColumnList
+ : '(' ViewColumnList ')'
+ ;
+
+ViewColumnList
+ : ColumnReference OptionalComment
+ | ViewColumnList ',' ColumnReference OptionalComment
+ ;
+
+RoleDefinition
+ : AnyCreate AnyRole RegularIdentifier
+ ;
+
+AnyRole
+ : '<hive>ROLE'
+ | 'ROLE'
+ ;
+
+IndexDefinition
+ : AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList
+   '<hive>AS' IndexType OptionalWithDeferredRebuild OptionalIdxProperties OptionalInTable OptionalStoredAsOrBy OptionalHdfsLocation
+   OptionalTblproperties OptionalComment
+ ;
+
+ExistingTable
+ : SchemaQualifiedTableIdentifier
+   {
+     addTablePrimary($1);
+   }
+ ;
+
+ExistingTable_EDIT
+ : SchemaQualifiedTableIdentifier_EDIT
+ ;
+
+IndexDefinition_EDIT
+ : AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'CURSOR'
+   {
+     suggestKeywords(['ON TABLE']);
+   }
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' 'CURSOR'
+   {
+     suggestKeywords(['TABLE']);
+   }
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' 'CURSOR'
+   {
+     suggestTables();
+     suggestDatabases({ appendDot: true });
+   }
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable_EDIT
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList_EDIT
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList 'CURSOR'
+   {
+     suggestKeywords(['AS']);
+   }
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList
+   '<hive>AS' 'CURSOR'
+   {
+     suggestKeywords(['\'BITMAP\'', '\'COMPACT\'']);
+   }
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList
+   '<hive>AS' IndexType_EDIT OptionalWithDeferredRebuild OptionalIdxProperties OptionalInTable OptionalStoredAsOrBy OptionalHdfsLocation
+   OptionalTblproperties OptionalComment
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable_EDIT ParenthesizedIndexColumnList
+   '<hive>AS' IndexType OptionalWithDeferredRebuild OptionalIdxProperties OptionalInTable OptionalStoredAsOrBy OptionalHdfsLocation
+   OptionalTblproperties OptionalComment
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList_EDIT
+   '<hive>AS' IndexType OptionalWithDeferredRebuild OptionalIdxProperties OptionalInTable OptionalStoredAsOrBy OptionalHdfsLocation
+   OptionalTblproperties OptionalComment
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList
+   '<hive>AS' IndexType OptionalWithDeferredRebuild_EDIT OptionalIdxProperties OptionalInTable OptionalStoredAsOrBy OptionalHdfsLocation
+   OptionalTblproperties OptionalComment
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList
+   '<hive>AS' IndexType OptionalWithDeferredRebuild OptionalIdxProperties OptionalInTable_EDIT OptionalStoredAsOrBy OptionalHdfsLocation
+   OptionalTblproperties OptionalComment
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList
+   '<hive>AS' IndexType OptionalWithDeferredRebuild OptionalIdxProperties OptionalInTable OptionalStoredAsOrBy_EDIT OptionalHdfsLocation
+   OptionalTblproperties OptionalComment
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList
+   '<hive>AS' IndexType OptionalWithDeferredRebuild OptionalIdxProperties OptionalInTable OptionalStoredAsOrBy OptionalHdfsLocation_EDIT
+   OptionalTblproperties OptionalComment
+ | AnyCreate '<hive>INDEX' RegularOrBacktickedIdentifier 'ON' '<hive>TABLE' ExistingTable ParenthesizedIndexColumnList
+   '<hive>AS' IndexType OptionalWithDeferredRebuild OptionalIdxProperties OptionalInTable OptionalStoredAsOrBy OptionalHdfsLocation
+   OptionalTblproperties OptionalComment 'CURSOR'
+   {
+     if (!$10 && !$11 && !$12 && !$13 && !$14 && !$15 && !$16) {
+       suggestKeywords(['WITH DEFERRED REBUILD', 'IDXPROPERTIES', 'IN TABLE', 'ROW FORMAT', 'STORED AS', 'STORED BY', 'LOCATION', 'TBLPROPERTIES', 'COMMENT']);
+     } else if (!$11 && !$12 && !$13 && !$14 && !$15 && !$16) {
+       suggestKeywords(['IDXPROPERTIES', 'IN TABLE', 'ROW FORMAT', 'STORED AS', 'STORED BY', 'LOCATION', 'TBLPROPERTIES', 'COMMENT']);
+     } else if (!$12 && !$13 && !$14 && !$15 && !$16) {
+       suggestKeywords(['IN TABLE', 'ROW FORMAT', 'STORED AS', 'STORED BY', 'LOCATION', 'TBLPROPERTIES', 'COMMENT']);
+     } else if (!$13 && !$14 && !$15 && !$16) {
+       suggestKeywords(['ROW FORMAT', 'STORED AS', 'STORED BY', 'LOCATION', 'TBLPROPERTIES', 'COMMENT']);
+     } else if ($13 && $13.suggestKeywords && !$14 && !$15 && !$16) {
+       suggestKeywords($13.suggestKeywords.concat(['LOCATION', 'TBLPROPERTIES', 'COMMENT']));
+     } else if (!$14 && !$15 && !$16) {
+       suggestKeywords(['LOCATION', 'TBLPROPERTIES', 'COMMENT']);
+     } else if (!$15 && !$16) {
+       suggestKeywords(['TBLPROPERTIES', 'COMMENT']);
+     } else if (!$16) {
+       suggestKeywords(['COMMENT']);
+     }
+   }
+ ;
+
+// TODO: find index types https://cwiki.apache.org/confluence/display/Hive/IndexDev#IndexDev-CREATEINDEX
+IndexType
+ : QuotedValue
+ ;
+
+IndexType_EDIT
+ : QuotedValue_EDIT
+   {
+     suggestKeywords(['\'BITMAP\'', '\'COMPACT\'']);
+   }
+ ;
+
+OptionalWithDeferredRebuild
+ :
+ | 'WITH' '<hive>DEFERRED' '<hive>REBUILD'
+ ;
+
+OptionalWithDeferredRebuild_EDIT
+ : 'WITH' 'CURSOR'
+   {
+     suggestKeywords(['DEFERRED REBUILD']);
+   }
+ | 'WITH' '<hive>DEFERRED' 'CURSOR'
+   {
+     suggestKeywords(['REBUILD']);
+   }
+ ;
+
+OptionalIdxProperties
+ :
+ | '<hive>IDXPROPERTIES' ParenthesizedPropertyAssignmentList
+ ;
+
+OptionalInTable
+ :
+ | 'IN' '<hive>TABLE' SchemaQualifiedTableIdentifier
+ ;
+
+OptionalInTable_EDIT
+ : 'IN' 'CURSOR'
+   {
+     suggestKeywords(['TABLE']);
+   }
+ | 'IN' '<hive>TABLE' 'CURSOR'
+   {
+     suggestTables();
+     suggestDatabases({ appendDot: true });
+   }
+ | 'IN' '<hive>TABLE' SchemaQualifiedTableIdentifier_EDIT
+ ;
+
+
+ParenthesizedIndexColumnList
+ : '(' IndexColumnList ')'
+ ;
+
+ParenthesizedIndexColumnList_EDIT
+ : '(' IndexColumnList_EDIT RightParenthesisOrError
+   {
+     suggestColumns();
+   }
+ ;
+
+IndexColumnList
+ : ColumnReference
+ | IndexColumnList ',' ColumnReference
+ ;
+
+IndexColumnList_EDIT
+ : AnyCursor
+ | IndexColumnList ',' AnyCursor
+ | AnyCursor ',' IndexColumnList
+ | IndexColumnList ',' AnyCursor ',' IndexColumnList
+ ;

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

@@ -0,0 +1,106 @@
+// 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
+ : DropStatement
+ ;
+
+DataDefinition_EDIT
+ : DropStatement_EDIT
+ ;
+
+DropStatement
+ : DropDatabaseStatement
+ | DropTableStatement
+ ;
+
+DropStatement_EDIT
+ : 'DROP' 'CURSOR'
+   {
+     if (isHive()) {
+       suggestKeywords(['DATABASE', 'FUNCTION', 'INDEX', 'MACRO', 'ROLE', 'SCHEMA', 'TABLE', 'TEMPORARY FUNCTION', 'TEMPORARY MACRO', 'VIEW']);
+     } else if (isImpala()) {
+       suggestKeywords(['AGGREGATE FUNCTION', 'DATABASE', 'FUNCTION', 'INCREMENTAL STATS', 'ROLE', 'SCHEMA', 'STATS', 'TABLE', 'VIEW']);
+     } else {
+       suggestKeywords(['ROLE', 'SCHEMA', 'TABLE', 'VIEW']);
+     }
+   }
+ | DropDatabaseStatement_EDIT
+ | DropTableStatement_EDIT
+ ;
+
+DropDatabaseStatement
+ : 'DROP' DatabaseOrSchema OptionalIfExists RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
+ ;
+
+DropDatabaseStatement_EDIT
+ : 'DROP' DatabaseOrSchema OptionalIfExists
+ | 'DROP' DatabaseOrSchema OptionalIfExists_EDIT
+ | 'DROP' DatabaseOrSchema OptionalIfExists 'CURSOR'
+   {
+     if (!$3) {
+       suggestKeywords(['IF EXISTS']);
+     }
+     suggestDatabases();
+   }
+ | 'DROP' DatabaseOrSchema OptionalIfExists RegularOrBacktickedIdentifier 'CURSOR'
+   {
+     if (isHive()) {
+       suggestKeywords(['CASCADE', 'RESTRICT']);
+     }
+   }
+ | 'DROP' DatabaseOrSchema OptionalIfExists_EDIT RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
+ | 'DROP' DatabaseOrSchema OptionalIfExists 'CURSOR' RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
+   {
+     if (!$3) {
+       suggestKeywords(['IF EXISTS']);
+     }
+   }
+ ;
+
+DropTableStatement
+ : 'DROP' AnyTable OptionalIfExists TablePrimary
+ ;
+
+DropTableStatement_EDIT
+ : 'DROP' AnyTable OptionalIfExists_EDIT
+ | 'DROP' AnyTable OptionalIfExists 'CURSOR'
+   {
+     if (!$3) {
+       suggestKeywords(['IF EXISTS']);
+     }
+     suggestTables();
+     suggestDatabases({
+       appendDot: true
+     });
+   }
+ | 'DROP' AnyTable OptionalIfExists TablePrimary_EDIT
+   {
+     if ($4.identifierChain && $4.identifierChain.length === 1) {
+       suggestTablesOrColumns($4.identifierChain[0].name);
+     } else if ($4.identifierChain && $4.identifierChain.length === 0) {
+       suggestTables();
+       suggestDatabases({ appendDot: true });
+     }
+   }
+ | 'DROP' AnyTable OptionalIfExists_EDIT TablePrimary
+ | 'DROP' AnyTable OptionalIfExists TablePrimary 'CURSOR'
+   {
+     if (isHive()) {
+       suggestKeywords(['PURGE']);
+     }
+   }
+ ;

+ 226 - 114
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/sql_main.jison

@@ -29,41 +29,66 @@
 %%
 
 NonReservedKeyword
- : '<hive>AVRO'
+ : '<hive>ADD'
+ | '<hive>AVRO'
+ | '<hive>AFTER'
+ | '<hive>ARCHIVE'
  | '<hive>BUCKETS'
+ | '<hive>CASCADE'
+ | '<hive>CHANGE'
  | '<hive>CLUSTERED'
  | '<hive>COLLECTION'
  | '<hive>COLUMNS'
  | '<hive>COMMENT'
+ | '<hive>COMPACT'
  | '<hive>COMPACTIONS'
+ | '<hive>CONCATENATE'
  | '<hive>DATA'
  | '<hive>DATABASES'
+ | '<hive>DEFERRED'
  | '<hive>DEFINED'
  | '<hive>DELIMITED'
+ | '<hive>DISABLE'
+ | '<hive>ENABLE'
  | '<hive>ESCAPED'
+ | '<hive>EXCHANGE'
  | '<hive>FIELDS'
+ | '<hive>FILE'
+ | '<hive>FILEFORMAT'
+ | '<hive>FIRST'
  | '<hive>FORMAT'
  | '<hive>FUNCTIONS'
  | '<hive>INPATH'
  | '<hive>INPUTFORMAT'
+ | '<hive>JAR'
+ | '<hive>IDXPROPERTIES'
  | '<hive>ITEMS'
  | '<hive>KEYS'
  | '<hive>LINES'
  | '<hive>LOAD'
  | '<hive>LOCATION'
  | '<hive>LOCKS'
+ | '<hive>NO_DROP'
+ | '<hive>OFFLINE'
  | '<hive>ORC'
  | '<hive>OUTPUTFORMAT'
  | '<hive>PARQUET'
  | '<hive>PARTITIONED'
  | '<hive>PARTITIONS'
+ | '<hive>PURGE'
  | '<hive>RCFILE'
+ | '<hive>REBUILD'
+ | '<hive>RECOVER'
+ | '<hive>RENAME'
+ | '<hive>REPLACE'
+ | '<hive>RESTRICT'
  | '<hive>ROLE'
  | '<hive>ROLES'
  | '<hive>SCHEMAS'
  | '<hive>SEQUENCEFILE'
  | '<hive>SERDE'
  | '<hive>SERDEPROPERTIES'
+ | '<hive>SHOW'
  | '<hive>SKEWED'
  | '<hive>SORTED'
  | '<hive>STORED'
@@ -75,25 +100,33 @@ NonReservedKeyword
  | '<hive>TERMINATED'
  | '<hive>TEXTFILE'
  | '<hive>TINYINT'
+ | '<hive>TOUCH'
  | '<hive>TRANSACTIONS'
+ | '<hive>UNARCHIVE'
  | '<hive>UNIONTYPE'
  | '<hive>USE'
  | '<hive>VIEW'
-// | '<hive>ASC'      // These cause conflicts, we need separate lexer state for DESCRIBE and SHOW then it should be fine
+// | '<hive>ASC'      // These cause conflicts, we could use a separate lexer state for DESCRIBE, ALTER and SHOW
 // | '<hive>DESC'
 // | '<hive>FORMATTED'
+// | '<hive>FUNCTION'
 // | '<hive>INDEX'
 // | '<hive>INDEXES'
 // | '<hive>LIMIT'
 // | '<hive>SCHEMA'
-// | '<hive>SHOW'
- | '<impala>ANALYTIC'
+ ;
+
+NonReservedKeyword
+ : '<impala>ANALYTIC'
  | '<impala>ANTI'
  | '<impala>CURRENT'
  | '<impala>GRANT'
  | '<impala>ROLE'
  | '<impala>ROLES'
- | 'ROLE'
+ ;
+
+NonReservedKeyword
+ : 'ROLE'
  ;
 
 RegularIdentifier
@@ -138,8 +171,8 @@ ErrorStatement
 // 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>AVRO' | '<hive>BINARY' | '<hive>BUCKETS' | '<hive>AS' | '<hive>CLUSTERED' | '<hive>COLLECTION' | '<hive>CONF' | '<hive>CROSS' | '<hive>CURRENT' | '<hive>DATE' | '<hive>DELIMITED' | '<hive>ESCAPED' | '<hive>EXTENDED' | '<hive>EXTERNAL' | '<hive>FIELDS' | '<hive>FORMAT' | '<hive>FUNCTION' | '<hive>GRANT' | '<hive>LATERAL' | '<hive>MACRO' | '<hive>TABLE' | '<hive>USER' | '<hive>ASC' | '<hive>COLUMNS' | '<hive>COMMENT' | '<hive>COMPACTIONS' | '<hive>DATA' | '<hive>DATABASES' | '<hive>DEFINED' | '<hive>DESC' | '<hive>STORED_AS_DIRECTORIES' | '<hive>FORMATTED' | '<hive>FUNCTIONS' | '<hive>INDEX' | '<hive>INDEXES' | '<hive>INPATH' | '<hive>INPUTFORMAT' | '<hive>ITEMS' | '<hive>LIMIT' | '<hive>KEYS' | '<hive>LINES' | '<hive>LOCATION' | '<hive>LOCKS' | '<hive>MAP' | '<hive>ORC' | '<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>STRING' | '<hive>STRUCT' | '<hive>TABLES' | '<hive>TBLPROPERTIES' | '<hive>TEMPORARY' | '<hive>TERMINATED' | '<hive>TEXTFILE' | '<hive>TINYINT' | '<hive>TRANSACTIONS' | '<hive>UNIONTYPE' | '<hive>VIEW' | '<hive>WINDOW' | '<hive>.' | '<hive>[' | '<hive>]'
- | '<impala>AGGREGATE' | '<impala>AVRO' | '<impala>CACHED' | '<impala>COLUMN' | '<impala>COMMENT' | '<impala>DATA' | '<impala>DATABASES' | '<impala>DELIMITED' | '<impala>ESCAPED' | '<impala>EXTERNAL' | '<impala>FIELDS' | '<impala>FIRST' | '<impala>FORMAT' | '<impala>FORMATTED' | '<impala>FUNCTION' | '<impala>FUNCTIONS' | '<impala>GROUP' | '<impala>INCREMENTAL' | '<impala>INPATH' | '<impala>LAST' | '<impala>LINES' | '<impala>LOCATION' | '<impala>NULLS' | '<impala>PARTITIONS' | '<impala>REAL' | '<impala>SCHEMAS' | '<impala>STATS' | '<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>BROADCAST' | '<impala>.' | '<impala>[' | '<impala>]'
+ : '<hive>ALL' | '<hive>ARRAY' | '<hive>AVRO' | '<hive>BINARY' | '<hive>BUCKETS' | '<hive>AS' | '<hive>CLUSTERED' | '<hive>COLLECTION' | '<hive>CONF' | '<hive>CROSS' | '<hive>CURRENT' | '<hive>DATE' | '<hive>DEFERRED' | '<hive>DELIMITED' | '<hive>ESCAPED' | '<hive>EXTENDED' | '<hive>EXTERNAL' | '<hive>FIELDS' | '<hive>FILE' | '<hive>FORMAT' | '<hive>FUNCTION' | '<hive>GRANT' | '<hive>IDXPROPERTIES' | '<hive>LATERAL' | '<hive>MACRO' | '<hive>PARTITION' | '<hive>REBUILD' | '<hive>TABLE' | '<hive>USER' | '<hive>ASC' | '<hive>COLUMNS' | '<hive>COMMENT' | '<hive>COMPACTIONS' | '<hive>DATA' | '<hive>DATABASES' | '<hive>DEFINED' | '<hive>DESC' | '<hive>STORED_AS_DIRECTORIES' | '<hive>FORMATTED' | '<hive>FUNCTIONS' | '<hive>INDEX' | '<hive>INDEXES' | '<hive>INPATH' | '<hive>INPUTFORMAT' | '<hive>ITEMS' | '<hive>JAR' | '<hive>LIMIT' | '<hive>KEYS' | '<hive>LINES' | '<hive>LOCATION' | '<hive>LOCKS' | '<hive>MAP' | '<hive>ORC' | '<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>STRING' | '<hive>STRUCT' | '<hive>TABLES' | '<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>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>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' | 'GROUPING' | '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' | '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'
@@ -167,12 +200,10 @@ SqlStatement_EDIT
 
 DataDefinition
  : DescribeStatement
- | DropStatement
  ;
 
 DataDefinition_EDIT
  : DescribeStatement_EDIT
- | DropStatement_EDIT
  ;
 
 DataManipulation
@@ -191,6 +222,16 @@ AggregateOrAnalytic
  | '<impala>ANALYTIC'
  ;
 
+Commas
+ : ','
+ | Commas ','
+ ;
+
+AnyAs
+ : 'AS'
+ | '<hive>AS'
+ ;
+
 AnyCreate
  : 'CREATE'
  | '<hive>CREATE'
@@ -213,6 +254,17 @@ AnyFromOrIn
  | 'IN'
  ;
 
+AnyGroup
+ : 'GROUP'
+ | '<hive>GROUP'
+ | '<impala>GROUP'
+ ;
+
+AnyPartition
+ : 'PARTITION'
+ | '<hive>PARTITION'
+ ;
+
 AnyTable
  : 'TABLE'
  | '<hive>TABLE'
@@ -262,11 +314,26 @@ HiveOrImpalaDatabasesOrSchemas
  | '<impala>SCHEMAS'
  ;
 
+HiveOrImpalaEscaped
+ : '<hive>ESCAPED'
+ | '<impala>ESCAPED'
+ ;
+
 HiveOrImpalaExternal
  : '<hive>EXTERNAL'
  | '<impala>EXTERNAL'
  ;
 
+HiveOrImpalaFields
+ : '<hive>FIELDS'
+ | '<impala>FIELDS'
+ ;
+
+HiveOrImpalaFormat
+ : '<hive>FORMAT'
+ | '<impala>FORMAT'
+ ;
+
 HiveOrImpalaLoad
  : '<hive>LOAD'
  | '<impala>LOAD'
@@ -282,6 +349,11 @@ HiveOrImpalaLeftSquareBracket
  | '<impala>['
  ;
 
+HiveOrImpalaLines
+ : '<hive>LINES'
+ | '<impala>LINES'
+ ;
+
 HiveOrImpalaLocation
  : '<hive>LOCATION'
  | '<impala>LOCATION'
@@ -292,11 +364,31 @@ HiveOrImpalaRightSquareBracket
  | '<impala>]'
  ;
 
+HiveOrImpalaPartitioned
+ : '<hive>PARTITIONED'
+ | '<impala>PARTITIONED'
+ ;
+
+HiveOrImpalaStored
+ : '<hive>STORED'
+ | '<impala>STORED'
+ ;
+
 HiveOrImpalaTables
  : '<hive>TABLES'
  | '<impala>TABLES'
  ;
 
+HiveOrImpalaTblproperties
+ : '<hive>TBLPROPERTIES'
+ | '<impala>TBLPROPERTIES'
+ ;
+
+HiveOrImpalaTerminated
+ : '<hive>TERMINATED'
+ | '<impala>TERMINATED'
+ ;
+
 HiveRoleOrUser
  : '<hive>ROLE'
  | '<hive>USER'
@@ -307,20 +399,24 @@ SingleQuotedValue
  | 'SINGLE_QUOTE' 'SINGLE_QUOTE'          -> ''
  ;
 
+SingleQuotedValue_EDIT
+ : 'SINGLE_QUOTE' 'PARTIAL_VALUE'
+ ;
+
+
 DoubleQuotedValue
  : 'DOUBLE_QUOTE' 'VALUE' 'DOUBLE_QUOTE'  -> $2
  | 'DOUBLE_QUOTE' 'DOUBLE_QUOTE'          -> ''
  ;
 
-AnyAs
- : 'AS'
- | '<hive>AS'
+QuotedValue
+ : SingleQuotedValue
+ | DoubleQuotedValue
  ;
 
-AnyGroup
- : 'GROUP'
- | '<hive>GROUP'
- | '<impala>GROUP'
+QuotedValue_EDIT
+ : SingleQuotedValue_EDIT
+ | DoubleQuotedValue_EDIT
  ;
 
 OptionalAggregateOrAnalytic
@@ -339,6 +435,12 @@ OptionalExtendedOrFormatted
  | '<hive>FORMATTED'
  ;
 
+OptionalExternal
+ :
+ | '<hive>EXTERNAL'
+ | '<impala>EXTERNAL'
+ ;
+
 OptionalFormatted
  :
  | '<impala>FORMATTED'
@@ -375,6 +477,11 @@ OptionalHiveCascadeOrRestrict
  | '<hive>RESTRICT'
  ;
 
+OptionalHiveTemporary
+ :
+ | '<hive>TEMPORARY'
+ ;
+
 OptionalIfExists
  :
  | 'IF' 'EXISTS'
@@ -415,6 +522,23 @@ OptionalInDatabase
  | 'IN' DatabaseIdentifier_EDIT
  ;
 
+OptionalPartitionSpec
+ :
+ | PartitionSpec
+ ;
+
+OptionalPartitionSpec_EDIT
+ : PartitionSpec_EDIT
+ ;
+
+PartitionSpec
+ : AnyPartition '(' PartitionSpecList ')'
+ ;
+
+PartitionSpec_EDIT
+ : AnyPartition '(' PartitionSpecList_EDIT RightParenthesisOrError
+ ;
+
 ConfigurationName
  : RegularIdentifier
  | 'CURSOR'
@@ -446,6 +570,48 @@ RightParenthesisOrError
  | error
  ;
 
+ParenthesizedColumnList
+ : '(' ColumnList ')'
+ ;
+
+ParenthesizedColumnList_EDIT
+ : '(' ColumnList_EDIT RightParenthesisOrError
+ | '(' AnyCursor RightParenthesisOrError
+   {
+     suggestColumns();
+   }
+ ;
+
+ColumnList
+ : ColumnIdentifier
+ | ColumnList ',' ColumnIdentifier
+ ;
+
+ColumnList_EDIT
+ : ColumnIdentifier_EDIT
+ | ColumnList ',' AnyCursor
+   {
+     suggestColumns();
+   }
+ | ColumnList ',' ColumnIdentifier_EDIT
+ | ColumnIdentifier_EDIT ',' ColumnList
+ | ColumnList ',' ColumnIdentifier_EDIT ',' ColumnList
+ | ColumnList ',' AnyCursor ',' ColumnList
+   {
+     suggestColumns();
+   }
+ ;
+
+
+ParenthesizedSimpleValueList
+ : '(' SimpleValueList ')'
+ ;
+
+SimpleValueList
+ : UnsignedValueSpecification
+ | SimpleValueList ',' UnsignedValueSpecification
+ ;
+
 SchemaQualifiedTableIdentifier
  : RegularOrBacktickedIdentifier
    {
@@ -490,12 +656,36 @@ DatabaseIdentifier_EDIT
  ;
 
 PartitionSpecList
- : PartitionSpec
- | PartitionSpecList ',' PartitionSpec
+ : PartitionExpression
+ | PartitionSpecList ',' PartitionExpression
  ;
 
-PartitionSpec
- : RegularOrBacktickedIdentifier '=' SingleQuotedValue
+PartitionSpecList_EDIT
+ : PartitionExpression_EDIT
+ | PartitionSpecList ',' PartitionExpression_EDIT
+ | PartitionExpression_EDIT ',' PartitionSpecList
+ | PartitionSpecList ',' PartitionExpression_EDIT ',' PartitionSpecList
+ ;
+
+PartitionExpression
+ : ColumnIdentifier '=' ValueExpression
+ | ColumnIdentifier // Hive allows partial partition specs in some cases
+ ;
+
+PartitionExpression_EDIT
+ : ColumnIdentifier '=' ValueExpression_EDIT
+ | ColumnIdentifier '=' AnyCursor
+   {
+     valueExpressionSuggest();
+   }
+ | PartialBacktickedIdentifier '=' ValueExpression
+   {
+     suggestColumns();
+   }
+ | AnyCursor
+   {
+     suggestColumns();
+   }
  ;
 
 RegularOrBacktickedIdentifier
@@ -819,91 +1009,6 @@ ImpalaDescribeStatement_EDIT
    }
  ;
 
-// ===================================== DROP Statement =====================================
-
-DropStatement
- : DropDatabaseStatement
- | DropTableStatement
- ;
-
-DropStatement_EDIT
- : 'DROP' 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['DATABASE', 'FUNCTION', 'INDEX', 'MACRO', 'ROLE', 'SCHEMA', 'TABLE', 'TEMPORARY FUNCTION', 'TEMPORARY MACRO', 'VIEW']);
-     } else if (isImpala()) {
-       suggestKeywords(['AGGREGATE FUNCTION', 'DATABASE', 'FUNCTION', 'INCREMENTAL STATS', 'ROLE', 'SCHEMA', 'STATS', 'TABLE', 'VIEW']);
-     } else {
-       suggestKeywords(['ROLE', 'SCHEMA', 'TABLE', 'VIEW']);
-     }
-   }
- | DropDatabaseStatement_EDIT
- | DropTableStatement_EDIT
- ;
-
-DropDatabaseStatement
- : 'DROP' DatabaseOrSchema OptionalIfExists RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
- ;
-
-DropDatabaseStatement_EDIT
- : 'DROP' DatabaseOrSchema OptionalIfExists
- | 'DROP' DatabaseOrSchema OptionalIfExists_EDIT
- | 'DROP' DatabaseOrSchema OptionalIfExists 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['IF EXISTS']);
-     }
-     suggestDatabases();
-   }
- | 'DROP' DatabaseOrSchema OptionalIfExists RegularOrBacktickedIdentifier 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['CASCADE', 'RESTRICT']);
-     }
-   }
- | 'DROP' DatabaseOrSchema OptionalIfExists_EDIT RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
- | 'DROP' DatabaseOrSchema OptionalIfExists 'CURSOR' RegularOrBacktickedIdentifier OptionalHiveCascadeOrRestrict
-   {
-     if (!$3) {
-       suggestKeywords(['IF EXISTS']);
-     }
-   }
- ;
-
-DropTableStatement
- : 'DROP' AnyTable OptionalIfExists TablePrimary
- ;
-
-DropTableStatement_EDIT
- : 'DROP' AnyTable OptionalIfExists_EDIT
- | 'DROP' AnyTable OptionalIfExists 'CURSOR'
-   {
-     if (!$3) {
-       suggestKeywords(['IF EXISTS']);
-     }
-     suggestTables();
-     suggestDatabases({
-       appendDot: true
-     });
-   }
- | 'DROP' AnyTable OptionalIfExists TablePrimary_EDIT
-   {
-     if ($4.identifierChain && $4.identifierChain.length === 1) {
-       suggestTablesOrColumns($4.identifierChain[0].name);
-     } else if ($4.identifierChain && $4.identifierChain.length === 0) {
-       suggestTables();
-       suggestDatabases({ appendDot: true });
-     }
-   }
- | 'DROP' AnyTable OptionalIfExists_EDIT TablePrimary
- | 'DROP' AnyTable OptionalIfExists TablePrimary 'CURSOR'
-   {
-     if (isHive()) {
-       suggestKeywords(['PURGE']);
-     }
-   }
- ;
-
 // ===================================== LOAD statement =====================================
 
 LoadStatement
@@ -2160,19 +2265,19 @@ WindowExpression_EDIT
 
 OptionalPartitionBy
  :
- | 'PARTITION' 'BY' ValueExpressionList
+ | AnyPartition 'BY' ValueExpressionList
  ;
 
 OptionalPartitionBy_EDIT
- : 'PARTITION' 'CURSOR'
+ : AnyPartition 'CURSOR'
    {
      suggestKeywords(['BY']);
    }
- | 'PARTITION' 'BY' 'CURSOR'
+ | AnyPartition 'BY' 'CURSOR'
    {
      valueExpressionSuggest();
    }
- | 'PARTITION' 'BY' ValueExpressionList_EDIT
+ | AnyPartition 'BY' ValueExpressionList_EDIT
  ;
 
 OptionalOrderByAndWindow
@@ -2201,7 +2306,7 @@ OptionalOrderByAndWindow_EDIT
 
 OptionalWindowSpec
  :
- | RowsOrRange 'BETWEEN' PopBetweenState OptionalCurrentOrPreceding OptionalAndFollowing
+ | RowsOrRange 'BETWEEN' PopLexerState OptionalCurrentOrPreceding OptionalAndFollowing
  ;
 
 OptionalWindowSpec_EDIT
@@ -2209,7 +2314,7 @@ OptionalWindowSpec_EDIT
    {
      suggestKeywords(['BETWEEN']);
    }
- | RowsOrRange 'BETWEEN' PopBetweenState OptionalCurrentOrPreceding OptionalAndFollowing 'CURSOR'
+ | RowsOrRange 'BETWEEN' PopLexerState OptionalCurrentOrPreceding OptionalAndFollowing 'CURSOR'
    {
      if (!$4 && !$5) {
        suggestKeywords(['CURRENT ROW', 'UNBOUNDED PRECEDING']);
@@ -2217,17 +2322,24 @@ OptionalWindowSpec_EDIT
        suggestKeywords(['AND']);
      }
    }
- | RowsOrRange 'BETWEEN' PopBetweenState OptionalCurrentOrPreceding_EDIT OptionalAndFollowing
- | RowsOrRange 'BETWEEN' PopBetweenState OptionalCurrentOrPreceding OptionalAndFollowing_EDIT
+ | RowsOrRange 'BETWEEN' PopLexerState OptionalCurrentOrPreceding_EDIT OptionalAndFollowing
+ | RowsOrRange 'BETWEEN' PopLexerState OptionalCurrentOrPreceding OptionalAndFollowing_EDIT
  ;
 
-PopBetweenState
+PopLexerState
  :
   {
     lexer.popState();
   }
  ;
 
+PushHdfsLexerState
+ :
+  {
+    lexer.begin('hdfs');
+  }
+ ;
+
 RowsOrRange
  : 'ROWS'
  | 'RANGE'

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

@@ -353,11 +353,11 @@ ShowLocksStatement
    {
      addTablePrimary($3);
    }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName 'PARTITION' '(' PartitionSpecList ')'
+ | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName PartitionSpec
    {
      addTablePrimary($3);
    }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName 'PARTITION' '(' PartitionSpecList ')' '<hive>EXTENDED'
+ | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName PartitionSpec '<hive>EXTENDED'
    {
      addTablePrimary($3);
    }
@@ -380,13 +380,13 @@ ShowLocksStatement_EDIT
       suggestKeywords(['EXTENDED', 'PARTITION']);
     }
  | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT '<hive>EXTENDED'
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT 'PARTITION' '(' PartitionSpecList ')'
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName 'PARTITION' '(' PartitionSpecList ')' 'CURSOR'
+ | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT PartitionSpec
+ | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName PartitionSpec 'CURSOR'
    {
      addTablePrimary($3);
      suggestKeywords(['EXTENDED']);
    }
- | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT 'PARTITION' '(' PartitionSpecList ')' '<hive>EXTENDED'
+ | AnyShow '<hive>LOCKS' RegularOrBackTickedSchemaQualifiedName_EDIT PartitionSpec '<hive>EXTENDED'
  | AnyShow '<hive>LOCKS' DatabaseOrSchema 'CURSOR'
    {
      suggestDatabases();
@@ -398,7 +398,7 @@ ShowPartitionsStatement
    {
      addTablePrimary($3);
    }
- | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName 'PARTITION' PartitionSpecList
+ | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName PartitionSpec
    {
      addTablePrimary($3);
    }
@@ -422,7 +422,7 @@ ShowPartitionsStatement_EDIT
      addTablePrimary($3);
      suggestKeywords(['PARTITION']);
    }
- | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName_EDIT 'PARTITION' PartitionSpecList
+ | AnyShow '<hive>PARTITIONS' RegularOrBackTickedSchemaQualifiedName_EDIT PartitionSpec
  | AnyShow '<impala>PARTITIONS' 'CURSOR'
    {
      suggestTables();
@@ -476,7 +476,7 @@ ShowRolesStatement
 
 ShowTableStatement
  : AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue 'PARTITION' PartitionSpecList
+ | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'LIKE' SingleQuotedValue PartitionSpec
  ;
 
 ShowTableStatement_EDIT
@@ -509,12 +509,12 @@ ShowTableStatement_EDIT
     {
       suggestKeywords(['PARTITION']);
     }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase_EDIT 'LIKE' SingleQuotedValue 'PARTITION' PartitionSpecList
- | AnyShow '<hive>TABLE' 'CURSOR' OptionalFromDatabase 'LIKE' SingleQuotedValue 'PARTITION' PartitionSpecList
+ | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase_EDIT 'LIKE' SingleQuotedValue PartitionSpec
+ | AnyShow '<hive>TABLE' 'CURSOR' OptionalFromDatabase 'LIKE' SingleQuotedValue PartitionSpec
    {
      suggestKeywords(['EXTENDED']);
    }
- | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'CURSOR' SingleQuotedValue 'PARTITION' PartitionSpecList
+ | AnyShow '<hive>TABLE' '<hive>EXTENDED' OptionalFromDatabase 'CURSOR' SingleQuotedValue PartitionSpec
    {
      suggestKeywords(['LIKE']);
    }

File diff ditekan karena terlalu besar
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/sql.js


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

@@ -578,6 +578,14 @@ var suggestNumbers = function (numbers) {
   parser.yy.result.suggestNumbers = numbers;
 };
 
+var suggestFileFormats = function () {
+  if (isHive()) {
+    suggestKeywords(['AVRO', 'INPUTFORMAT', 'ORC', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
+  } else {
+    suggestKeywords(['AVRO', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']);
+  }
+};
+
 var suggestDdlAndDmlKeywords = function () {
   var keywords = ['ALTER', 'CREATE', 'DELETE', 'DESCRIBE', 'DROP', 'EXPLAIN', 'INSERT', 'REVOKE', 'SELECT', 'SET', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE'];
 

+ 1 - 1
desktop/core/src/desktop/static/desktop/js/sqlAutocompleter2.js

@@ -474,7 +474,7 @@
   };
 
   var extraHiveReservedKeywords = {
-    ASC: true, DESC: true, FORMATTED: true, INDEX: true, INDEXES: true, LIMIT: true, SCHEMA: true, SHOW: true
+    ASC: true, DESC: true, FORMATTED: true, FUNCTION: true, INDEX: true, INDEXES: true, LIMIT: true, SCHEMA: true
   };
 
   var impalaReservedKeywords = {

+ 1 - 0
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpec.js

@@ -17,6 +17,7 @@ define([
   'knockout',
   'desktop/js/autocomplete/sql',
   'desktop/spec/autocompleterTestUtils',
+  'desktop/spec/autocomplete/sqlSpecAlter',
   'desktop/spec/autocomplete/sqlSpecCreate',
   'desktop/spec/autocomplete/sqlSpecDescribe',
   'desktop/spec/autocomplete/sqlSpecDrop',

+ 1570 - 0
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecAlter.js

@@ -0,0 +1,1570 @@
+// 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 ALTER statements', function() {
+
+    beforeAll(function () {
+      sql.yy.parseError = function (msg) {
+        throw Error(msg);
+      };
+      jasmine.addMatchers(testUtils.testDefinitionMatcher);
+    });
+
+    var assertAutoComplete = testUtils.assertAutocomplete;
+
+    describe('ALTER TABLE statements', function () {
+      it('should suggest keywords for "ALTER |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'ALTER ',
+          afterCursor: '',
+          containsKeywords: ['TABLE'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should suggest tables for "ALTER TABLE |"', function() {
+        assertAutoComplete({
+          beforeCursor: 'ALTER TABLE ',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest tables for "ALTER TABLE foo.|"', function() {
+        assertAutoComplete({
+          beforeCursor: 'ALTER TABLE foo.',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: { database: 'foo' }
+          }
+        });
+      });
+
+      describe('Hive specific', function () {
+        it('should handle "ALTER TABLE foo PARTITION (ds=\'2008-04-08\', hr) CHANGE COLUMN dec_column_name dec_column_name DECIMAL;|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE foo PARTITION (ds=\'2008-04-08\', hr) CHANGE COLUMN dec_column_name dec_column_name DECIMAL;',
+            afterCursor: '',
+            dialect: 'hive',
+            containsKeywords: ['SELECT'],
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should handle "ALTER TABLE page_view DROP PARTITION (dt=\'2008-08-08\', country=\'us\');|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE page_view DROP PARTITION (dt=\'2008-08-08\', country=\'us\');',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should handle "ALTER TABLE page_view ADD PARTITION (dt=\'2008-08-08\', country=\'us\') location \'/path/to/us/part080808\'\nPARTITION (dt=\'2008-08-09\', country=\'us\') location \'/path/to/us/part080809\';|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE page_view ADD PARTITION (dt=\'2008-08-08\', country=\'us\') location \'/path/to/us/part080808\'\nPARTITION (dt=\'2008-08-09\', country=\'us\') location \'/path/to/us/part080809\';',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['ADD COLUMNS', 'ADD IF NOT EXISTS', 'ADD PARTITION', 'ARCHIVE PARTITION', 'CHANGE',
+                'CLUSTERED BY', 'COMPACT', 'CONCATENATE', 'DISABLE NO_DROP', 'DISABLE OFFLINE', 'DROP',  'ENABLE NO_DROP',
+                'ENABLE OFFLINE', 'EXCHANGE PARTITION', 'NOT SKEWED', 'NOT STORED AS DIRECTORIES',  'PARTITION',
+                'RECOVER PARTITIONS', 'RENAME TO', 'REPLACE COLUMNS', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDE',
+                'SET SERDEPROPERTIES', 'SET SKEWED LOCATION', 'SET TBLPROPERTIES', 'SKEWED BY', 'TOUCH', 'UNARCHIVE PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COLUMNS', 'IF NOT EXISTS', 'PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD COLUMNS (boo |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD COLUMNS (boo ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['INT', 'STRUCT<>'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD COLUMNS (boo INT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD COLUMNS (boo INT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COMMENT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD COLUMNS (boo INT) |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD COLUMNS (boo INT) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CASCADE', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD IF |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['NOT EXISTS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD IF NOT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF NOT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['EXISTS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD IF NOT EXISTS |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF NOT EXISTS ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD IF NOT EXISTS PARTITION (dt=\'2008-08-08\', country=\'us\') |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF NOT EXISTS PARTITION (dt=\'2008-08-08\', country=\'us\')  ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['LOCATION', 'PARTITION']
+            }
+          });
+        });
+
+        it('should suggest hdfs for "ALTER TABLE bar ADD IF NOT EXISTS PARTITION (dt=\'2008-08-08\', country=\'us\') LOCATION \'|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF NOT EXISTS PARTITION (dt=\'2008-08-08\', country=\'us\') LOCATION \'',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestHdfs: { path: '' }
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar ADD PARTITION (dt=\'2008-08-08\', |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF NOT EXISTS PARTITION (dt=\'2008-08-08\', ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar ADD PARTITION (dt=\'2008-08-08\') LOCATION \'/boo\' PARTITION (|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF NOT EXISTS PARTITION (dt=\'2008-08-08\') LOCATION \'/boo\' PARTITION  (',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD PARTITION (dt=\'2008-08-08\') LOCATION \'/boo\' PARTITION (baa=1) "', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF NOT EXISTS PARTITION (dt=\'2008-08-08\') LOCATION \'/boo\' PARTITION (baa=1) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['LOCATION', 'PARTITION']
+            }
+          });
+        });
+
+        it('should suggest hdfs for "ALTER TABLE bar ADD PARTITION (dt=\'2008-08-08\') LOCATION \'/boo\' PARTITION (country=\'us\') LOCATION \'"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD IF NOT EXISTS PARTITION (dt=\'2008-08-08\') LOCATION \'/boo\' PARTITION (country=\'us\') LOCATION \'',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestHdfs: { path: '' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ARCHIVE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ARCHIVE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITION']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar CHANGE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' },
+              suggestKeywords: ['COLUMN']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CHANGE boo baa |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE boo baa ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['ARRAY<>', 'INT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CHANGE boo baa INT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE boo baa INT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AFTER', 'CASCADE', 'COMMENT', 'FIRST', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CHANGE boo baa INT COMMENT \'ble\' |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE boo baa INT COMMENT \'ble\' ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AFTER', 'CASCADE', 'FIRST', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar CHANGE boo baa INT COMMENT \'ble\' AFTER |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE boo baa INT COMMENT \'ble\' AFTER ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar'}
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar CHANGE boo baa INT FIRST |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE boo baa INT FIRST ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar'}
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CHANGE boo baa INT FIRST ba |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE boo baa INT FIRST ba ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CASCADE', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CHANGE COLUMN boo baa INT AFTER ba |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE COLUMN boo baa INT AFTER ba ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CASCADE', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CLUSTERED |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CLUSTERED ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['BY']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar CLUSTERED BY (|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CLUSTERED BY (',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar CLUSTERED BY (a, b, |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CLUSTERED BY (a, b, ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CLUSTERED BY (a, b, c) |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CLUSTERED BY (a, b, c) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['INTO', 'SORTED BY']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CLUSTERED BY (a, b, c) INTO 10 |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CLUSTERED BY (a, b, c) INTO 10 ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['BUCKETS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CLUSTERED BY (a, b, c) SORTED |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CLUSTERED BY (a, b, c) SORTED ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['BY']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE foo.bar CLUSTERED BY (a, b, c) SORTED BY (|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE foo.bar CLUSTERED BY (a, b, c) SORTED BY (',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { database: 'foo', table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE foo.bar CLUSTERED BY (a, b, c) SORTED BY (a) |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CLUSTERED BY (a, b, c) SORTED BY (a) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['INTO']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE foo.bar CLUSTERED BY (a, b, c) SORTED BY (a) INTO 10 |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CLUSTERED BY (a, b, c) SORTED BY (a) INTO 10 ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['BUCKETS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar DROP |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['IF EXISTS', 'PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar DROP IF |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP IF ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['EXISTS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar DROP IF EXISTS |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP IF EXISTS ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITION']
+            }
+          });
+        });
+
+        // TODO: Suggest partitions
+        it('should suggest columns for "ALTER TABLE bar DROP IF EXISTS PARTITION (|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP IF EXISTS PARTITION (',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar DROP IF EXISTS PARTITION (a=\'baa\'), |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP IF EXISTS PARTITION (a=\'baa\'), ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar DROP PARTITION (a=\'baa\') |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP PARTITION (a=\'baa\') ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PURGE']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar DROP PARTITION (a=\'baa\'), PARTITION (b=\'boo\') |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP PARTITION (a=\'baa\'), PARTITION (b=\'boo\') ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PURGE']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar EXCHANGE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar EXCHANGE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar EXCHANGE PARTITION ((boo=\'baa\'), (baa=\'boo\')) |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar EXCHANGE PARTITION ((boo=\'baa\'), (baa=\'boo\')) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['WITH TABLE']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar EXCHANGE PARTITION ((boo=\'baa\'), (baa=\'boo\')) WITH |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar EXCHANGE PARTITION ((boo=\'baa\'), (baa=\'boo\')) WITH ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['TABLE']
+            }
+          });
+        });
+
+        it('should suggest tables for "ALTER TABLE bar EXCHANGE PARTITION ((boo=\'baa\'), (baa=\'boo\')) WITH TABLE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar EXCHANGE PARTITION ((boo=\'baa\'), (baa=\'boo\')) WITH TABLE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestTables: {},
+              suggestDatabases: { appendDot: true }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar NOT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar NOT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['SKEWED', 'STORED AS DIRECTORIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar NOT STORED |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar NOT STORED ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AS DIRECTORIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar NOT STORED AS |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar NOT STORED AS ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['DIRECTORIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['ADD COLUMNS', 'CHANGE', 'COMPACT', 'CONCATENATE', 'DISABLE NO_DROP', 'DISABLE OFFLINE',
+                'ENABLE NO_DROP', 'ENABLE OFFLINE', 'RENAME TO PARTITION', 'REPLACE COLUMNS', 'SET FILEFORMAT',
+                'SET LOCATION', 'SET SERDE', 'SET SERDEPROPERTIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') ADD |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') ADD ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COLUMNS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') ADD COLUMNS (boo |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') ADD COLUMNS (boo ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['INT', 'STRUCT<>'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') ADD COLUMNS (boo INT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') ADD COLUMNS (boo INT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COMMENT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') ADD COLUMNS (boo INT) |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') ADD COLUMNS (boo INT) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CASCADE', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar PARTITION (col=\'val\') CHANGE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') CHANGE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' },
+              suggestKeywords: ['COLUMN']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col1, col2) CHANGE boo baa |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col1, col2) CHANGE boo baa ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['ARRAY<>', 'INT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['ARRAY<>', 'INT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AFTER', 'CASCADE', 'COMMENT', 'FIRST', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT COMMENT \'ble\' |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT COMMENT \'ble\' ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AFTER', 'CASCADE', 'FIRST', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT COMMENT \'ble\' AFTER |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT COMMENT \'ble\' AFTER ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar'}
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT FIRST |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT FIRST ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar'}
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT FIRST ba |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') CHANGE boo baa INT FIRST ba ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CASCADE', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') CHANGE COLUMN boo baa INT AFTER ba |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') CHANGE COLUMN boo baa INT AFTER ba ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CASCADE', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') DISABLE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') DISABLE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['NO_DROP', 'OFFLINE']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') ENABLE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') ENABLE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['NO_DROP', 'OFFLINE']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') RENAME |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') RENAME ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['TO PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') RENAME TO |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') RENAME TO ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') REPLACE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') REPLACE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COLUMNS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') REPLACE COLUMNS (boo |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') REPLACE COLUMNS (boo ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['INT', 'STRUCT<>'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') REPLACE COLUMNS (boo INT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') REPLACE COLUMNS (boo INT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COMMENT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') REPLACE COLUMNS (boo INT) |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') REPLACE COLUMNS (boo INT) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CASCADE', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') SET |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') SET ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (col=\'val\') SET FILEFORMAT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') SET FILEFORMAT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['ORC', 'PARQUET'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest hdfs for "ALTER TABLE bar PARTITION (col=\'val\') SET LOCATION \'|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (col=\'val\') SET LOCATION \'',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestHdfs: { path: '' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar RECOVER |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar RECOVER ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITIONS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar RENAME |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar RENAME ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['TO']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar REPLACE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar REPLACE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COLUMNS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar REPLACE COLUMNS (boo |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar REPLACE COLUMNS (boo ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['INT', 'STRUCT<>'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar REPLACE COLUMNS (boo INT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar REPLACE COLUMNS (boo INT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COMMENT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar REPLACE COLUMNS (boo INT) |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar REPLACE COLUMNS (boo INT) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CASCADE', 'RESTRICT']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SET |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES', 'SKEWED LOCATION', 'TBLPROPERTIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SET FILEFORMAT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET FILEFORMAT ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            containsKeywords: ['ORC', 'PARQUET'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest hdfs for "ALTER TABLE bar SET LOCATION \'|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET LOCATION \'',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestHdfs: { path: '' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SET SERDE \'boo\' |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET SERDE \'boo\' ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['WITH SERDEPROPERTIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SET SERDE \'boo\' WITH |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET SERDE \'boo\' WITH ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['SERDEPROPERTIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SET SKEWED |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET SKEWED ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['LOCATION']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar SET SKEWED LOCATION (|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET SKEWED LOCATION (',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar SET SKEWED LOCATION (a=\'/boo\', |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SET SKEWED LOCATION (a=\'/boo\', ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SKEWED |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SKEWED ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['BY']
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar SKEWED BY (|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SKEWED BY (',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE foo.bar SKEWED BY (a, |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE foo.bar SKEWED BY (a, ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { database: 'foo', table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SKEWED BY (a, b) |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SKEWED BY (a, b) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['ON']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SKEWED BY (a, b) ON ((1, 2), (2, 3)) "', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SKEWED BY (a, b) ON ((1, 2), (2, 3)) ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['STORED AS DIRECTORIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SKEWED BY (a, b) ON ((1, 2), (2, 3)) STORED "', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SKEWED BY (a, b) ON ((1, 2), (2, 3)) STORED ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AS DIRECTORIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar SKEWED BY (a, b) ON ((1, 2), (2, 3)) STORED AS "', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar SKEWED BY (a, b) ON ((1, 2), (2, 3)) STORED AS ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['DIRECTORIES']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar TOUCH |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar TOUCH ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar UNARCHIVE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar UNARCHIVE ',
+            afterCursor: '',
+            dialect: 'hive',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['PARTITION']
+            }
+          });
+        });
+
+      });
+
+      describe('Impala specific', function () {
+        it('should handle "alter table d2.mobile rename to d3.mobile;|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'alter table d2.mobile rename to d3.mobile;',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: true
+            }
+          });
+        });
+
+        it('should handle "alter table p1 partition (month=1, day=1) set location \'/usr/external_data/new_years_day\';|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'alter table p1 partition (month=1, day=1) set location \'/usr/external_data/new_years_day\';',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: true
+            }
+          });
+        });
+
+        it('should handle "alter table sales_data add partition (zipcode = cast(9021 * 10 as string));|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'alter table sales_data add partition (zipcode = cast(9021 * 10 as string));',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: true
+            }
+          });
+        });
+
+        it('should handle "ALTER TABLE table_name SET TBLPROPERTIES(\'EXTERNAL\'=\'FALSE\');|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE table_name SET TBLPROPERTIES(\'EXTERNAL\'=\'FALSE\');',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['ADD COLUMNS', 'ADD PARTITION', 'CHANGE', 'DROP COLUMN', 'DROP PARTITION', 'PARTITION', 'RENAME TO', 'REPLACE COLUMNS', 'SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDEPROPERTIES', 'SET TBLPROPERTIES', 'SET UNCACHED' ]
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['COLUMNS', 'PARTITION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar ADD COLUMNS (a INT, b |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD COLUMNS (a INT, b ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            containsKeywords: ['INT'],
+            doesNotContainKeywords: ['ARRAY<>'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar ADD PARTITION (|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar ADD PARTITION (',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar CHANGE |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar CHANGE foo bar |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar CHANGE foo bar ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            containsKeywords: ['INT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest columns for "ALTER TABLE bar DROP |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' },
+              suggestKeywords: ['COLUMN', 'PARTITION']
+            }
+          });
+        });
+
+        // TODO: Should suggest partitions
+        it('should suggest columns for "ALTER TABLE bar DROP PARTITION (|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar DROP PARTITION (',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestColumns: { table: 'bar' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (a=\'b\') |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (a=\'b\') ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['SET CACHED IN', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDEPROPERTIES', 'SET TBLPROPERTIES', 'SET UNCACHED']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (a=\'b\') SET |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (a=\'b\') SET ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['CACHED IN', 'FILEFORMAT', 'LOCATION', 'SERDEPROPERTIES', 'TBLPROPERTIES', 'UNCACHED']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (a=\'b\') SET CACHED |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (a=\'b\') SET CACHED ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['IN']
+            }
+          });
+        });
+
+        it('should suggest keywords for "ALTER TABLE bar PARTITION (a=\'b\') SET FILEFORMAT |"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (a=\'b\') SET FILEFORMAT ',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            containsKeywords: ['PARQUET'],
+            doesNotContainKeywords: ['ORC'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest hdfs for "ALTER TABLE bar PARTITION (a=\'b\') SET LOCATION \'|"', function() {
+          assertAutoComplete({
+            beforeCursor: 'ALTER TABLE bar PARTITION (a=\'b\') SET LOCATION \'',
+            afterCursor: '',
+            dialect: 'impala',
+            hasLocations: true,
+            expectedResult: {
+              lowerCase: false,
+              suggestHdfs: { path: '' }
+            }
+          });
+        });
+      });
+    });
+  });
+});

+ 1000 - 6
desktop/core/src/desktop/static/desktop/spec/autocomplete/sqlSpecCreate.js

@@ -48,7 +48,7 @@ define([
         dialect: 'generic',
         expectedResult: {
           lowerCase: false,
-          suggestKeywords: ['DATABASE', 'SCHEMA', 'TABLE']
+          suggestKeywords: ['DATABASE', 'ROLE', 'SCHEMA', 'TABLE', 'VIEW']
         }
       });
     });
@@ -61,7 +61,7 @@ define([
           dialect: 'hive',
           expectedResult: {
             lowerCase: false,
-            suggestKeywords: ['DATABASE', 'EXTERNAL TABLE', 'SCHEMA', 'TABLE', 'TEMPORARY EXTERNAL TABLE', 'TEMPORARY TABLE']
+            suggestKeywords: ['DATABASE', 'EXTERNAL TABLE', 'FUNCTION', 'INDEX', 'ROLE', 'SCHEMA', 'TABLE', 'TEMPORARY EXTERNAL TABLE', 'TEMPORARY FUNCTION', 'TEMPORARY TABLE', 'VIEW']
           }
         });
       });
@@ -75,7 +75,7 @@ define([
           dialect: 'impala',
           expectedResult: {
             lowerCase: false,
-            suggestKeywords: ['DATABASE', 'EXTERNAL TABLE', 'SCHEMA', 'TABLE']
+            suggestKeywords: ['AGGREGATE FUNCTION', 'DATABASE', 'EXTERNAL TABLE', 'FUNCTION', 'ROLE', 'SCHEMA', 'TABLE', 'VIEW']
           }
         });
       });
@@ -381,10 +381,10 @@ define([
           });
         });
 
-        it('should suggest keywords for "CREATE TABLE foo (id int) PARTITIONED BY (boo INT, baa BIGINT |, boo) AS SELECT * FROM baa;"', function () {
+        it('should suggest keywords for "CREATE TABLE foo (id int) PARTITIONED BY (boo INT, baa BIGINT |, boo INT) AS SELECT * FROM baa;"', function () {
           assertAutoComplete({
             beforeCursor: 'CREATE TABLE foo (id int) PARTITIONED BY (boo INT, baa BIGINT ',
-            afterCursor: ', boo) AS SELECT * FROM baa;',
+            afterCursor: ', boo INT) AS SELECT * FROM baa;',
             dialect: 'impala',
             hasLocations: true,
             expectedResult: {
@@ -642,7 +642,7 @@ define([
             dialect: 'hive',
             expectedResult: {
               lowerCase: false,
-              suggestKeywords: ['EXTERNAL TABLE', 'TABLE']
+              suggestKeywords: ['EXTERNAL TABLE', 'FUNCTION', 'TABLE']
             }
           });
         });
@@ -938,6 +938,18 @@ define([
           });
         });
 
+        it('should suggest keywords for "CREATE TABLE foo (id int) ROW FORMAT DELIMITED |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE TABLE foo (id int) ROW FORMAT DELIMITED ',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AS', 'COLLECTION ITEMS TERMINATED BY', 'FIELDS TERMINATED BY', 'LINES TERMINATED BY', 'LOCATION', 'MAP KEYS TERMINATED BY', 'NULL DEFINED AS', 'STORED AS', 'TBLPROPERTIES']
+            }
+          });
+        });
+
         it('should suggest keywords for "CREATE TABLE foo (id int) ROW FORMAT DELIMITED MAP |"', function () {
           assertAutoComplete({
             beforeCursor: 'CREATE TABLE foo (id int) ROW FORMAT DELIMITED MAP ',
@@ -1278,5 +1290,987 @@ define([
         });
       });
     });
+
+    describe('CREATE VIEW', function () {
+      it('should handle "CREATE VIEW foo AS SELECT a, | FROM tableOne"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE VIEW foo AS SELECT a, ',
+          afterCursor: ' FROM tableOne',
+          hasLocations:true,
+          expectedResult: {
+            lowerCase: false,
+            suggestAggregateFunctions: true,
+            suggestAnalyticFunctions: true,
+            suggestFunctions: {},
+            suggestColumns: { table: 'tableOne' },
+            suggestKeywords: ['*']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE VIEW |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE VIEW ',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['IF NOT EXISTS'],
+            suggestDatabases: { appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE VIEW | boo AS select * from baa;"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE VIEW ',
+          afterCursor: ' boo AS SELECT * FROM baa;',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['IF NOT EXISTS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE VIEW IF |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE VIEW IF ',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['NOT EXISTS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE VIEW IF NOT |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE VIEW IF NOT ',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['EXISTS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE VIEW boo AS |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE VIEW boo AS ',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['SELECT']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE VIEW IF NOT EXISTS boo AS |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE VIEW IF NOT EXISTS boo AS ',
+          afterCursor: '',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['SELECT']
+          }
+        });
+      });
+
+      describe('Hive specific', function () {
+        it('should handle "CREATE VIEW IF NOT EXISTS db.foo (baa COMMENT \'foo bar\', ble) COMMENT \'baa\' TBLPROPERTIES ("boo.baa"="buu") AS SELECT a, | FROM tableOne"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE VIEW IF NOT EXISTS db.foo (baa COMMENT \'foo bar\', ble) COMMENT \'baa\' TBLPROPERTIES ("boo.baa"="buu") AS SELECT a, ',
+            afterCursor: ' FROM tableOne',
+            dialect: 'hive',
+            hasLocations:true,
+            expectedResult: {
+              lowerCase: false,
+              suggestAggregateFunctions: true,
+              suggestAnalyticFunctions: true,
+              suggestFunctions: {},
+              suggestColumns: { table: 'tableOne' },
+              suggestKeywords: ['*']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE VIEW IF NOT EXISTS boo |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE VIEW IF NOT EXISTS boo ',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AS', 'COMMENT', 'TBLPROPERTIES']
+            }
+          });
+        });
+      });
+
+      describe('Impala specific', function () {
+        it('should suggest keywords for "CREATE VIEW IF NOT EXISTS boo |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE VIEW IF NOT EXISTS boo ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AS']
+            }
+          });
+        });
+      });
+    });
+
+    describe('CREATE ROLE', function () {
+      it('should handle "CREATE ROLE boo; |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE ROLE boo; ',
+          afterCursor: '',
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+    });
+
+    describe('CREATE FUNCTION', function () {
+      describe('Hive specific', function () {
+        it('should handle "CREATE TEMPORARY FUNCTION baaa AS \'boo.baa\'; |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE TEMPORARY FUNCTION baaa AS \'boo.baa\'; ',
+            afterCursor: '',
+            dialect: 'hive',
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should handle "CREATE FUNCTION boo.baaa AS \'boo.baa\' USING JAR \'boo.jar\', FILE \'booo\', ARCHIVE \'baa\'; |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo.baaa AS \'boo.baa\' USING JAR \'boo.jar\', FILE \'booo\', ARCHIVE \'baa\'; ',
+            afterCursor: '',
+            dialect: 'hive',
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo.baa |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo.baa ',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo.baa AS \'baa.boo\' |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo.baa AS \'baa.boo\' ',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['USING']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo.baa AS \'baa.boo\' USING |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo.baa AS \'baa.boo\' USING ',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['ARCHIVE', 'FILE', 'JAR']
+            }
+          });
+        });
+
+        xit('should suggest hdfs for "CREATE FUNCTION boo.baa AS \'baa.boo\' USING FILE \'|"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo.baa AS \'baa.boo\' USING FILE \'',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false,
+              suggestHdfs: { path: '' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo.baa AS \'baa.boo\' USING FILE \'boo\' |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo.baa AS \'baa.boo\' USING FILE \'boo\' ',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['ARCHIVE', 'FILE', 'JAR']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE TEMPORARY FUNCTION boo |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE TEMPORARY FUNCTION boo ',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['AS']
+            }
+          });
+        });
+
+        it('should not suggest keywords for "CREATE TEMPORARY FUNCTION boo AS \'boo.baa\' |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE TEMPORARY FUNCTION boo AS \'boo.baa\' ',
+            afterCursor: '',
+            dialect: 'hive',
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+      });
+
+      describe('Impala specific', function () {
+        it('should handle "CREATE FUNCTION foo.boo(INT, BOOLEAN) RETURNS INT LOCATION \'/boo\' SYMBOL=\'baaa\'; |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(INT, BOOLEAN) RETURNS INT LOCATION \'/boo\' SYMBOL=\'baaa\'; ',
+            afterCursor: '',
+            dialect: 'impala',
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should handle "CREATE AGGREGATE FUNCTION baa.boo(INT, DOUBLE) RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' UPDATE_FN=\'sin\' ' +
+            'MERGE_FN=\'cos\' PREPARE_FN=\'cos\' CLOSE_FN=\'cos\' SERIALIZE_FN=\'cos\' FINALIZE_FN=\'cos\'; |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' UPDATE_FN=\'sin\' MERGE_FN=\'cos\' PREPARE_FN=\'cos\' CLOSE_FN=\'cos\' SERIALIZE_FN=\'cos\' FINALIZE_FN=\'cos\'; ',
+            afterCursor: '',
+            dialect: 'impala',
+            containsKeywords: ['SELECT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['FUNCTION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['IF NOT EXISTS'],
+              suggestDatabases: { appendDot: true }
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION IF |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION IF ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['NOT EXISTS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION IF NOT |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION IF NOT ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['EXISTS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION boo(|"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo(',
+            afterCursor: '',
+            dialect: 'impala',
+            containsKeywords: ['INT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION boo() |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['RETURNS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION boo() RETURNS |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS ',
+            afterCursor: '',
+            dialect: 'impala',
+            containsKeywords: ['INT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION boo() RETURNS INT |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS INT ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['LOCATION']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['INIT_FN', 'UPDATE_FN']
+            }
+          });
+        });
+
+        it('should suggest functions for "CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'|"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestAnalyticFunctions: true,
+              suggestAggregateFunctions: true,
+              suggestFunctions: {}
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['UPDATE_FN']
+            }
+          });
+        });
+
+        it('should suggest functions for "CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' UPDATE_FN=\'|"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' UPDATE_FN=\'',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestAnalyticFunctions: true,
+              suggestAggregateFunctions: true,
+              suggestFunctions: {}
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' UPDATE_FN=\'sin\' |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' UPDATE_FN=\'sin\' ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['MERGE_FN']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' UPDATE_FN=\'sin\' MERGE_FN=\'tan\' ' +
+            'PREPARE_FN=\'boo\' SERIALIZE_FN=\'baa\' |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE AGGREGATE FUNCTION boo() RETURNS INT LOCATION \'/boo\' INIT_FN=\'cos\' UPDATE_FN=\'sin\' MERGE_FN=\'tan\' PREPARE_FN=\'boo\' SERIALIZE_FN=\'baa\' ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['FINALIZE_FN']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['IF NOT EXISTS'],
+              suggestDatabases: { appendDot: true }
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION IF |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION IF ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['NOT EXISTS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION IF NOT |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION IF NOT ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['EXISTS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo(|"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(',
+            afterCursor: '',
+            dialect: 'impala',
+            containsKeywords: ['INT'],
+            doesNotContainKeywords: ['ARRAY<>', '...'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo(INT, BOOLEAN |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(INT, BOOLEAN ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['...']
+            }
+          });
+        });
+
+        it('should not suggest keywords for "CREATE FUNCTION boo(INT |, BOOLEAN"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(INT ',
+            afterCursor: ', BOOLEAN',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo(INT, BOOLEAN, |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION  boo(INT, BOOLEAN, ',
+            afterCursor: '',
+            dialect: 'impala',
+            containsKeywords: ['INT'],
+            doesNotContainKeywords: ['ARRAY<>', '...'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo(INT, BOOLEAN, STRING |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION  boo(INT, BOOLEAN, STRING ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['...']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo(INT, BOOLEAN) |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(INT, BOOLEAN) ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['RETURNS']
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo(INT, BOOLEAN) RETURNS |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(INT, BOOLEAN) RETURNS ',
+            afterCursor: '',
+            dialect: 'impala',
+            containsKeywords: ['INT'],
+            expectedResult: {
+              lowerCase: false
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo(INT, BOOLEAN) RETURNS INT |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(INT, BOOLEAN) RETURNS INT ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['LOCATION']
+            }
+          });
+        });
+
+        it('should suggest hdfs for "CREATE FUNCTION boo(INT, BOOLEAN) RETURNS INT LOCATION \'|"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(INT, BOOLEAN) RETURNS INT LOCATION \'',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestHdfs: { path: '' }
+            }
+          });
+        });
+
+        it('should suggest keywords for "CREATE FUNCTION boo(INT, BOOLEAN) RETURNS INT LOCATION \'/boo\' |"', function () {
+          assertAutoComplete({
+            beforeCursor: 'CREATE FUNCTION boo(INT, BOOLEAN) RETURNS INT LOCATION \'/boo\' ',
+            afterCursor: '',
+            dialect: 'impala',
+            expectedResult: {
+              lowerCase: false,
+              suggestKeywords: ['SYMBOL']
+            }
+          });
+        });
+      });
+    });
+
+    describe('CREATE INDEX', function () {
+      it('should handle "CREATE INDEX bla ON TABLE db.tbl (a, b, c) AS \'COMPACT\' WITH DEFERRED REBUILD IDXPROPERTIES ("boo.baa"="ble", "blaa"=1) IN TABLE dbTwo.tblTwo ROW FORMAT DELIMITED STORED AS PARQUET LOCATION \'/baa/boo\' TBLPROPERTIES ("bla"=1) COMMENT \"booo\"; |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE db.tbl (a, b, c) AS \'COMPACT\' WITH DEFERRED REBUILD IDXPROPERTIES ' +
+          '("boo.baa"="ble", "blaa"=1) IN TABLE dbTwo.tblTwo ROW FORMAT DELIMITED STORED AS PARQUET LOCATION \'/baa/boo\' ' +
+          'TBLPROPERTIES ("bla"=1) COMMENT \"booo\"; ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should handle "CREATE INDEX bla ON TABLE db.tbl (a, b, c) AS \'boo.baa.bitmap\'; |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE db.tbl (a, b, c) AS \'boo.baa.bitmap\'; ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          containsKeywords: ['SELECT'],
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla  |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ',
+          afterCursor: '',
+          dialect: 'hive',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['ON TABLE']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON ',
+          afterCursor: '',
+          dialect: 'hive',
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['TABLE']
+          }
+        });
+      });
+
+      it('should suggest tables for "CREATE INDEX bla ON TABLE |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE ',
+          afterCursor: '',
+          dialect: 'hive',
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest columns for "CREATE INDEX bla ON TABLE foo.bar (|"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE foo.bar (',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestColumns: { database: 'foo', table: 'bar' }
+          }
+        });
+      });
+
+      it('should suggest columns for "CREATE INDEX bla ON TABLE foo.bar (a, b, c, |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE foo.bar (a, b, c, ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestColumns: { database: 'foo', table: 'bar' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['AS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['\'BITMAP\'', '\'COMPACT\'']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BIT|"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BIT',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['\'BITMAP\'', '\'COMPACT\'']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['COMMENT', 'IDXPROPERTIES', 'IN TABLE', 'LOCATION', 'ROW FORMAT', 'STORED AS', 'STORED BY', 'TBLPROPERTIES', 'WITH DEFERRED REBUILD']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' WITH |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' WITH ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['DEFERRED REBUILD']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' WITH DEFERRED |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' WITH DEFERRED ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['REBUILD']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' WITH DEFERRED REBUILD |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' WITH DEFERRED REBUILD ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['COMMENT', 'IDXPROPERTIES', 'IN TABLE', 'LOCATION', 'ROW FORMAT', 'STORED AS', 'STORED BY', 'TBLPROPERTIES']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' IDXPROPERTIES ("baa"="boo") |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' IDXPROPERTIES ("baa"="boo") ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['COMMENT', 'IN TABLE', 'LOCATION', 'ROW FORMAT', 'STORED AS', 'STORED BY', 'TBLPROPERTIES']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' IN |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' IN ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['TABLE']
+          }
+        });
+      });
+
+      it('should suggest tables for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' IN TABLE |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' IN TABLE ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestTables: {},
+            suggestDatabases: { appendDot: true }
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' IN TABLE boo |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' IN TABLE boo ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['COMMENT', 'LOCATION', 'ROW FORMAT', 'STORED AS', 'STORED BY', 'TBLPROPERTIES']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ROW |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ROW ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['FORMAT']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ROW FORMAT |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ROW FORMAT ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['DELIMITED', 'SERDE']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ROW FORMAT DELIMITED |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ROW FORMAT DELIMITED ',
+          afterCursor: '',
+          dialect: 'hive',
+          containsKeywords: ['MAP KEYS TERMINATED BY', 'NULL DEFINED AS', 'LOCATION', 'TBLPROPERTIES', 'COMMENT'],
+          doesNotContainKeywords: ['AS'],
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ROW FORMAT DELIMITED NULL |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'BITMAP\' ROW FORMAT DELIMITED NULL ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['DEFINED AS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' ROW FORMAT DELIMITED STORED |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' ROW FORMAT DELIMITED STORED ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['AS']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' STORED |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' STORED ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['AS', 'BY']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' ROW FORMAT DELIMITED STORED AS |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' ROW FORMAT DELIMITED STORED AS ',
+          afterCursor: '',
+          dialect: 'hive',
+          containsKeywords: ['ORC', 'PARQUET'],
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false
+          }
+        });
+      });
+
+      it('should suggest hdfs for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' LOCATION \'|"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' LOCATION \'',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestHdfs: { path: '' }
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' LOCATION \'/baa\' |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' LOCATION \'/baa\' ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['COMMENT', 'TBLPROPERTIES']
+          }
+        });
+      });
+
+      it('should suggest keywords for "CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' TBLPROPERTIES ("baa"="boo") |"', function () {
+        assertAutoComplete({
+          beforeCursor: 'CREATE INDEX bla ON TABLE boo (a, b, c) AS \'COMPACT\' TBLPROPERTIES ("baa"="boo") ',
+          afterCursor: '',
+          dialect: 'hive',
+          hasLocations: true,
+          expectedResult: {
+            lowerCase: false,
+            suggestKeywords: ['COMMENT']
+          }
+        });
+      });
+    });
   });
 });

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

@@ -32,10 +32,11 @@ 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_create.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_alter.jison sql_create.jison sql_drop.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
+rm sql.jison
 rm sql.js
 rm sql_end.jison
 popd

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini