Browse Source

[editor] Add SparkSQL autocomplete for DROP, INSERT, LOAD, MSCK and TRUNCATE statements

Johan Åhlén 3 năm trước cách đây
mục cha
commit
11fc7d8521
30 tập tin đã thay đổi với 1929 bổ sung8 xóa
  1. 27 0
      desktop/core/src/desktop/js/parse/sql/generic/jison/drop/drop_view.test.json
  2. 4 4
      desktop/core/src/desktop/js/parse/sql/generic/jison/select/union_clause.test.json
  3. 7 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/alter/alter_common.jison
  4. 22 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_common.jison
  5. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_common.test.json
  6. 49 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_function.jison
  7. 59 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_function.test.json
  8. 57 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_table.jison
  9. 94 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_table.test.json
  10. 65 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_common.jison
  11. 72 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_common.test.json
  12. 109 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_overwrite_directory.jison
  13. 285 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_overwrite_directory.test.json
  14. 79 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_table.jison
  15. 252 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_table.test.json
  16. 81 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/load/load_data.jison
  17. 197 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/load/load_data.test.json
  18. 22 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/msck/msck_common.jison
  19. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/msck/msck_common.test.json
  20. 77 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/msck/msck_repair_table.jison
  21. 112 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/msck/msck_repair_table.test.json
  22. 14 3
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/sql.jisonlex
  23. 28 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/structure.json
  24. 22 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/truncate/truncate_common.jison
  25. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/truncate/truncate_common.test.json
  26. 55 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/truncate/truncate_table.jison
  27. 88 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/truncate/truncate_table.test.json
  28. 0 0
      desktop/core/src/desktop/js/parse/sql/sparksql/sparksqlAutocompleteParser.js
  29. 0 0
      desktop/core/src/desktop/js/parse/sql/sparksql/sparksqlSyntaxParser.js
  30. 13 1
      desktop/core/src/desktop/js/parse/sql/sparksql/sqlParseSupport.js

+ 27 - 0
desktop/core/src/desktop/js/parse/sql/generic/jison/drop/drop_view.test.json

@@ -80,5 +80,32 @@
         "onlyViews": true
       }
     }
+  },
+  {
+    "namePrefix": "should suggest views",
+    "beforeCursor": "DROP VIEW IF EXISTS foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ],
+        "onlyViews": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DROP VIEW ",
+    "afterCursor": " foo.bar",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "IF EXISTS"
+      ]
+    }
   }
 ]

+ 4 - 4
desktop/core/src/desktop/js/parse/sql/generic/jison/select/union_clause.test.json

@@ -3,11 +3,11 @@
     "namePrefix": "should suggest keywords",
     "beforeCursor": "SELECT * FROM database_two.testTable ORDER BY foo LIMIT 10 ",
     "afterCursor": "",
+    "containsKeywords": [
+      "UNION"
+    ],
     "expectedResult": {
-      "lowerCase": false,
-      "suggestKeywords": [
-        "UNION"
-      ]
+      "lowerCase": false
     }
   },
   {

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

@@ -32,6 +32,13 @@ PropertyAssignmentList
 
 PropertyAssignment
  : QuotedValue '=' UnsignedValueSpecification
+ | QuotedValue '=' RegularIdentifier
+ | QuotedValue RegularIdentifier
+ | QuotedValue QuotedValue
+ | RegularIdentifier '=' UnsignedValueSpecification
+ | RegularIdentifier UnsignedValueSpecification
+ | RegularIdentifier '=' RegularIdentifier
+ | RegularIdentifier RegularIdentifier
  ;
 
 ParenthesizedPropertyList

+ 22 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_common.jison

@@ -0,0 +1,22 @@
+// 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
+ : 'DROP' 'CURSOR'
+   {
+     parser.suggestKeywords(['DATABASE', 'FUNCTION', 'SCHEMA', 'TABLE', 'TEMPORARY FUNCTION', 'VIEW']);
+   }
+ ;

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

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

+ 49 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_function.jison

@@ -0,0 +1,49 @@
+// 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
+ : DropFunctionStatement
+ ;
+
+DataDefinition_EDIT
+ : DropFunctionStatement_EDIT
+ ;
+
+DropFunctionStatement
+ : 'DROP' OptionalTemporary 'FUNCTION' OptionalIfExists SchemaQualifiedIdentifier
+ ;
+
+DropFunctionStatement_EDIT
+ : 'DROP' 'TEMPORARY' 'CURSOR'
+   {
+     parser.suggestKeywords(['FUNCTION']);
+   }
+ | 'DROP' OptionalTemporary 'FUNCTION' OptionalIfExists 'CURSOR'
+   {
+     if (!$4) {
+       parser.suggestKeywords(['IF EXISTS']);
+     }
+   }
+ | 'DROP' OptionalTemporary 'FUNCTION' OptionalIfExists 'CURSOR' SchemaQualifiedIdentifier
+   {
+     if (!$4) {
+       parser.suggestKeywords(['IF EXISTS']);
+     }
+   }
+ | 'DROP' OptionalTemporary 'FUNCTION' OptionalIfExists_EDIT
+ | 'DROP' OptionalTemporary 'FUNCTION' OptionalIfExists_EDIT SchemaQualifiedIdentifier
+ | 'DROP' OptionalTemporary 'FUNCTION' OptionalIfExists SchemaQualifiedIdentifier_EDIT
+ ;

+ 59 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_function.test.json

@@ -0,0 +1,59 @@
+[
+  {
+    "namePrefix": "should handle",
+    "beforeCursor": "DROP TEMPORARY FUNCTION IF EXISTS baa;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DROP ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FUNCTION",
+      "TEMPORARY FUNCTION"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DROP TEMPORARY ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FUNCTION"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DROP FUNCTION ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "IF EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DROP FUNCTION IF ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "EXISTS"
+      ]
+    }
+  }
+]

