Browse Source

[editor] Add SparkSQL autocomplete for ALTER statements

Johan Åhlén 3 years ago
parent
commit
b123a39561

+ 8 - 0
desktop/core/src/desktop/js/parse/sql/generic/jison/sql_main.jison

@@ -282,6 +282,10 @@ OptionalIfExists
    }
  ;
 
+IfExists_EDIT
+ : OptionalIfExists_EDIT
+ ;
+
 OptionalIfExists_EDIT
  : 'IF' 'CURSOR'
    {
@@ -297,6 +301,10 @@ OptionalIfNotExists
    }
  ;
 
+IfNotExists_EDIT
+ : OptionalIfNotExists_EDIT
+ ;
+
 OptionalIfNotExists_EDIT
  : 'IF' 'CURSOR'
    {

+ 52 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_common.jison

@@ -0,0 +1,52 @@
+// 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_EDIT
+ : 'ALTER' 'CURSOR'
+   {
+     parser.suggestKeywords(['DATABASE', 'NAMESPACE', 'SCHEMA', 'TABLE', 'VIEW']);
+   }
+ ;
+
+ParenthesizedPropertyAssignmentList
+ : '(' PropertyAssignmentList ')'
+ ;
+
+PropertyAssignmentList
+ : PropertyAssignment
+ | PropertyAssignmentList ',' PropertyAssignment
+ ;
+
+PropertyAssignment
+ : QuotedValue '=' UnsignedValueSpecification
+ ;
+
+ParenthesizedPropertyList
+ : '(' PropertyList ')'
+ ;
+
+PropertyList
+ : QuotedValue
+ | PropertyList ',' QuotedValue
+ ;
+
+FileFormat
+ : 'CSV'
+ | 'JSON'
+ | 'ORC'
+ | 'PARQUET'
+ | 'TEXTFILE'
+ ;

+ 13 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_common.test.json

@@ -0,0 +1,13 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ALTER"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  }
+]

+ 73 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_database.jison

@@ -0,0 +1,73 @@
+// 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
+ : AlterDatabase
+ ;
+
+DataDefinition_EDIT
+ : AlterDatabase_EDIT
+ ;
+
+AlterDatabase
+ : 'ALTER' DatabaseNamespaceOrSchema RegularOrBacktickedIdentifier AlterDatabaseSetOperations
+   {
+     parser.addDatabaseLocation(@3, [ { name: $3 } ]);
+   }
+ ;
+
+AlterDatabase_EDIT
+ : 'ALTER' DatabaseNamespaceOrSchema 'CURSOR'
+   {
+     parser.suggestDatabases();
+   }
+ | 'ALTER' DatabaseNamespaceOrSchema 'CURSOR' AlterDatabaseSetOperations
+   {
+     parser.suggestDatabases();
+   }
+ | 'ALTER' DatabaseNamespaceOrSchema RegularOrBacktickedIdentifier 'CURSOR'
+   {
+     parser.addDatabaseLocation(@3, [ { name: $3 } ]);
+     parser.suggestKeywords(['SET DBPROPERTIES', 'SET LOCATION', 'SET PROPERTIES']);
+   }
+ | 'ALTER' DatabaseNamespaceOrSchema RegularOrBacktickedIdentifier AlterDatabaseSetOperations_EDIT
+    {
+      parser.addDatabaseLocation(@3, [ { name: $3 } ]);
+    }
+ ;
+
+AlterDatabaseSetOperations
+ : 'SET' DbPropertiesOrProperties ParenthesizedPropertyAssignmentList
+ | 'SET' 'LOCATION' QuotedValue
+ ;
+
+AlterDatabaseSetOperations_EDIT
+ : 'SET' 'CURSOR'
+   {
+     parser.suggestKeywords(['DBPROPERTIES', 'LOCATION', 'PROPERTIES']);
+   }
+ ;
+
+DatabaseNamespaceOrSchema
+ : 'DATABASE'
+ | 'NAMESPACE'
+ | 'SCHEMA'
+ ;
+
+DbPropertiesOrProperties
+ : 'DBPROPERTIES'
+ | 'PROPERTIES'
+ ;

+ 77 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_database.test.json

@@ -0,0 +1,77 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "DATABASE",
+      "NAMESPACE",
+      "SCHEMA"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "ALTER DATABASE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "ALTER NAMESPACE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "ALTER SCHEMA ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER DATABASE foo ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "SET DBPROPERTIES",
+        "SET LOCATION",
+        "SET PROPERTIES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER SCHEMA foo SET ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "DBPROPERTIES",
+        "LOCATION",
+        "PROPERTIES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "ALTER NAMESPACE ",
+    "afterCursor": " SET LOCATION 'some location';",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestDatabases": {}
+    }
+  }
+]

+ 272 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_table.jison

@@ -0,0 +1,272 @@
+// 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
+ : AlterTable
+ ;
+
+DataDefinition_EDIT
+ : AlterTable_EDIT
+ ;
+
+AlterTable
+ : 'ALTER' 'TABLE' SchemaQualifiedTableIdentifier AlterTableOperations
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+AlterTable_EDIT
+ : 'ALTER' 'TABLE' 'CURSOR' OptionalAlterTableOperations
+   {
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | 'ALTER' 'TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalAlterTableOperations
+ | 'ALTER' 'TABLE' SchemaQualifiedTableIdentifier 'CURSOR' OptionalAlterTableOperations
+   {
+     parser.addTablePrimary($3);
+     if (!$5) {
+       parser.suggestKeywords([ 'ADD', 'ADD COLUMNS', 'ADD IF NOT EXISTS', 'ALTER', 'ALTER COLUMN', 'CHANGE',
+         'CHANGE COLUMN', 'DROP', 'DROP COLUMN', 'DROP COLUMNS', 'DROP IF EXISTS', 'PARTITION', 'RECOVER PARTITIONS',
+         'RENAME COLUMN', 'RENAME TO', 'REPLACE COLUMNS', 'SET', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDE',
+         'SET SERDEPROPERTIES', 'SET TBLPROPERTIES', 'UNSET TBLPROPERTIES']);
+     }
+   }
+ | 'ALTER' 'TABLE' SchemaQualifiedTableIdentifier AlterTableOperations_EDIT
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+OptionalAlterTableOperations
+ :
+ | AlterTableOperations
+ ;
+
+AlterTableOperations
+ : AlterAddOperations
+ | AlterOrChange OptionalColumn ColumnIdentifier ColumnDataType OptionalComment
+ | AlterDropOperations
+ | PartitionSpec 'RENAME' 'TO' PartitionSpec
+ | PartitionSpec 'REPLACE' 'COLUMNS' ParenthesizedColumnSpecificationList
+ | 'RECOVER' 'PARTITIONS'
+ | 'RENAME' 'COLUMN' ColumnIdentifier 'TO' ColumnIdentifier
+ | 'RENAME' 'TO' RegularOrBacktickedIdentifier
+ | 'REPLACE' 'COLUMNS' ParenthesizedColumnSpecificationList
+ | AlterSetOperations
+ | PartitionSpec AlterSetOperations
+ | AlterSetTblPropertiesOperations
+ ;
+
+AlterTableOperations_EDIT
+ : AlterAddOperations_EDIT
+ | AlterOrChange OptionalColumn 'CURSOR'
+   {
+     if (!$2) {
+        parser.suggestKeywords(['COLUMN']);
+     }
+     parser.suggestColumns();
+   }
+ | AlterOrChange OptionalColumn ColumnIdentifier 'CURSOR' OptionalComment
+   {
+     parser.suggestKeywords(parser.getTypeKeywords());
+   }
+ | AlterOrChange OptionalColumn ColumnIdentifier ColumnDataType 'CURSOR' OptionalComment
+   {
+     if (!$6) {
+       parser.suggestKeywords(['COMMENT']);
+     }
+   }
+ | AlterOrChange OptionalColumn ColumnIdentifier ColumnDataType_EDIT OptionalComment
+ | AlterOrChange OptionalColumn 'CURSOR' ColumnDataType OptionalComment
+   {
+     if (!$2) {
+        parser.suggestKeywords(['COLUMN']);
+     }
+     parser.suggestColumns();
+   }
+ | AlterDropOperations_EDIT
+ | PartitionSpec 'CURSOR'
+   {
+     parser.suggestKeywords([
+       'REPLACE COLUMNS', 'RENAME TO', 'SET', 'SET FILEFORMAT', 'SET LOCATION', 'SET SERDE', 'SET SERDEPROPERTIES']);
+   }
+ | PartitionSpec 'RENAME' 'CURSOR'
+   {
+     parser.suggestKeywords(['TO']);
+   }
+ | PartitionSpec 'RENAME' 'TO' 'CURSOR'
+   {
+     parser.suggestKeywords(['PARTITION']);
+   }
+ | PartitionSpec 'REPLACE' 'CURSOR'
+   {
+     parser.suggestKeywords(['COLUMNS']);
+   }
+ | PartitionSpec 'REPLACE' 'COLUMNS' ParenthesizedColumnSpecificationList_EDIT
+ | 'RECOVER' 'CURSOR'
+   {
+     parser.suggestKeywords(['PARTITIONS']);
+   }
+ | 'RENAME' 'CURSOR'
+   {
+     parser.suggestKeywords(['COLUMN', 'TO']);
+   }
+ | 'RENAME' 'COLUMN' 'CURSOR'
+   {
+     parser.suggestColumns();
+   }
+ | 'RENAME' 'COLUMN' ColumnIdentifier 'CURSOR'
+   {
+     parser.suggestKeywords(['TO']);
+   }
+ | 'REPLACE' 'CURSOR'
+   {
+     parser.suggestKeywords(['COLUMNS']);
+   }
+ | 'REPLACE' 'COLUMNS' ParenthesizedColumnSpecificationList_EDIT
+ | AlterSetOperations_EDIT
+ | PartitionSpec AlterSetOperations_EDIT
+ | AlterSetTblPropertiesOperations_EDIT
+ ;
+
+AlterAddOperations
+ : 'ADD' 'COLUMNS' ParenthesizedColumnSpecificationList
+ | 'ADD' OptionalIfNotExists ParenthesizedPartitionList
+ ;
+
+AlterAddOperations_EDIT
+ : 'ADD' OptionalIfNotExists 'CURSOR'
+   {
+     if (!$2) {
+       parser.suggestKeywords(['COLUMNS', 'IF NOT EXISTS']);
+     }
+   }
+ | 'ADD' IfNotExists_EDIT
+ | 'ADD' OptionalIfNotExists 'CURSOR' ParenthesizedPartitionList
+   {
+     if (!$2) {
+       parser.suggestKeywords(['IF NOT EXISTS']);
+     }
+   }
+ | 'ADD' IfNotExists_EDIT ParenthesizedPartitionList
+ | 'ADD' 'COLUMNS' ParenthesizedColumnSpecificationList_EDIT
+ ;
+
+AlterDropOperations
+ : 'DROP' OptionalIfExists PartitionSpec OptionalPurge
+ | 'DROP' 'COLUMN' ColumnIdentifier
+ | 'DROP' 'COLUMNS' ParenthesizedColumnIdentifierList
+ ;
+
+AlterDropOperations_EDIT
+ : 'DROP' OptionalIfExists 'CURSOR'
+   {
+     if (!$2) {
+       parser.suggestKeywords(['COLUMN', 'COLUMNS', 'IF EXISTS', 'PARTITION'])
+     } else {
+       parser.suggestKeywords(['PARTITION']);
+     }
+   }
+ | 'DROP' IfExists_EDIT
+ | 'DROP' OptionalIfExists 'CURSOR' PartitionSpec OptionalPurge
+   {
+     if (!$2) {
+       parser.suggestKeywords(['IF EXISTS'])
+     }
+   }
+ | 'DROP' IfExists_EDIT PartitionSpec OptionalPurge
+ | 'DROP' OptionalIfExists PartitionSpec OptionalPurge 'CURSOR'
+   {
+     if (!$4) {
+       parser.suggestKeywords(['PURGE'])
+     }
+   }
+ | 'DROP' 'COLUMN' 'CURSOR'
+   {
+     parser.suggestColumns();
+   }
+ | 'DROP' 'COLUMNS' ParenthesizedColumnIdentifierList_EDIT
+ ;
+
+AlterSetOperations
+ : 'SET' 'FILEFORMAT' FileFormat
+ | 'SET' 'LOCATION' QuotedValue
+ | 'SET' 'SERDE' QuotedValue
+ | 'SET' 'SERDE' QuotedValue 'WITH' 'SERDEPROPERTIES' ParenthesizedPropertyAssignmentList
+ | 'SET' 'SERDEPROPERTIES' ParenthesizedPropertyAssignmentList
+ ;
+
+AlterSetOperations_EDIT
+ : 'SET' 'CURSOR'
+   {
+     parser.suggestKeywords(['FILEFORMAT', 'LOCATION', 'SERDE', 'SERDEPROPERTIES', 'TBLPROPERTIES']);
+   }
+ | 'SET' 'FILEFORMAT' 'CURSOR'
+   {
+     parser.suggestFileFormats();
+   }
+ | 'SET' 'SERDE' QuotedValue 'CURSOR'
+   {
+     parser.suggestKeywords(['WITH SERDEPROPERTIES']);
+   }
+ | 'SET' 'SERDE' QuotedValue 'WITH' 'CURSOR'
+   {
+     parser.suggestKeywords(['SERDEPROPERTIES']);
+   }
+ ;
+
+AlterSetTblPropertiesOperations
+ : 'SET' 'TBLPROPERTIES' ParenthesizedPropertyAssignmentList
+ | 'UNSET' 'TBLPROPERTIES' OptionalIfExists ParenthesizedPropertyList
+ ;
+
+AlterSetTblPropertiesOperations_EDIT
+ : 'UNSET' 'CURSOR'
+   {
+     parser.suggestKeywords(['TBLPROPERTIES']);
+   }
+ | 'UNSET' 'TBLPROPERTIES' OptionalIfExists 'CURSOR'
+   {
+     if (!$3) {
+       parser.suggestKeywords(['IF EXISTS']);
+     }
+   }
+ | 'UNSET' 'TBLPROPERTIES' IfExists_EDIT
+ | 'UNSET' 'TBLPROPERTIES' OptionalIfExists 'CURSOR' ParenthesizedPropertyList
+   {
+     if (!$3) {
+       parser.suggestKeywords(['IF EXISTS']);
+     }
+   }
+ | 'UNSET' 'TBLPROPERTIES' IfExists_EDIT ParenthesizedPropertyList
+ ;
+
+OptionalColumn
+ :
+ | 'COLUMN'
+ ;
+
+OptionalPurge
+ :
+ | 'PURGE'
+ ;
+
+AlterOrChange
+ : 'ALTER'
+ | 'CHANGE'
+ ;

+ 783 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_table.test.json

@@ -0,0 +1,783 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest tables and databases",
+    "beforeCursor": "ALTER TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "ALTER TABLE foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "PARTITION",
+      "ADD"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo.bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "PARTITION",
+      "ADD"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "RENAME TO",
+      "PARTITION"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo RENAME ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TO"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest tables and databases",
+    "beforeCursor": "ALTER TABLE ",
+    "afterCursor": " RENAME TO bar",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "ALTER TABLE foo.",
+    "afterCursor": " RENAME TO bar",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo PARTITION (a=1) RENAME ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "TO"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo PARTITION (a=1) RENAME TO ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITION"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest tables and databases",
+    "beforeCursor": "ALTER TABLE ",
+    "afterCursor": " PARTITION (a=1) RENAME TO PARTITION (b=1)",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "ALTER TABLE foo.",
+    "afterCursor": " PARTITION (a=1) RENAME TO PARTITION (b=1)",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ADD COLUMNS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo ADD ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COLUMNS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest column types",
+    "beforeCursor": "ALTER TABLE foo ADD COLUMNS (a ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "DEC"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "DROP COLUMN",
+      "DROP COLUMNS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo DROP ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COLUMN",
+      "COLUMNS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ALTER TABLE foo DROP COLUMN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ALTER TABLE foo DROP COLUMNS (",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ALTER TABLE foo DROP COLUMNS (bar, ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "RENAME COLUMN"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo RENAME ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COLUMN"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ALTER TABLE foo RENAME COLUMN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo RENAME COLUMN bar ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "TO"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ALTER",
+      "CHANGE",
+      "ALTER COLUMN",
+      "CHANGE COLUMN"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ALTER TABLE bar ALTER ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      },
+      "suggestKeywords": [
+        "COLUMN"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ALTER TABLE bar CHANGE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      },
+      "suggestKeywords": [
+        "COLUMN"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ALTER TABLE bar ALTER COLUMN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ALTER TABLE bar CHANGE COLUMN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest types",
+    "beforeCursor": "ALTER TABLE bar CHANGE foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "BIGINT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "REPLACE COLUMNS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar REPLACE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COLUMNS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar PARTITION (a=1) REPLACE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COLUMNS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ADD",
+      "ADD IF NOT EXISTS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ADD IF ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "NOT EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ADD IF NOT ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ADD ",
+    "afterCursor": " (PARTITION (a=1));",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "IF NOT EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "DROP",
+      "DROP IF EXISTS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar DROP ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "IF EXISTS",
+      "PARTITION"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar DROP IF ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar DROP IF EXISTS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITION"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar DROP PARTITION (a=1) ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PURGE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SET",
+      "SET TBLPROPERTIES",
+      "UNSET TBLPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar SET ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TBLPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar UNSET ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TBLPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar UNSET TBLPROPERTIES ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "IF EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar UNSET TBLPROPERTIES IF ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SET",
+      "SET SERDE",
+      "SET SERDEPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar SET ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SERDE",
+      "SERDEPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar PARTITION (a=1) ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SET",
+      "SET SERDE",
+      "SET SERDEPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar PARTITION (a=1) SET ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SERDE",
+      "SERDEPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar SET SERDE \"asdf\" ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "WITH SERDEPROPERTIES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar SET SERDE \"asdf\" WITH ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "SERDEPROPERTIES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SET",
+      "SET FILEFORMAT",
+      "SET LOCATION"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar PARTITION (a=1) ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SET",
+      "SET FILEFORMAT",
+      "SET LOCATION"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar SET ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FILEFORMAT",
+      "LOCATION"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar PARTITION (a=1) SET ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FILEFORMAT",
+      "LOCATION"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar SET FILEFORMAT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "PARQUET"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "RECOVER PARTITIONS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER TABLE bar RECOVER ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "PARTITIONS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  }
+]