+ 57 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_table.jison

@@ -0,0 +1,57 @@
+// 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
+ : DropTableStatement
+ ;
+
+DataDefinition_EDIT
+ : DropTableStatement_EDIT
+ ;
+
+DropTableStatement
+ : 'DROP' 'TABLE' OptionalIfExists SchemaQualifiedTableIdentifier
+   {
+     parser.addTablePrimary($4);
+   }
+ ;
+
+DropTableStatement_EDIT
+ : 'DROP' 'TABLE' OptionalIfExists_EDIT
+ | 'DROP' 'TABLE' OptionalIfExists 'CURSOR'
+   {
+     if (!$3) {
+       parser.suggestKeywords(['IF EXISTS']);
+     }
+     parser.suggestTables({ onlyTables: true });
+     parser.suggestDatabases({
+       appendDot: true
+     });
+   }
+ | 'DROP' 'TABLE' OptionalIfExists SchemaQualifiedTableIdentifier_EDIT
+   {
+     if (parser.yy.result.suggestTables) {
+       parser.yy.result.suggestTables.onlyTables = true;
+     }
+   }
+ | 'DROP' 'TABLE' OptionalIfExists 'CURSOR' SchemaQualifiedTableIdentifier
+   {
+     if (!$3) {
+       parser.suggestKeywords(['IF EXISTS']);
+     }
+   }
+ | 'DROP' 'TABLE' OptionalIfExists_EDIT SchemaQualifiedTableIdentifier
+ ;

+ 94 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_table.test.json

@@ -0,0 +1,94 @@
+[
+  {
+    "namePrefix": "should handle",
+    "beforeCursor": "DROP TABLE  IF EXISTS db.tbl;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DROP ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "DROP TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "onlyTables": true
+      },
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestKeywords": [
+        "IF EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DROP TABLE IF ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "EXISTS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "DROP TABLE IF EXISTS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "onlyTables": true
+      },
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "DROP TABLE IF EXISTS foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ],
+        "onlyTables": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DROP TABLE ",
+    "afterCursor": " foo.bar",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "IF EXISTS"
+      ]
+    }
+  }
+]

+ 65 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_common.jison

@@ -0,0 +1,65 @@
+// 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_EDIT
+ : 'INSERT' OptionalInsertOptions 'CURSOR'
+   {
+     var keywords = $2.tableKeywords || [];
+     if ($2.directoryKeywords) {
+       keywords = keywords.concat($2.directoryKeywords);
+     }
+     if (keywords.length) {
+       parser.suggestKeywords(keywords);
+     }
+     if ($2.suggestTables) {
+       parser.suggestTables({ tablesOnly: true });
+       parser.suggestDatabases({ appendDot: true });
+     }
+   }
+ ;
+
+OptionalInsertOptions
+ :                     -> { suggestTables: true, tableKeywords: ['INTO', 'INTO TABLE', 'OVERWRITE', 'OVERWRITE TABLE', 'TABLE'], directoryKeywords: ['OVERWRITE DIRECTORY', 'OVERWRITE LOCAL DIRECTORY'] }
+ | 'INTO'              -> { suggestTables: true, tableKeywords: ['TABLE'] }
+ | 'OVERWRITE'         -> { suggestTables: true, tableKeywords: ['TABLE'], directoryKeywords: ['DIRECTORY', 'LOCAL DIRECTORY'] }
+ | 'INTO' 'TABLE'      -> { suggestTables: true }
+ | 'OVERWRITE' 'TABLE' -> { suggestTables: true }
+ | 'TABLE'             -> { suggestTables: true }
+ | 'OVERWRITE' 'LOCAL' -> { directoryKeywords: ['DIRECTORY'] }
+ ;
+
+// TODO: FROM x SELECT y ...
+ValuesClauseOrQuerySpecification
+ : ValuesClause
+ | QuerySpecification
+ ;
+
+ValuesClauseOrQuerySpecification_EDIT
+ : QuerySpecification_EDIT
+ ;
+
+ValuesClause
+ : 'VALUES' ValuesList
+ ;
+
+ValuesList
+ : ParenthesizedRowValuesList
+ | ValuesList ',' ParenthesizedRowValuesList
+ ;
+
+ParenthesizedRowValuesList
+ : '(' InValueList ')'
+ ;

+ 72 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_common.test.json