+ 96 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_view.jison

@@ -0,0 +1,96 @@
+// 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
+ : AlterView
+ ;
+
+DataDefinition_EDIT
+ : AlterView_EDIT
+ ;
+
+AlterView
+ : 'ALTER' 'VIEW' SchemaQualifiedTableIdentifier AlterViewOperations
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+AlterView_EDIT
+ : 'ALTER' 'VIEW' 'CURSOR' OptionalAlterViewOperations
+   {
+     parser.suggestTables({ onlyViews: true });
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | 'ALTER' 'VIEW' SchemaQualifiedTableIdentifier_EDIT OptionalAlterViewOperations
+   {
+     if (parser.yy.result.suggestTables) {
+       parser.yy.result.suggestTables.onlyViews = true;
+     }
+   }
+ | 'ALTER' 'VIEW' SchemaQualifiedTableIdentifier 'CURSOR' OptionalAlterViewOperations
+   {
+     parser.addTablePrimary($3);
+     if (!$5) {
+       parser.suggestKeywords(['AS SELECT', 'RENAME TO', 'SET TBLPROPERTIES', 'UNSET TBLPROPERTIES']);
+     }
+   }
+ | 'ALTER' 'VIEW' SchemaQualifiedTableIdentifier AlterViewOperations_EDIT
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+OptionalAlterViewOperations
+ :
+ | AlterViewOperations
+ ;
+
+AlterViewOperations
+ : AlterSetTblPropertiesOperations
+ | AsQuerySpecification
+ | 'RENAME' 'TO' RegularOrBacktickedIdentifier
+ ;
+
+AlterViewOperations_EDIT
+ : AlterSetTblPropertiesOperations_EDIT
+ | 'SET' 'CURSOR'
+   {
+     parser.suggestKeywords(['TBLPROPERTIES']);
+   }
+ | AsQuerySpecification_EDIT
+ | 'RENAME' 'CURSOR'
+   {
+     parser.suggestKeywords(['TO']);
+   }
+ ;
+
+OptionalAsQuerySpecification
+ :
+ | AsQuerySpecification
+ ;
+
+AsQuerySpecification
+ : 'AS' QuerySpecification
+ ;
+
+AsQuerySpecification_EDIT
+ : 'AS' 'CURSOR'
+   {
+     parser.suggestKeywords(['SELECT']);
+   }
+ | 'AS' QuerySpecification_EDIT
+ ;

+ 223 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_view.test.json

@@ -0,0 +1,223 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "VIEW"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest views and databases",
+    "beforeCursor": "ALTER VIEW ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "onlyViews": true
+      },
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest views",
+    "beforeCursor": "ALTER VIEW foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "onlyViews": true,
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SET TBLPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW foo.bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SET TBLPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "RENAME TO"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW foo RENAME ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TO"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest views and databases",
+    "beforeCursor": "ALTER VIEW ",
+    "afterCursor": " RENAME TO bar",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "onlyViews": true
+      },
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "ALTER VIEW foo.",
+    "afterCursor": " RENAME TO bar",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "onlyViews": true,
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SET TBLPROPERTIES",
+      "UNSET TBLPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW bar SET ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TBLPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW bar UNSET ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TBLPROPERTIES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW bar UNSET TBLPROPERTIES ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "IF EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW bar UNSET TBLPROPERTIES IF ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW bar ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "AS SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW bar AS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "SELECT"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ALTER VIEW bar AS SELECT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "*"
+    ],
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestAggregateFunctions": {
+        "tables": []
+      },
+      "suggestAnalyticFunctions": true,
+      "suggestFunctions": {},
+      "suggestColumns": {
+        "source": "select",
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+]

+ 259 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/create/create_common.jison

@@ -0,0 +1,259 @@
+// 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.
+
+ParenthesizedColumnSpecificationList
+ : '(' ColumnSpecificationList ')'                              -> $2
+ ;
+
+ParenthesizedColumnSpecificationList_EDIT
+ : '(' ColumnSpecificationList_EDIT RightParenthesisOrError
+ ;
+
+ColumnSpecificationList
+ : ColumnSpecification                              -> [$1]
+ | ColumnSpecificationList ',' ColumnSpecification  -> $1.concat($3)
+ ;
+
+ColumnSpecificationList_EDIT
+ : ColumnSpecification_EDIT
+ | ColumnSpecification_EDIT ',' ColumnSpecificationList
+ | ColumnSpecificationList ',' ColumnSpecification_EDIT
+ | ColumnSpecificationList ',' ColumnSpecification_EDIT ',' ColumnSpecificationList
+ | ColumnSpecification 'CURSOR'
+   {
+     parser.checkForKeywords($1);
+   }
+ | ColumnSpecification 'CURSOR' ',' ColumnSpecificationList
+   {
+     parser.checkForKeywords($1);
+   }
+ | ColumnSpecificationList ',' ColumnSpecification 'CURSOR'
+   {
+     parser.checkForKeywords($3);
+   }
+ | ColumnSpecificationList ',' ColumnSpecification 'CURSOR' ',' ColumnSpecificationList
+   {
+     parser.checkForKeywords($3);
+   }
+ ;
+
+ColumnSpecification
+ : ColumnIdentifier ColumnDataType OptionalColumnOptions
+   {
+     $$ = $1;
+     $$.type = $2;
+     var keywords = [];
+     if (!$3['comment']) {
+       keywords.push('COMMENT');
+     }
+     if (keywords.length > 0) {
+       $$.suggestKeywords = keywords;
+     }
+   }
+ ;
+
+ColumnSpecification_EDIT
+ : ColumnIdentifier 'CURSOR' OptionalColumnOptions
+   {
+     parser.suggestKeywords(parser.getColumnDataTypeKeywords());
+   }
+ | ColumnIdentifier ColumnDataType_EDIT OptionalColumnOptions
+ | ColumnIdentifier ColumnDataType ColumnOptions_EDIT
+ ;
+
+OptionalColumnOptions
+ :                      -> {}
+ | ColumnOptions
+ ;
+
+ColumnOptions
+ : ColumnOption
+   {
+     $$ = {};
+     $$[$1] = true;
+   }
+ | ColumnOptions ColumnOption
+   {
+     $1[$2] = true;
+   }
+ ;
+
+ColumnOptions_EDIT
+ : ColumnOption_EDIT
+ | ColumnOption_EDIT ColumnOptions
+ | ColumnOptions ColumnOption_EDIT
+ | ColumnOptions ColumnOption_EDIT ColumnOptions
+ ;
+
+ColumnOption
+ : 'NOT' 'NULL'                                              -> 'null'
+ | 'NULL'                                                    -> 'null'
+ | Comment                                                   -> 'comment'
+ ;
+
+ColumnOption_EDIT
+ : 'NOT' 'CURSOR'
+   {
+     parser.suggestKeywords(['NULL']);
+   }
+ ;
+
+ColumnDataType
+ : PrimitiveType
+ | ArrayType
+ | MapType
+ | StructType
+ | ArrayType_INVALID
+ | MapType_INVALID
+ | StructType_INVALID
+ ;
+
+ColumnDataType_EDIT
+ : ArrayType_EDIT
+ | MapType_EDIT
+ | StructType_EDIT
+ ;
+
+ArrayType
+ : 'ARRAY' '<' ColumnDataType '>'
+ ;
+
+ArrayType_INVALID
+ : 'ARRAY' '<' '>'
+ ;
+
+ArrayType_EDIT
+ : 'ARRAY' '<' AnyCursor GreaterThanOrError
+   {
+     parser.suggestKeywords(parser.getColumnDataTypeKeywords());
+   }
+ | 'ARRAY' '<' ColumnDataType_EDIT GreaterThanOrError
+ ;
+
+MapType
+ : 'MAP' '<' PrimitiveType ',' ColumnDataType '>'
+ ;
+
+MapType_INVALID
+ : 'MAP' '<' '>'
+ ;
+
+MapType_EDIT
+ : 'MAP' '<' PrimitiveType ',' ColumnDataType_EDIT GreaterThanOrError
+ | 'MAP' '<' AnyCursor GreaterThanOrError
+   {
+     parser.suggestKeywords(parser.getTypeKeywords());
+   }
+ | 'MAP' '<' PrimitiveType ',' AnyCursor GreaterThanOrError
+   {
+     parser.suggestKeywords(parser.getColumnDataTypeKeywords());
+   }
+ | 'MAP' '<' ',' AnyCursor GreaterThanOrError
+   {
+     parser.suggestKeywords(parser.getColumnDataTypeKeywords());
+   }
+ ;
+
+StructType
+ : 'STRUCT' '<' StructDefinitionList '>'
+ ;
+
+StructType_INVALID
+ : 'STRUCT' '<' '>'
+ ;
+
+StructType_EDIT
+ : '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
+ ;
+
+StructDefinition
+ : RegularOrBacktickedIdentifier ':' ColumnDataType OptionalComment
+ ;
+
+StructDefinition_EDIT
+ : Commas RegularOrBacktickedIdentifier ':' ColumnDataType 'CURSOR'
+   {
+     parser.suggestKeywords(['COMMENT']);
+   }
+ | Commas RegularOrBacktickedIdentifier ':' AnyCursor
+   {
+     parser.suggestKeywords(parser.getColumnDataTypeKeywords());
+   }
+ | Commas RegularOrBacktickedIdentifier ':' ColumnDataType_EDIT
+ | RegularOrBacktickedIdentifier ':' ColumnDataType 'CURSOR'
+   {
+     parser.suggestKeywords(['COMMENT']);
+   }
+ | RegularOrBacktickedIdentifier ':' AnyCursor
+   {
+     parser.suggestKeywords(parser.getColumnDataTypeKeywords());
+   }
+ | RegularOrBacktickedIdentifier ':' ColumnDataType_EDIT
+ ;
+
+ParenthesizedColumnIdentifierList
+ : '(' ColumnIdentifierList ')'
+ ;
+
+ParenthesizedColumnIdentifierList_EDIT
+ : '(' ColumnIdentifierList_EDIT RightParenthesisOrError
+ ;
+
+ColumnIdentifierList
+ : ColumnIdentifier
+ | ColumnIdentifierList ',' ColumnIdentifier
+ ;
+
+ColumnIdentifierList_EDIT
+ : 'CURSOR'
+   {
+     parser.suggestColumns();
+   }
+ | 'CURSOR' ',' ColumnIdentifierList
+   {
+     parser.suggestColumns();
+   }
+ | ColumnIdentifierList ',' 'CURSOR'
+   {
+     parser.suggestColumns();
+   }
+ | ColumnIdentifierList ',' 'CURSOR' ',' ColumnIdentifierList
+   {
+     parser.suggestColumns();
+   }
+ ;
+
+ParenthesizedPartitionList
+ : '(' PartitionList ')'
+ ;
+
+PartitionList
+ : PartitionSpec
+ | PartitionList, PartitionSpec
+ ;