@@ -0,0 +1,72 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "",
+    "afterCursor": "",
+    "containsKeywords": [
+      "INSERT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "INTO",
+        "INTO TABLE",
+        "OVERWRITE",
+        "OVERWRITE DIRECTORY",
+        "OVERWRITE LOCAL DIRECTORY",
+        "OVERWRITE TABLE",
+        "TABLE"
+      ],
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {
+        "tablesOnly": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT INTO ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "TABLE"
+      ],
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {
+        "tablesOnly": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "DIRECTORY",
+        "LOCAL DIRECTORY",
+        "TABLE"
+      ],
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {
+        "tablesOnly": true
+      }
+    }
+  }
+]

+ 109 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_overwrite_directory.jison

@@ -0,0 +1,109 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+DataManipulation
+ : InsertOverwriteDirectory
+ ;
+
+DataManipulation_EDIT
+ : InsertOverwriteDirectory_EDIT
+ ;
+
+InsertOverwriteDirectory
+ : 'INSERT' OptionalInsertOptions DirectoryWithOrWithoutPath OptionalSparkFormatOrHiveFormat ValuesClauseOrQuerySpecification
+ ;
+
+InsertOverwriteDirectory_EDIT
+ : 'INSERT' OptionalInsertOptions DirectoryWithOrWithoutPath_EDIT
+ | 'INSERT' OptionalInsertOptions DirectoryWithOrWithoutPath OptionalSparkFormatOrHiveFormat 'CURSOR'
+   {
+     var keywords = $4 && $4.suggestKeywords || [];
+     keywords.push('SELECT');
+     keywords.push('VALUES');
+     parser.suggestKeywords(keywords);
+   }
+ | 'INSERT' OptionalInsertOptions DirectoryWithOrWithoutPath SparkFormatOrHiveFormat_EDIT
+ | 'INSERT' OptionalInsertOptions DirectoryWithOrWithoutPath OptionalSparkFormatOrHiveFormat 'CURSOR' ValuesClauseOrQuerySpecification
+   {
+     parser.checkForKeywords($4);
+   }
+ | 'INSERT' OptionalInsertOptions DirectoryWithOrWithoutPath SparkFormatOrHiveFormat_EDIT ValuesClauseOrQuerySpecification
+ | 'INSERT' OptionalInsertOptions DirectoryWithOrWithoutPath OptionalSparkFormatOrHiveFormat ValuesClauseOrQuerySpecification_EDIT
+ ;
+
+DirectoryWithOrWithoutPath
+ : 'DIRECTORY_PATH' DirectoryHdfsPathRight
+ | 'DIRECTORY'
+ ;
+
+DirectoryWithOrWithoutPath_EDIT
+ : 'DIRECTORY_PATH' DirectoryHdfsPathRight_EDIT
+   {
+     parser.suggestHdfs($2);
+   }
+ ;
+
+OptionalSparkFormatOrHiveFormat
+ : OptionalRowFormat OptionalStoredAs
+   {
+     if (!$1 && !$2) {
+       $$ = { suggestKeywords: ['ROW FORMAT', 'STORED AS', 'USING'] }
+     } else if ($1 && !$2) {
+       if ($1.suggestKeywords) {
+         $1.suggestKeywords.push('STORED AS');
+       } else {
+         $$ = { suggestKeywords: ['STORED AS'] }
+       }
+     }
+   }
+ | 'USING' DataSource OptionalOptions
+   {
+     if (!$3) {
+       $$ = { suggestKeywords: ['OPTIONS'] }
+     }
+   }
+ ;
+
+SparkFormatOrHiveFormat_EDIT
+ : RowFormat_EDIT OptionalStoredAs
+ | OptionalRowFormat StoredAs_EDIT
+ | 'USING' 'CURSOR'
+   {
+     parser.suggestKeywords(parser.getDataSourceKeywords());
+   }
+ ;
+
+OptionalLocal
+ :
+ | 'LOCAL'
+ ;
+
+OptionalHdfsPath
+ :
+ | PushHdfsLexerState HdfsPath PopLexerState
+ ;
+
+DirectoryHdfsPathRight
+ : 'HDFS_PATH' 'HDFS_END_QUOTE'
+ ;
+
+DirectoryHdfsPathRight_EDIT
+ : 'HDFS_PATH' 'PARTIAL_CURSOR' 'HDFS_PATH' 'HDFS_END_QUOTE' -> { path: $1 }
+ | 'HDFS_PATH' 'PARTIAL_CURSOR' 'HDFS_END_QUOTE'             -> { path: $1 }
+ | 'HDFS_PATH' 'PARTIAL_CURSOR'                              -> { path: $1 }
+ | 'PARTIAL_CURSOR' 'HDFS_END_QUOTE'                         -> { path: '' }
+ | 'PARTIAL_CURSOR'                                          -> { path: '' }
+ ;

+ 285 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_overwrite_directory.test.json

@@ -0,0 +1,285 @@
+[
+  {
+    "namePrefix": "should handle ",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/blabla/bla' USING parquet OPTIONS (col1 = 1, col2 = 2, col3 = test) SELECT * FROM boo;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should handle ",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY\nUSING parquet\nOPTIONS ('path' '/tmp/destination', col1 1, col2 2, col3 'test')\n    SELECT * FROM test_table;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should handle ",
+    "beforeCursor": "INSERT OVERWRITE LOCAL DIRECTORY '/tmp/destination'\n    ROW FORMAT DELIMITED FIELDS TERMINATED BY ','\n    SELECT * FROM test_table;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE LOCAL ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "DIRECTORY"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest paths",
+    "beforeCursor": "INSERT OVERWRITE LOCAL DIRECTORY '",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": {
+        "path": ""
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest paths",
+    "beforeCursor": "INSERT OVERWRITE LOCAL DIRECTORY '/bla/bla/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": {
+        "path": "/bla/bla/"
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "ROW FORMAT",
+        "SELECT",
+        "STORED AS",
+        "USING",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "ROW FORMAT",
+        "SELECT",
+        "STORED AS",
+        "USING",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' ROW ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "FORMAT"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' ROW FORMAT ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "DELIMITED",
+        "SERDE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' ROW FORMAT DELIMITED ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "FIELDS TERMINATED BY",
+        "COLLECTION ITEMS TERMINATED BY",
+        "MAP KEYS TERMINATED BY",
+        "LINES TERMINATED BY",
+        "NULL DEFINED AS",
+        "SELECT",
+        "STORED AS",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' ROW FORMAT DELIMITED NULL ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "DEFINED AS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' ROW FORMAT DELIMITED FIELDS TERMINATED BY 'a' ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "STORED AS",
+      "SELECT",
+      "VALUES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' USING ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "PARQUET"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' USING PARQUET ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "OPTIONS",
+        "SELECT",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' USING PARQUET OPTIONS (a b) ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "SELECT",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY USING PARQUET OPTIONS (a b) ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "SELECT",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' USING PARQUET OPTIONS (a b) SELECT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "*",
+      "CASE",
+      "ALL",
+      "DISTINCT",
+      "FALSE",
+      "NULL",
+      "TRUE"
+    ],
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestAggregateFunctions": {
+        "tables": []
+      },
+      "suggestAnalyticFunctions": true,
+      "suggestFunctions": {},
+      "suggestTables": {
+        "prependQuestionMark": true,
+        "prependFrom": true
+      },
+      "suggestDatabases": {
+        "prependQuestionMark": true,
+        "prependFrom": true,
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE DIRECTORY '/foo' ROW FORMAT DELIMITED FIELDS TERMINATED BY 'a' SELECT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "*",
+      "CASE",
+      "ALL",
+      "DISTINCT",
+      "FALSE",
+      "NULL",
+      "TRUE"
+    ],
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestAggregateFunctions": {
+        "tables": []
+      },
+      "suggestAnalyticFunctions": true,
+      "suggestFunctions": {},
+      "suggestTables": {
+        "prependQuestionMark": true,
+        "prependFrom": true
+      },
+      "suggestDatabases": {
+        "prependQuestionMark": true,
+        "prependFrom": true,
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest paths",
+    "beforeCursor": "INSERT OVERWRITE LOCAL DIRECTORY '/bla/bla/' ROW FORMAT ",
+    "afterCursor": " VALUES (1,2,3);",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": ["DELIMITED", "SERDE"]
+    }
+  }
+]

+ 79 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_table.jison

@@ -0,0 +1,79 @@
+// 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
+ : InsertTableStatement
+ ;
+
+DataManipulation_EDIT
+ : InsertTableStatement_EDIT
+ ;
+
+InsertTableStatement
+ : 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList ValuesClauseOrQuerySpecification
+ ;
+
+InsertTableStatement_EDIT
+ : 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec OptionalParenthesizedColumnList
+   {
+     if (parser.yy.result.suggestTables) {
+       parser.yy.result.suggestTables.tablesOnly = true;
+     }
+   }
+ | 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList 'CURSOR'
+   {
+     if (!$5 && !$4) {
+       parser.suggestKeywords(['PARTITION', 'SELECT', 'VALUES']);
+     } else {
+       parser.suggestKeywords(['SELECT', 'VALUES']);
+     }
+   }
+ | 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier PartitionSpec_EDIT OptionalParenthesizedColumnList
+   {
+     parser.addTablePrimary($3);
+   }
+ | 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier PartitionSpec_EDIT OptionalParenthesizedColumnList ValuesClauseOrQuerySpecification
+   {
+     parser.addTablePrimary($3);
+   }
+ | 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier OptionalPartitionSpec ParenthesizedColumnList_EDIT
+   {
+     parser.addTablePrimary($3);
+   }
+ | 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier OptionalPartitionSpec ParenthesizedColumnList_EDIT ValuesClauseOrQuerySpecification
+   {
+     parser.addTablePrimary($3);
+   }
+ | 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec OptionalParenthesizedColumnList ValuesClauseOrQuerySpecification
+   {
+     if (parser.yy.result.suggestTables) {
+       parser.yy.result.suggestTables.tablesOnly = true;
+     }
+   }
+ | 'INSERT' OptionalInsertOptions 'CURSOR' SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList ValuesClauseOrQuerySpecification
+   {
+     if ($2.tableKeywords) {
+       parser.suggestKeywords($2.tableKeywords);
+     }
+   }
+ | 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList 'CURSOR' ValuesClauseOrQuerySpecification
+   {
+     if (!$4 && !$5) {
+       parser.suggestKeywords(['PARTITION']);
+     }
+   }
+ | 'INSERT' OptionalInsertOptions SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalParenthesizedColumnList ValuesClauseOrQuerySpecification_EDIT
+ ;