+ 16 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/sql.jisonlex

@@ -29,6 +29,7 @@
 <between>'AND'                             { this.popState(); return 'BETWEEN_AND'; }
 
 // Reserved Keywords
+'ADD'                                      { return 'ADD'; }
 'ALL'                                      { return 'ALL'; }
 'ALTER'                                    { parser.determineCase(yytext); parser.addStatementTypeLocation('ALTER', yylloc, yy.lexer.upcomingInput()); return 'ALTER'; }
 'AND'                                      { return 'AND'; }
@@ -40,13 +41,16 @@
 'BY'                                       { return 'BY'; }
 'CASCADE'                                  { return 'CASCADE'; }
 'CASE'                                     { return 'CASE'; }
+'CHANGE'                                   { return 'CHANGE'; }
 'CHAR'                                     { return 'CHAR'; }
+'COLUMN'                                   { return 'COLUMN'; }
 'COLUMNS'                                  { return 'COLUMNS'; }
 'COMMENT'                                  { return 'COMMENT'; }
 'CREATE'                                   { parser.determineCase(yytext); return 'CREATE'; }
 'CROSS'                                    { return 'CROSS'; }
 'CURRENT'                                  { return 'CURRENT'; }
 'DATABASE'                                 { return 'DATABASE'; }
+'DBPROPERTIES'                             { return 'DBPROPERTIES'; }
 'DECIMAL'                                  { return 'DECIMAL'; }
 'DESC'                                     { return 'DESC'; }
 'DISTINCT'                                 { return 'DISTINCT'; }