+ 252 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_table.test.json

@@ -0,0 +1,252 @@
+[
+  {
+    "namePrefix": "should handle",
+    "beforeCursor": "INSERT INTO TABLE db.tbl PARTITION (a=1,b=2) (c,d) VALUES (NULL , 1), ( 2, 3 ); ",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should handle",
+    "beforeCursor": "INSERT INTO TABLE db.tbl PARTITION (a=1,b=2) (c,d) SELECT 1; ",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "INSERT db.",
+    "afterCursor": "",
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "db"
+          }
+        ],
+        "tablesOnly": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "INSERT INTO db.",
+    "afterCursor": "",
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "db"
+          }
+        ],
+        "tablesOnly": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "INSERT OVERWRITE TABLE db.",
+    "afterCursor": "",
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "db"
+          }
+        ],
+        "tablesOnly": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT db ",
+    "afterCursor": "",
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITION",
+        "SELECT",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "INSERT OVERWRITE TABLE foo.tbl ( ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "tbl"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "INSERT OVERWRITE TABLE foo.tbl PARTITION ( ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "tbl"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "INSERT OVERWRITE TABLE foo.tbl PARTITION (a = 1) (b, c, ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "tbl"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT INTO TABLE db.tbl PARTITION (a = 1) (b) ",
+    "afterCursor": "",
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "SELECT",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE tbl (b) ",
+    "afterCursor": "",
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "SELECT",
+        "VALUES"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE tbl PARTITION (b = '123') SELECT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "*",
+      "CASE",
+      "ALL",
+      "DISTINCT",
+      "FALSE",
+      "NULL",
+      "TRUE"
+    ],
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestAggregateFunctions": {
+        "tables": []
+      },
+      "suggestAnalyticFunctions": true,
+      "suggestFunctions": {},
+      "suggestTables": {
+        "prependQuestionMark": true,
+        "prependFrom": true
+      },
+      "suggestDatabases": {
+        "prependQuestionMark": true,
+        "prependFrom": true,
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT ",
+    "afterCursor": " db.tbl VALUES (1);",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "INTO",
+        "INTO TABLE",
+        "OVERWRITE",
+        "OVERWRITE TABLE",
+        "TABLE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE ",
+    "afterCursor": " db.tbl VALUES (1);",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "TABLE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "INSERT OVERWRITE db.tbl ",
+    "afterCursor": " SELECT * FROM foo;",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITION"
+      ]
+    }
+  }
+]

+ 81 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/load/load_data.jison