@@ -57,6 +61,7 @@
 'END'                                      { return 'END'; }
 'EXISTS'                                   { parser.yy.correlatedSubQuery = true; return 'EXISTS'; }
 'FALSE'                                    { return 'FALSE'; }
+'FILEFORMAT'                               { return 'FILEFORMAT'; }
 'FLOAT'                                    { return 'FLOAT'; }
 'FOLLOWING'                                { return 'FOLLOWING'; }
 'FROM'                                     { parser.determineCase(yytext); return 'FROM'; }
@@ -74,6 +79,8 @@
 'LEFT'                                     { return 'LEFT'; }
 'LIKE'                                     { return 'LIKE'; }
 'LIMIT'                                    { return 'LIMIT'; }
+'LOCATION'                                 { return 'LOCATION'; }
+'NAMESPACE'                                { return 'NAMESPACE'; }
 'NOT'                                      { return 'NOT'; }
 'NULL'                                     { return 'NULL'; }
 'ON'                                       { return 'ON'; }
@@ -82,10 +89,15 @@
 'ORDER'                                    { return 'ORDER'; }
 'OUTER'                                    { return 'OUTER'; }
 'PARTITION'                                { return 'PARTITION'; }
+'PARTITIONS'                               { return 'PARTITIONS'; }
 'PRECEDING'                                { return 'PRECEDING'; }
+'PROPERTIES'                               { return 'PROPERTIES'; }
 'PURGE'                                    { return 'PURGE'; }
 'RANGE'                                    { return 'RANGE'; }
+'RECOVER'                                  { return 'RECOVER'; }
 'REGEXP'                                   { return 'REGEXP'; }
+'RENAME'                                   { return 'RENAME'; }
+'REPLACE'                                  { return 'REPLACE'; }
 'RIGHT'                                    { return 'RIGHT'; }
 'RLIKE'                                    { return 'RLIKE'; }
 'ROW'                                      { return 'ROW'; }
@@ -95,12 +107,15 @@
 'SCHEMAS'                                  { return 'SCHEMAS'; }
 'SELECT'                                   { parser.determineCase(yytext); parser.addStatementTypeLocation('SELECT', yylloc); return 'SELECT'; }
 'SEMI'                                     { return 'SEMI'; }
+'SERDE'                                    { return 'SERDE'; }
+'SERDEPROPERTIES'                          { return 'SERDEPROPERTIES'; }
 'SET'                                      { parser.determineCase(yytext); parser.addStatementTypeLocation('SET', yylloc); return 'SET'; }
 'SHOW'                                     { parser.determineCase(yytext); parser.addStatementTypeLocation('SHOW', yylloc); return 'SHOW'; }
 'SMALLINT'                                 { return 'SMALLINT'; }
 'STRING'                                   { return 'STRING'; }
 'TABLE'                                    { return 'TABLE'; }
 'TABLES'                                   { return 'TABLES'; }