@@ -0,0 +1,81 @@
+// 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
+ : LoadDataStatement
+ ;
+
+DataManipulation_EDIT
+ : LoadDataStatement_EDIT
+ ;
+
+LoadDataStatement
+ : 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath OptionalOverwrite 'INTO' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec
+ ;
+
+LoadDataStatement_EDIT
+ : 'LOAD' 'CURSOR'
+   {
+     parser.suggestKeywords(['DATA LOCAL INPATH', 'DATA INPATH']);
+   }
+ | 'LOAD' 'DATA' OptionalLocal 'CURSOR'
+   {
+     if (!$3) {
+       parser.suggestKeywords(['INPATH', 'LOCAL INPATH']);
+     } else {
+       parser.suggestKeywords(['INPATH']);
+     }
+   }
+ | 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath_EDIT OptionalOverwrite
+ | 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath OptionalOverwrite 'CURSOR'
+   {
+     if (!$6) {
+       parser.suggestKeywords(['OVERWRITE INTO TABLE', 'INTO TABLE']);
+     } else {
+       parser.suggestKeywords(['INTO TABLE']);
+     }
+   }
+ | 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath OptionalOverwrite 'INTO' 'CURSOR'
+   {
+     parser.suggestKeywords([ 'TABLE' ]);
+   }
+ | 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath OptionalOverwrite 'INTO' 'TABLE' 'CURSOR'
+   {
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath OptionalOverwrite 'INTO' 'TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec
+ | 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath OptionalOverwrite 'INTO' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
+   {
+     parser.addTablePrimary($9);
+     if (!$10) {
+       parser.suggestKeywords(['PARTITION']);
+     }
+   }
+ | 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath OptionalOverwrite 'INTO' 'TABLE' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
+   {
+     parser.addTablePrimary($9);
+   }
+ | 'LOAD' 'DATA' OptionalLocal 'INPATH' HdfsPath_EDIT OptionalOverwrite 'INTO' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec
+   {
+     parser.addTablePrimary($9);
+   }
+ ;
+
+OptionalOverwrite
+ :
+ | 'OVERWRITE'
+ ;

+ 197 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/load/load_data.test.json

@@ -0,0 +1,197 @@
+[
+  {
+    "namePrefix": "should handle ",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/warehouse/test_partition/c2=2/c3=3'\n    OVERWRITE INTO TABLE test_load_partition PARTITION (c2=2, c3=3);",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "",
+    "afterCursor": "",
+    "containsKeywords": [
+      "LOAD"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "DATA INPATH",
+        "DATA LOCAL INPATH"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD DATA ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "INPATH",
+        "LOCAL INPATH"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD DATA LOCAL ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "INPATH"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LOAD DATA INPATH '",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": {
+        "path": ""
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LOAD DATA INPATH '/foo",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": {
+        "path": "/"
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LOAD DATA INPATH '/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": {
+        "path": "/foo/"
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "INTO TABLE",
+        "OVERWRITE INTO TABLE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "INTO TABLE",
+        "OVERWRITE INTO TABLE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' OVERWRITE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "INTO TABLE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' OVERWRITE INTO ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "TABLE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' INTO ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "TABLE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' INTO TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' OVERWRITE INTO TABLE foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' INTO TABLE foo ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITION"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "LOAD DATA LOCAL INPATH '/boo' INTO TABLE foo PARTITION (",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": { "tables": [{ "identifierChain": [{ "name": "foo" }] }] }
+    }
+  }
+]

+ 22 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/msck/msck_common.jison

@@ -0,0 +1,22 @@
+// 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
+ : 'MSCK' 'CURSOR'
+   {
+     parser.suggestKeywords(['REPAIR TABLE']);
+   }
+ ;

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

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

+ 77 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/msck/msck_repair_table.jison

@@ -0,0 +1,77 @@
+// 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
+ : Msck
+ ;
+
+DataDefinition_EDIT
+ : Msck_EDIT
+ ;
+
+Msck
+ : 'MSCK' 'REPAIR' 'TABLE' SchemaQualifiedTableIdentifier OptionalAddDropSyncPartitions
+   {
+     parser.addTablePrimary($4);
+   }
+ ;
+
+Msck_EDIT
+ : 'MSCK' 'REPAIR' 'CURSOR'
+   {
+     parser.suggestKeywords(['TABLE']);
+   }
+ | 'MSCK' 'REPAIR' 'TABLE' 'CURSOR'
+   {
+     parser.suggestTables({ onlyTables: true });
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | 'MSCK' 'REPAIR' 'TABLE' SchemaQualifiedTableIdentifier_EDIT
+   {
+     if (parser.yy.result.suggestTables) {
+       parser.yy.result.suggestTables.onlyTables = true;
+     }
+   }
+ | 'MSCK' 'REPAIR' 'TABLE' SchemaQualifiedTableIdentifier AddDropSyncPartitions_EDIT
+   {
+     parser.addTablePrimary($4);
+   }
+ | 'MSCK' 'REPAIR' 'TABLE' SchemaQualifiedTableIdentifier OptionalAddDropSyncPartitions 'CURSOR'
+   {
+     parser.addTablePrimary($4);
+     if (!$5) {
+       parser.suggestKeywords(['ADD PARTITIONS', 'DROP PARTITIONS', 'SYNC PARTITIONS']);
+     }
+   }
+ ;
+
+OptionalAddDropSyncPartitions
+ :
+ | AddDropOrSync 'PARTITIONS'
+ ;
+
+AddDropSyncPartitions_EDIT
+ : AddDropOrSync 'CURSOR'
+   {
+     parser.suggestKeywords(['PARTITIONS']);
+   }
+ ;
+
+AddDropOrSync
+ : 'ADD'
+ | 'DROP'
+ | 'SYNC'
+ ;

+ 112 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/msck/msck_repair_table.test.json

@@ -0,0 +1,112 @@
+[
+  {
+    "namePrefix": "should handle",
+    "beforeCursor": "MSCK REPAIR TABLE db.tbl ADD PARTITIONS;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "MSCK ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "REPAIR TABLE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "MSCK REPAIR ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "MSCK REPAIR TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "onlyTables": true
+      },
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "MSCK REPAIR TABLE foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ],
+        "onlyTables": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "MSCK REPAIR TABLE foo.bar ",
+    "afterCursor": " ",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "ADD PARTITIONS",
+        "DROP PARTITIONS",
+        "SYNC PARTITIONS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "MSCK REPAIR TABLE foo.bar ADD ",
+    "afterCursor": " ",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITIONS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "MSCK REPAIR TABLE foo.bar DROP ",
+    "afterCursor": " ",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITIONS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "MSCK REPAIR TABLE foo.bar SYNC ",
+    "afterCursor": " ",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITIONS"
+      ]
+    }
+  }
+]

+ 14 - 3
desktop/core/src/desktop/js/parse/sql/sparksql/jison/sql.jisonlex

@@ -16,7 +16,7 @@
 
 %options case-insensitive flex
 %s between
-%x hdfs doubleQuotedValue singleQuotedValue backtickedValue
+%x hdfs hdfsv2 doubleQuotedValue singleQuotedValue backtickedValue
 %%
 
 \s                                         { /* skip whitespace */ }
@@ -66,7 +66,7 @@
 'IF'                                       { return 'IF'; }
 'IN'                                       { return 'IN'; }
 'INNER'                                    { return 'INNER'; }
-'INSERT'                                   { return 'INSERT'; }
+'INSERT'                                   { parser.determineCase(yytext); return 'INSERT'; }
 'INT'                                      { return 'INT'; }
 'INTO'                                     { return 'INTO'; }
 'IS'                                       { return 'IS'; }
@@ -128,12 +128,14 @@
 'CLUSTERED'                                { return 'CLUSTERED'; }
 'COLLECTION'                               { return 'COLLECTION'; }
 'COLUMN'                                   { return 'COLUMN'; }
+'DATA'                                     { return 'DATA'; }
 'DATE'                                     { return 'DATE'; }
 'DAY'                                      { return 'DAY'; }
 'DBPROPERTIES'                             { return 'DBPROPERTIES'; }
 'DEC'                                      { return 'DEC'; }
 'DEFINED'                                  { return 'DEFINED'; }
 'DELIMITED'                                { return 'DELIMITED'; }
+'DIRECTORY'                                { return 'DIRECTORY'; }
 'ESCAPED'                                  { return 'ESCAPED'; }
 'EXTERNAL'                                 { return 'EXTERNAL'; }
 'FIELDS'                                   { return 'FIELDS'; }
@@ -143,20 +145,25 @@
 'FUNCTION'                                 { return 'FUNCTION'; }
 'GLOBAL'                                   { return 'GLOBAL'; }
 'HOUR'                                     { return 'HOUR'; }
+'INPATH'                                   { this.begin('hdfs'); return 'INPATH'; }
 'INTEGER'                                  { return 'INTEGER'; }
 'INTERVAL'                                 { return 'INTERVAL'; }
 'ITEMS'                                    { return 'ITEMS'; }
 'JAR'                                      { return 'JAR'; }
 'KEYS'                                     { return 'KEYS'; }
 'LINES'                                    { return 'LINES'; }
+'LOAD'                                     { parser.determineCase(yytext); return 'LOAD'; }
+'LOCAL'                                    { return 'LOCAL'; }
 'LOCATION'                                 { return 'LOCATION'; }
 'LONG'                                     { return 'LONG'; }
 'MAP'                                      { return 'MAP'; }
 'MINUTE'                                   { return 'MINUTE'; }
 'MONTH'                                    { return 'MONTH'; }
+'MSCK'                                     { return 'MSCK'; }
 'NAMESPACE'                                { return 'NAMESPACE'; }
 'NUMERIC'                                  { return 'NUMERIC'; }
 'OPTIONS'                                  { return 'OPTIONS'; }
+'OVERWRITE'                                { return 'OVERWRITE'; }
 'PARTITIONED'                              { return 'PARTITIONED'; }
 'PARTITIONS'                               { return 'PARTITIONS'; }
 'PROPERTIES'                               { return 'PROPERTIES'; }
@@ -164,12 +171,15 @@
 'RECOVER'                                  { return 'RECOVER'; }
 'RENAME'                                   { return 'RENAME'; }
 'REPLACE'                                  { return 'REPLACE'; }
+'REPAIR'                                   { return 'REPAIR'; }
+'RESTRICT'                                 { return 'RESTRICT'; }
 'SECOND'                                   { return 'SECOND'; }
 'SERDE'                                    { return 'SERDE'; }
 'SERDEPROPERTIES'                          { return 'SERDEPROPERTIES'; }
 'SHORT'                                    { return 'SHORT'; }
 'SORTED'                                   { return 'SORTED'; }
 'STORED'                                   { return 'STORED'; }
+'SYNC'                                     { return 'SYNC'; }
 'TBLPROPERTIES'                            { return 'TBLPROPERTIES'; }
 'TEMPORARY'                                { return 'TEMPORARY'; }
 'TERMINATED'                               { return 'TERMINATED'; }