+'TBLPROPERTIES'                            { return 'TBLPROPERTIES'; }
 'THEN'                                     { return 'THEN'; }
 'TIMESTAMP'                                { return 'TIMESTAMP'; }
 'TINYINT'                                  { return 'TINYINT'; }
@@ -109,6 +124,7 @@
 'TRUNCATE'                                 { parser.determineCase(yytext); parser.addStatementTypeLocation('TRUNCATE', yylloc, yy.lexer.upcomingInput()); return 'TRUNCATE'; }
 'UNBOUNDED'                                { return 'UNBOUNDED'; }
 'UNION'                                    { return 'UNION'; }
+'UNSET'                                    { return 'UNSET'; }
 'UPDATE'                                   { parser.determineCase(yytext); return 'UPDATE'; }
 'USE'                                      { parser.determineCase(yytext); parser.addStatementTypeLocation('USE', yylloc); return 'USE'; }
 'VALUES'                                   { return 'VALUES'; }

+ 10 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/structure.json

@@ -2,6 +2,11 @@
   "lexer": "sql.jisonlex",
   "autocomplete": [
     "../../generic/jison/autocomplete_header.jison",
+    "alter/alter_common.jison",
+    "alter/alter_database.jison",
+    "alter/alter_table.jison",
+    "alter/alter_view.jison",
+    "create/create_common.jison",
     "../../generic/jison/select/cte_select_statement.jison",
     "../../generic/jison/select/from_clause.jison",
     "../../generic/jison/select/group_by_clause.jison",
@@ -38,6 +43,11 @@
   ],
   "syntax": [
     "../../generic/jison/syntax_header.jison",
+    "alter/alter_common.jison",
+    "alter/alter_database.jison",
+    "alter/alter_table.jison",
+    "alter/alter_view.jison",
+    "create/create_common.jison",
     "../../generic/jison/select/cte_select_statement.jison",
     "../../generic/jison/select/from_clause.jison",
     "../../generic/jison/select/group_by_clause.jison",

File diff suppressed because it is too large
+ 0 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/sparksqlAutocompleteParser.js


File diff suppressed because it is too large
+ 0 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/sparksqlSyntaxParser.js


+ 32 - 4
desktop/core/src/desktop/js/parse/sql/sparksql/sqlParseSupport.js

@@ -193,20 +193,48 @@ const initSqlParser = function (parser) {
     return { suggestKeywords: keywords };
   };
 
+  parser.getDataSourceKeywords = function () {
+    return ['AVRO', 'CSV', 'HIVE', 'JDBC', 'ORC', 'PARQUET', 'TEXTFILE', 'TXT'];
+  };
+
   parser.getTypeKeywords = function () {
     return [
+      'ARRAY',
       'BIGINT',
+      'BINARY',
       'BOOLEAN',
-      'CHAR',
+      'BYTE',
+      'DATE',
+      'DEC',
       'DECIMAL',
       'DOUBLE',
       'FLOAT',
       'INT',
+      'INTEGER',
+      'INTERVAL YEAR',
+      'INTERVAL YEAR TO MONTH',
+      'INTERVAL MONTH',
+      'INTERVAL DAY',
+      'INTERVAL DAY TO HOUR',
+      'INTERVAL DAY TO MINUTE',
+      'INTERVAL DAY TO SECOND',
+      'INTERVAL HOUR',
+      'INTERVAL HOUR TO MINUTE',
+      'INTERVAL HOUR TO SECOND',
+      'INTERVAL MINUTE',
+      'INTERVAL MINUTE TO SECOND',
+      'INTERVAL SECOND',
+      'LONG',
+      'MAP',
+      'NUMERIC',
+      'REAL',
       'SMALLINT',
+      'STRUCT',
       'TIMESTAMP',
-      'STRING',
       'TINYINT',
-      'VARCHAR'
+      'STRING',
+      'SHORT',
+      'TINYINT'
     ];
   };
 
@@ -1002,7 +1030,7 @@ const initSqlParser = function (parser) {
   };
 
   parser.suggestDdlAndDmlKeywords = function (extraKeywords) {
-    let keywords = ['CREATE', 'DESCRIBE', 'SELECT', 'SHOW'];
+    let keywords = ['ALTER', 'CREATE', 'DESCRIBE', 'SELECT', 'SHOW'];
 
     if (extraKeywords) {
       keywords = keywords.concat(extraKeywords);

Some files were not shown because too many files changed in this diff