@@ -216,6 +226,7 @@ ROW_NUMBER\s*\(                            { yy.lexer.unput('('); yytext = 'row_
 [0-9]+E                                    { return 'UNSIGNED_INTEGER_E'; }
 [A-Za-z0-9_]+                              { return 'REGULAR_IDENTIFIER'; }
 
+DIRECTORY\s+['"]                           { this.begin('hdfs'); return 'DIRECTORY_PATH'; }
 <hdfs>'\u2020'                             { parser.yy.cursorFound = true; return 'CURSOR'; }
 <hdfs>'\u2021'                             { parser.yy.cursorFound = true; return 'PARTIAL_CURSOR'; }
 <hdfs>\s+['"]                              { return 'HDFS_START_QUOTE'; }
@@ -268,7 +279,7 @@ ROW_NUMBER\s*\(                            { yy.lexer.unput('('); yytext = 'row_
 <backtickedValue>\`                        { this.popState(); return 'BACKTICK'; }
 
 \'                                         { this.begin('singleQuotedValue'); return 'SINGLE_QUOTE'; }
-<singleQuotedValue>(?:\\\\|\\[']|[^'])+         {
+<singleQuotedValue>(?:\\\\|\\[']|[^'])+    {
                                              if (parser.handleQuotedValueWithCursor(this, yytext, yylloc, '\'')) {
                                                return 'PARTIAL_VALUE';
                                              }

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

@@ -14,6 +14,17 @@
     "create/create_table.jison",
     "create/create_view.jison",
     "../../hive/jison/create/row_format.jison",
+    "drop/drop_common.jison",
+    "../../impala/jison/drop/drop_database.jison",
+    "drop/drop_function.jison",
+    "drop/drop_table.jison",
+    "../../generic/jison/drop/drop_view.jison",
+    "insert/insert_common.jison",
+    "insert/insert_overwrite_directory.jison",
+    "insert/insert_table.jison",
+    "load/load_data.jison",
+    "msck/msck_common.jison",
+    "msck/msck_repair_table.jison",
     "../../generic/jison/select/cte_select_statement.jison",
     "../../generic/jison/select/from_clause.jison",
     "../../generic/jison/select/group_by_clause.jison",
@@ -46,6 +57,9 @@
     "../../generic/jison/sql_error.jison",
     "../../generic/jison/sql_main.jison",
     "../../generic/jison/sql_valueExpression.jison",
+    "truncate/truncate_common.jison",
+    "truncate/truncate_table.jison",
+    "../../generic/jison/use/use.jison",
     "../../generic/jison/autocomplete_footer.jison"
   ],
   "syntax": [
@@ -62,6 +76,17 @@
     "create/create_table.jison",
     "create/create_view.jison",
     "../../hive/jison/create/row_format.jison",
+    "drop/drop_common.jison",
+    "../../impala/jison/drop/drop_database.jison",
+    "drop/drop_function.jison",
+    "drop/drop_table.jison",
+    "../../generic/jison/drop/drop_view.jison",
+    "insert/insert_common.jison",
+    "insert/insert_overwrite_directory.jison",
+    "insert/insert_table.jison",
+    "load/load_data.jison",
+    "msck/msck_common.jison",
+    "msck/msck_repair_table.jison",
     "../../generic/jison/select/cte_select_statement.jison",
     "../../generic/jison/select/from_clause.jison",
     "../../generic/jison/select/group_by_clause.jison",
@@ -93,6 +118,9 @@
     "../../generic/jison/udf/udf_common.jison",
     "../../generic/jison/sql_main.jison",
     "../../generic/jison/sql_valueExpression.jison",
+    "truncate/truncate_common.jison",
+    "truncate/truncate_table.jison",
+    "../../generic/jison/use/use.jison",
     "../../generic/jison/syntax_footer.jison"
   ]
 }

+ 22 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/truncate/truncate_common.jison

@@ -0,0 +1,22 @@
+// 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
+ : 'TRUNCATE' 'CURSOR'
+   {
+     parser.suggestKeywords(['TABLE']);
+   }
+ ;

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

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

+ 55 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/truncate/truncate_table.jison

@@ -0,0 +1,55 @@
+// 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
+ : TruncateTableStatement
+ ;
+
+DataDefinition_EDIT
+ : TruncateTableStatement_EDIT
+ ;
+
+TruncateTableStatement
+ : 'TRUNCATE' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+TruncateTableStatement_EDIT
+ : 'TRUNCATE' 'TABLE' 'CURSOR' OptionalPartitionSpec
+   {
+     parser.suggestTables({ onlyTables: true });
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | 'TRUNCATE' 'TABLE' SchemaQualifiedTableIdentifier_EDIT OptionalPartitionSpec
+   {
+     if (parser.yy.result.suggestTables) {
+       parser.yy.result.suggestTables.onlyTables = true;
+     }
+   }
+ | 'TRUNCATE' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
+   {
+     parser.addTablePrimary($3);
+     if (!$4) {
+       parser.suggestKeywords(['PARTITION']);
+     }
+   }
+ | 'TRUNCATE' 'TABLE' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
+   {
+     parser.addTablePrimary($3);
+   }
+ ;

+ 88 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/truncate/truncate_table.test.json

@@ -0,0 +1,88 @@
+[
+  {
+    "namePrefix": "should handle",
+    "beforeCursor": "TRUNCATE TABLE table_identifier PARTITION (a = 1, b = 2);",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true,
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "TRUNCATE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "TRUNCATE TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "onlyTables": true
+      },
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "TRUNCATE TABLE foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ],
+        "onlyTables": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "TRUNCATE TABLE foo.bar ",
+    "afterCursor": " ",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITION"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "TRUNCATE TABLE foo.bar PARTITION (",
+    "afterCursor": " ",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+]

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/sparksqlAutocompleteParser.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/sparksqlSyntaxParser.js


+ 13 - 1
desktop/core/src/desktop/js/parse/sql/sparksql/sqlParseSupport.js

@@ -1030,7 +1030,19 @@ const initSqlParser = function (parser) {
   };
 
   parser.suggestDdlAndDmlKeywords = function (extraKeywords) {
-    let keywords = ['ALTER', 'CREATE', 'DESCRIBE', 'SELECT', 'SHOW'];
+    let keywords = [
+      'ALTER',
+      'CREATE',
+      'DESCRIBE',
+      'DROP',
+      'INSERT',
+      'LOAD',
+      'MSCK',
+      'SELECT',
+      'SHOW',
+      'TRUNCATE',
+      'USE'
+    ];
 
     if (extraKeywords) {
       keywords = keywords.concat(extraKeywords);

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác