Эх сурвалжийг харах

[editor] Add SparkSQL autocomplete for auxiliary statements

This adds support for ADD, ANALYZE, CACHE, CLEAR, DESCRIBE, LIST, REFRESH, SET, SHOW and UNCACHE statements
Johan Åhlén 3 жил өмнө
parent
commit
6bec0b99b2
100 өөрчлөгдсөн 6555 нэмэгдсэн , 89 устгасан
  1. 0 0
      desktop/core/src/desktop/js/parse/sql/generic/genericAutocompleteParser.js
  2. 0 0
      desktop/core/src/desktop/js/parse/sql/generic/genericSyntaxParser.js
  3. 7 4
      desktop/core/src/desktop/js/parse/sql/generic/jison/sql_main.jison
  4. 35 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_archive.jison
  5. 130 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_archive.test.json
  6. 39 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_archives.jison
  7. 61 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_archives.test.json
  8. 57 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_common.jison
  9. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_common.test.json
  10. 35 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_file.jison
  11. 130 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_file.test.json
  12. 39 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_files.jison
  13. 61 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_files.test.json
  14. 35 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_jar.jison
  15. 142 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_jar.test.json
  16. 39 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_jars.jison
  17. 61 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_jars.test.json
  18. 22 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_common.jison
  19. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_common.test.json
  20. 92 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_table.jison
  21. 220 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_table.test.json
  22. 55 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_tables.jison
  23. 134 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_tables.test.json
  24. 22 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/cache/cache_common.jison
  25. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/cache/cache_common.test.json
  26. 110 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/cache/cache_table.jison
  27. 181 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/cache/cache_table.test.json
  28. 6 8
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/clear/clear_cache.jison
  29. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/clear/clear_cache.test.json
  30. 22 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/clear/clear_common.jison
  31. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/clear/clear_common.test.json
  32. 48 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_common.jison
  33. 11 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_common.test.json
  34. 41 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_database.jison
  35. 46 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_database.test.json
  36. 40 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_function.jison
  37. 70 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_function.test.json
  38. 37 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_query.jison
  39. 63 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_query.test.json
  40. 53 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_table.jison
  41. 137 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_table.test.json
  42. 1 1
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_function.test.json
  43. 1 1
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/drop/drop_table.test.json
  44. 6 4
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_overwrite_directory.test.json
  45. 2 2
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/insert/insert_table.test.json
  46. 35 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_archive.jison
  47. 135 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_archive.test.json
  48. 39 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_archives.jison
  49. 61 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_archives.test.json
  50. 24 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_common.jison
  51. 13 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_common.test.json
  52. 36 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_file.jison
  53. 135 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_file.test.json
  54. 39 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_files.jison
  55. 61 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_files.test.json
  56. 35 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_jar.jison
  57. 147 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_jar.test.json
  58. 39 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_jars.jison
  59. 61 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_jars.test.json
  60. 1 1
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/load/load_data.test.json
  61. 1508 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/main.jison
  62. 46 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/main.test.json
  63. 1 1
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/msck/msck_repair_table.test.json
  64. 24 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_common.jison
  65. 10 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_common.test.json
  66. 34 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_function.jison
  67. 37 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_function.test.json
  68. 23 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_resource.jison
  69. 11 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_resource.test.json
  70. 38 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_table.jison
  71. 45 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_table.test.json
  72. 28 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/reset/reset_config.jison
  73. 28 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/reset/reset_config.test.json
  74. 20 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/set/set_common.jison
  75. 35 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/set/set_config.jison
  76. 50 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/set/set_config.test.json
  77. 52 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_columns.jison
  78. 91 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_columns.test.json
  79. 45 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_common.jison
  80. 10 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_common.test.json
  81. 64 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_create_table.jison
  82. 77 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_create_table.test.json
  83. 41 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_databases.jison
  84. 45 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_databases.test.json
  85. 47 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_functions.jison
  86. 104 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_functions.test.json
  87. 49 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_partitions.jison
  88. 93 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_partitions.test.json
  89. 51 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_table_extended.jison
  90. 76 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_table_extended.test.json
  91. 39 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_tables.jison
  92. 77 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_tables.test.json
  93. 46 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_tblproperties.jison
  94. 62 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_tblproperties.test.json
  95. 39 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_views.jison
  96. 77 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_views.test.json
  97. 100 62
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/sql.jisonlex
  98. 92 4
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/structure.json
  99. 1 1
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/truncate/truncate_table.test.json
  100. 22 0
      desktop/core/src/desktop/js/parse/sql/sparksql/jison/uncache/uncache_common.jison

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
desktop/core/src/desktop/js/parse/sql/generic/genericAutocompleteParser.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
desktop/core/src/desktop/js/parse/sql/generic/genericSyntaxParser.js


+ 7 - 4
desktop/core/src/desktop/js/parse/sql/generic/jison/sql_main.jison

@@ -135,7 +135,6 @@ NonStartingToken
  | 'CURRENT'
  | 'DATABASE'
  | 'DECIMAL'
- | 'DESC'
  | 'DISTINCT'
  | 'DOUBLE'
  | 'DOUBLE_QUOTE'
@@ -260,12 +259,16 @@ QuotedValue_EDIT
  | DoubleQuotedValue_EDIT
  ;
 
-OptionalFromDatabase
+OptionalFromOrInDatabase
  :
- | FromOrIn DatabaseIdentifier
+ | FromOrInDatabases
  ;
 
-OptionalFromDatabase_EDIT
+FromOrInDatabases
+ : FromOrIn DatabaseIdentifier
+ ;
+
+FromOrInDatabase_EDIT
  : FromOrIn DatabaseIdentifier_EDIT
  ;
 

+ 35 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_archive.jison

@@ -0,0 +1,35 @@
+// 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.
+
+Auxiliary
+ : AddArchive
+ ;
+
+Auxiliary_EDIT
+ : AddArchive_EDIT
+ ;
+
+AddArchive
+ : 'ADD_ARCHIVE' FilePath
+ ;
+
+AddArchive_EDIT
+ : 'ADD_ARCHIVE' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_ARCHIVE' FilePath_EDIT
+ ;

+ 130 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_archive.test.json

@@ -0,0 +1,130 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD ARCHIVE /tmp/test;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD ARCHIVE \"/path/to/file/abc.txt\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD ARCHIVE '/path/to/file with space/abc.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ADD ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ARCHIVE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE /boo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/boo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE '",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE '/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE '/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE \"",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE \"/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVE \"/foo bar/partial",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  }
+]

+ 39 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_archives.jison

@@ -0,0 +1,39 @@
+// 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.
+
+Auxiliary
+ : AddArchives
+ ;
+
+Auxiliary_EDIT
+ : AddArchives_EDIT
+ ;
+
+AddArchives
+ : 'ADD_ARCHIVES' FilePaths
+ ;
+
+AddArchives_EDIT
+ : 'ADD_ARCHIVES' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_ARCHIVES' FilePaths 'CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_ARCHIVES' FilePaths_EDIT
+ ;

+ 61 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_archives.test.json

@@ -0,0 +1,61 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD ARCHIVES /tmp/test.txt \"/path with space/cde.txt\" '/path with space/fgh.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ADD ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ARCHIVES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVES /boo/file.txt /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVES /boo/file1.txt \"/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVES '/boo/file2.txt' \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD ARCHIVES '/boo/file2.txt' /foo.txt '/foo /bar/bla",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo /bar/" }
+    }
+  }
+]

+ 57 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_common.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.
+
+Auxiliary_EDIT
+ : 'ADD' 'CURSOR'
+   {
+     parser.suggestKeywords(['ARCHIVE', 'ARCHIVES', 'FILE', 'FILES', 'JAR', 'JARS']);
+   }
+ ;
+
+FilePaths
+ : FilePath
+ | FilePaths 'WHITESPACE' FilePath
+ ;
+
+FilePaths_EDIT
+ : FilePath_EDIT
+ | FilePaths 'WHITESPACE' FilePath_EDIT
+ ;
+
+FilePath
+ : 'FILE_QUOTE' FilePathWithWhitespace 'FILE_QUOTE'
+ | 'FILE_PATH'
+ ;
+
+FilePath_EDIT
+ : 'FILE_QUOTE' AnyCursor
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'FILE_QUOTE' FilePathWithWhitespace AnyCursor
+   {
+     parser.suggestHdfs({ path: $2 });
+   }
+ | 'FILE_PATH' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: $1 });
+   }
+ ;
+
+FilePathWithWhitespace
+ : 'FILE_PATH'
+ | FilePathWithWhitespace 'WHITESPACE' 'FILE_PATH' -> $1 + $2 + $3
+ ;

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

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

+ 35 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_file.jison

@@ -0,0 +1,35 @@
+// 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.
+
+Auxiliary
+ : AddFile
+ ;
+
+Auxiliary_EDIT
+ : AddFile_EDIT
+ ;
+
+AddFile
+ : 'ADD_FILE' FilePath
+ ;
+
+AddFile_EDIT
+ : 'ADD_FILE' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_FILE' FilePath_EDIT
+ ;

+ 130 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_file.test.json

@@ -0,0 +1,130 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD FILE /tmp/test;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD FILE \"/path/to/file/abc.txt\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD FILE '/path/to/file with space/abc.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ADD ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FILE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE /boo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/boo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE '",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE '/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE '/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE \"",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE \"/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILE \"/foo bar/partial",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  }
+]

+ 39 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_files.jison

@@ -0,0 +1,39 @@
+// 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.
+
+Auxiliary
+ : AddFiles
+ ;
+
+Auxiliary_EDIT
+ : AddFiles_EDIT
+ ;
+
+AddFiles
+ : 'ADD_FILES' FilePaths
+ ;
+
+AddFiles_EDIT
+ : 'ADD_FILES' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_FILES' FilePaths 'CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_FILES' FilePaths_EDIT
+ ;

+ 61 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_files.test.json

@@ -0,0 +1,61 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD FILES /tmp/test.txt \"/path with space/cde.txt\" '/path with space/fgh.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ADD ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FILES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILES /boo/file.txt /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILES /boo/file1.txt \"/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILES '/boo/file2.txt' \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD FILES '/boo/file2.txt' /foo.txt '/foo /bar/bla",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo /bar/" }
+    }
+  }
+]

+ 35 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_jar.jison

@@ -0,0 +1,35 @@
+// 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.
+
+Auxiliary
+ : AddJar
+ ;
+
+Auxiliary_EDIT
+ : AddJar_EDIT
+ ;
+
+AddJar
+ : 'ADD_JAR' FilePath
+ ;
+
+AddJar_EDIT
+ : 'ADD_JAR' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_JAR' FilePath_EDIT
+ ;

+ 142 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_jar.test.json

@@ -0,0 +1,142 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD JAR /tmp/test;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD JAR \"ivy://group:module:version?exclude=group:module&transitive=true\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD JAR \"/path/to/file/abc.txt\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD JAR '/path/to/file with space/abc.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ADD ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "JAR"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR /boo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/boo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR '",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR '/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR '/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR \"",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR \"/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JAR \"/foo bar/partial",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  }
+]

+ 39 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_jars.jison

@@ -0,0 +1,39 @@
+// 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.
+
+Auxiliary
+ : AddJars
+ ;
+
+Auxiliary_EDIT
+ : AddJars_EDIT
+ ;
+
+AddJars
+ : 'ADD_JARS' FilePaths
+ ;
+
+AddJars_EDIT
+ : 'ADD_JARS' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_JARS' FilePaths 'CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'ADD_JARS' FilePaths_EDIT
+ ;

+ 61 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/add/add_jars.test.json

@@ -0,0 +1,61 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ADD JARS /tmp/test.txt \"/path with space/cde.txt\" '/path with space/fgh.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ADD ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "JARS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JARS /boo/file.txt /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JARS /boo/file1.txt \"/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JARS '/boo/file2.txt' \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "ADD JARS '/boo/file2.txt' /foo.txt '/foo /bar/bla",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo /bar/" }
+    }
+  }
+]

+ 22 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_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.
+
+Auxiliary_EDIT
+ : 'ANALYZE' 'CURSOR'
+   {
+     parser.suggestKeywords(['TABLE', 'TABLES']);
+   }
+ ;

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

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

+ 92 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_table.jison

@@ -0,0 +1,92 @@
+// 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.
+
+Auxiliary
+ : AnalyzeTable
+ ;
+
+Auxiliary_EDIT
+ : AnalyzeTable_EDIT
+ ;
+
+AnalyzeTable
+ : 'ANALYZE' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'COMPUTE' 'STATISTICS' OptionalAnalyzeTableComputeOptions
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+AnalyzeTable_EDIT
+ : 'ANALYZE' 'TABLE' 'CURSOR'
+   {
+     parser.suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+   }
+ | 'ANALYZE' 'TABLE' SchemaQualifiedTableIdentifier_EDIT
+ | 'ANALYZE' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
+   {
+     if (!$4) {
+       parser.suggestKeywords([{ value: 'PARTITION', weight: 2 }, { value: 'COMPUTE STATISTICS', weight: 1 }]);
+     } else {
+       parser.suggestKeywords(['COMPUTE STATISTICS']);
+     }
+   }
+ | 'ANALYZE' 'TABLE' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
+   {
+     parser.addTablePrimary($3);
+   }
+ | 'ANALYZE' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'COMPUTE' 'CURSOR'
+   {
+     parser.suggestKeywords(['STATISTICS']);
+   }
+ | 'ANALYZE' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'COMPUTE' 'STATISTICS' OptionalAnalyzeTableComputeOptions 'CURSOR'
+   {
+     if (!$7) {
+       parser.suggestKeywords(['FOR ALL COLUMNS', 'FOR COLUMNS', 'NOSCAN']);
+     }
+   }
+ | 'ANALYZE' 'TABLE' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'COMPUTE' 'STATISTICS' AnalyzeTableComputeOptions_EDIT
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+OptionalAnalyzeTableComputeOptions
+ :
+ | AnalyzeTableComputeOptions
+ ;
+
+AnalyzeTableComputeOptions
+ : 'FOR' 'ALL' 'COLUMNS'
+ | 'FOR' 'COLUMNS' ColumnList
+ | 'NOSCAN'
+ ;
+
+AnalyzeTableComputeOptions_EDIT
+ : 'FOR' 'CURSOR'
+   {
+     parser.suggestKeywords(['ALL COLUMNS', 'COLUMNS']);
+   }
+ | 'FOR' 'ALL' 'CURSOR'
+   {
+     parser.suggestKeywords(['COLUMNS']);
+   }
+ | 'FOR' 'COLUMNS' 'CURSOR'
+   {
+     parser.suggestColumns();
+   }
+ | 'FOR' 'COLUMNS' ColumnList_EDIT
+ ;

+ 220 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_table.test.json

@@ -0,0 +1,220 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ANALYZE TABLE students COMPUTE STATISTICS NOSCAN;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ANALYZE TABLE students PARTITION (student_id = 111111) COMPUTE STATISTICS;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ANALYZE TABLE students COMPUTE STATISTICS FOR COLUMNS name;;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "ANALYZE TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "ANALYZE TABLE foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLE bar ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "PARTITION",
+        "COMPUTE STATISTICS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ANALYZE TABLE bar PARTITION (",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLE bar PARTITION (a = 1) ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "COMPUTE STATISTICS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLE bar PARTITION (a = 1) COMPUTE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "STATISTICS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLE bar COMPUTE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "STATISTICS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLE bar COMPUTE STATISTICS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "FOR ALL COLUMNS",
+        "FOR COLUMNS",
+        "NOSCAN"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLE bar COMPUTE STATISTICS FOR ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "ALL COLUMNS",
+        "COLUMNS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLE bar COMPUTE STATISTICS FOR ALL ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "COLUMNS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ANALYZE TABLE foo.bar PARTITION (a = 1) COMPUTE STATISTICS FOR COLUMNS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "ANALYZE TABLE foo.bar PARTITION (a = 1) COMPUTE STATISTICS FOR COLUMNS a, b, ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+]

+ 55 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_tables.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.
+
+Auxiliary
+ : AnalyzeTables
+ ;
+
+Auxiliary_EDIT
+ : AnalyzeTables_EDIT
+ ;
+
+AnalyzeTable
+ : 'ANALYZE' 'TABLES' OptionalFromOrInDatabase 'COMPUTE' 'STATISTICS' OptionalNoScan
+ ;
+
+AnalyzeTable_EDIT
+ : 'ANALYZE' 'TABLES' OptionalFromOrInDatabase 'CURSOR'
+   {
+     if (!$3) {
+       parser.suggestKeywords(['FROM', 'IN', 'COMPUTE STATISTICS']);
+     } else {
+       parser.suggestKeywords(['COMPUTE STATISTICS']);
+     }
+   }
+ | 'ANALYZE' 'TABLES' FromOrInDatabase_EDIT
+ | 'ANALYZE' 'TABLES' OptionalFromOrInDatabase 'COMPUTE' 'CURSOR'
+   {
+     parser.suggestKeywords(['STATISTICS']);
+   }
+ | 'ANALYZE' 'TABLES' OptionalFromOrInDatabase 'COMPUTE' 'STATISTICS' OptionalNoScan 'CURSOR'
+   {
+     if (!$6) {
+       parser.suggestKeywords(['NOSCAN']);
+     }
+   }
+ ;
+
+
+OptionalNoScan
+ :
+ | 'NOSCAN'
+ ;

+ 134 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/analyze/analyze_tables.test.json

@@ -0,0 +1,134 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ANALYZE TABLES IN school_db COMPUTE STATISTICS NOSCAN;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "ANALYZE TABLES COMPUTE STATISTICS;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLES ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COMPUTE STATISTICS",
+      "FROM",
+      "IN"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "ANALYZE TABLES FROM ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "ANALYZE TABLES IN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLES FROM foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COMPUTE STATISTICS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLES IN foo ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COMPUTE STATISTICS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLES COMPUTE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "STATISTICS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLES FROM foo COMPUTE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "STATISTICS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLES FROM foo COMPUTE STATISTICS ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "NOSCAN"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "ANALYZE TABLES IN foo COMPUTE STATISTICS ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "NOSCAN"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  }
+]

+ 22 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/cache/cache_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.
+
+Auxiliary_EDIT
+ : 'CACHE' 'CURSOR'
+   {
+     parser.suggestKeywords(['TABLE', 'LAZY TABLE']);
+   }
+ ;

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

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

+ 110 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/cache/cache_table.jison

@@ -0,0 +1,110 @@
+// 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.
+
+Auxiliary
+ : CacheTable
+ ;
+
+Auxiliary_EDIT
+ : CacheTable_EDIT
+ ;
+
+CacheTable
+ : 'CACHE' LazyTableOrTable SchemaQualifiedTableIdentifier OptionalCacheOptions OptionalCacheQuerySpecification
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+CacheTable_EDIT
+ : 'CACHE' LazyTable_EDIT
+ | 'CACHE' LazyTableOrTable 'CURSOR'
+   {
+     parser.suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+   }
+ | 'CACHE' LazyTableOrTable SchemaQualifiedTableIdentifier_EDIT
+ | 'CACHE' LazyTableOrTable SchemaQualifiedTableIdentifier OptionalCacheOptions 'CURSOR' OptionalCacheQuerySpecification
+   {
+     if (!$4 && !$6) {
+       parser.suggestKeywords([{ value: 'OPTIONS', weight: 2 }, { value: 'AS SELECT', weight: 1 }, { value: 'SELECT', weight: 1 }]);
+     } else if (!$4) {
+       parser.suggestKeywords(['OPTIONS']);
+     } else {
+       parser.suggestKeywords(['AS SELECT', 'SELECT']);
+     }
+   }
+ | 'CACHE' LazyTableOrTable SchemaQualifiedTableIdentifier CacheOptions_EDIT OptionalCacheQuerySpecification
+ | 'CACHE' LazyTableOrTable SchemaQualifiedTableIdentifier OptionalCacheOptions CacheQuerySpecification_EDIT
+ ;
+
+LazyTableOrTable
+ : 'LAZY' 'TABLE'
+ | 'TABLE'
+ ;
+
+LazyTable_EDIT
+ : 'LAZY' 'CURSOR'
+   {
+     parser.suggestKeywords(['TABLE']);
+   }
+ ;
+
+OptionalCacheOptions
+ :
+ | CacheOptions
+ ;
+
+CacheOptions
+ : 'OPTIONS' '(' QuotedValue OptionalEquals QuotedValue ')'
+ ;
+
+CacheOptions_EDIT
+ : 'OPTIONS' '(' 'CURSOR' RightParenthesisOrError
+   {
+     parser.suggestKeywords(["'storageLevel'"]);
+   }
+ | 'OPTIONS' '(' QuotedValue OptionalEquals 'CURSOR' RightParenthesisOrError
+   {
+     parser.suggestKeywords(["'NONE'", "'DISK_ONLY'", "'DISK_ONLY_2'", "'DISK_ONLY_3'", "'MEMORY_ONLY'", 
+       "'MEMORY_ONLY_2'", "'MEMORY_ONLY_SER'", "'MEMORY_ONLY_SER_2'", "'MEMORY_AND_DISK'", "'MEMORY_AND_DISK_2'", 
+       "'MEMORY_AND_DISK_SER'", "'MEMORY_AND_DISK_SER_2'", "'OFF_HEAP'"]);
+   }
+ ;
+
+OptionalEquals
+ :
+ | '='
+ ;
+
+OptionalCacheQuerySpecification
+ :
+ | CacheQuerySpecification
+ ;
+
+CacheQuerySpecification
+ : 'AS' QuerySpecification
+ | QuerySpecification
+ ;
+
+CacheQuerySpecification_EDIT
+ : 'AS' 'CURSOR'
+   {
+     parser.suggestKeywords(['SELECT']);
+   }
+ | 'AS' QuerySpecification_EDIT
+ | QuerySpecification_EDIT
+ ;

+ 181 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/cache/cache_table.test.json

@@ -0,0 +1,181 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "CACHE TABLE testCache OPTIONS ('storageLevel' 'DISK_ONLY') SELECT * FROM testData;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "LAZY TABLE",
+      "TABLE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE LAZY ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "TABLE"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "CACHE TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "CACHE LAZY TABLE foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE TABLE foo.bar ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "OPTIONS",
+        "AS SELECT",
+        "SELECT"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE TABLE foo.bar OPTIONS (",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "'storageLevel'"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE TABLE foo.bar OPTIONS ('storageLevel' ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "'MEMORY_AND_DISK_2'"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE TABLE foo.bar OPTIONS ('storageLevel' = ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "'MEMORY_AND_DISK_2'"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE TABLE foo.bar OPTIONS ('storageLevel' = 'MEMORY_AND_DISK_2') ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "AS SELECT",
+        "SELECT"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE TABLE foo.bar OPTIONS ('storageLevel' = 'MEMORY_AND_DISK_2') AS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestKeywords": [
+        "SELECT"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "CACHE TABLE foo.bar OPTIONS ('storageLevel' = 'MEMORY_AND_DISK_2') AS SELECT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "*"
+    ],
+    "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": "CACHE TABLE foo SELECT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "*"
+    ],
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestAggregateFunctions": {
+        "tables": []
+      },
+      "suggestAnalyticFunctions": true,
+      "suggestFunctions": {},
+      "suggestTables": {
+        "prependQuestionMark": true,
+        "prependFrom": true
+      },
+      "suggestDatabases": {
+        "prependQuestionMark": true,
+        "prependFrom": true,
+        "appendDot": true }
+    }
+  }
+]

+ 6 - 8
desktop/core/src/desktop/js/parse/sql/sparksql/jison/common.jison → desktop/core/src/desktop/js/parse/sql/sparksql/jison/clear/clear_cache.jison

@@ -14,12 +14,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-NonReservedKeyword
- : 'CSV'
- | 'JDBC'
- | 'JSON'
- | 'ORC'
- | 'PARQUET'
- | 'TEXTFILE'
- | 'TXT'
+Auxiliary
+ : ClearCache
  ;
+
+ClearCache
+ : 'CLEAR' 'CACHE'
+ ;

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

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

+ 22 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/clear/clear_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.
+
+Auxiliary_EDIT
+ : 'CLEAR' 'CURSOR'
+   {
+     parser.suggestKeywords(['CACHE']);
+   }
+ ;

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

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

+ 48 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_common.jison

@@ -0,0 +1,48 @@
+// 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.
+
+Auxiliary_EDIT
+ : DescribeOrDesc OptionalTable OptionalExtended 'CURSOR'
+   {
+     if (!$2 && !$3) {
+       parser.suggestKeywords(['DATABASE', 'EXTENDED', 'FUNCTION', 'QUERY', 'SELECT', 'WITH', 'TABLE']);
+     } else if ($2 && !$3) {
+       parser.suggestKeywords(['EXTENDED']);
+     }
+   parser.suggestTables();
+   parser.suggestDatabases({ appendDot: true });
+   }
+ ;
+
+DescribeOrDesc
+ : 'DESCRIBE'
+ | 'DESC'
+ ;
+
+OptionalExtended
+ :
+ | 'EXTENDED'
+ ;
+
+OptionalQuery
+ :
+ | 'QUERY'
+ ;
+
+OptionalTable
+ :
+ | 'TABLE'
+ ;

+ 11 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_common.test.json

@@ -0,0 +1,11 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "",
+    "afterCursor": "",
+    "containsKeywords": [
+      "DESC",
+      "DESCRIBE"
+    ]
+  }
+]

+ 41 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_database.jison

@@ -0,0 +1,41 @@
+// 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.
+
+Auxiliary
+ : DescribeDatabase
+ ;
+
+Auxiliary_EDIT
+ : DescribeDatabase_EDIT
+ ;
+
+DescribeDatabase
+ : DescribeOrDesc 'DATABASE' OptionalExtended DatabaseIdentifier
+ ;
+
+DescribeDatabase_EDIT
+ : DescribeOrDesc 'DATABASE' OptionalExtended 'CURSOR'
+   {
+     if (!$3) {
+       parser.suggestKeywords(['EXTENDED']);
+     }
+     parser.suggestDatabases();
+   }
+ | DescribeOrDesc 'DATABASE' OptionalExtended PartialBacktickedIdentifier
+   {
+     parser.suggestDatabases();
+   }
+ ;

+ 46 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_database.test.json

@@ -0,0 +1,46 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "DESCRIBE DATABASE EXTENDED employees;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "DATABASE"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE DATABASE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "EXTENDED"
+      ],
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE DATABASE EXTENDED ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESC DATABASE EXTENDED `",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": { "appendBacktick": true }
+    }
+  }
+]

+ 40 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_function.jison

@@ -0,0 +1,40 @@
+// 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.
+
+Auxiliary
+ : DescribeFunction
+ ;
+
+Auxiliary_EDIT
+ : DescribeFunction_EDIT
+ ;
+
+DescribeFunction
+ : DescribeOrDesc 'FUNCTION' OptionalExtended ColumnOrArbitraryFunctionRef
+ ;
+
+DescribeFunction_EDIT
+ : DescribeOrDesc 'FUNCTION' OptionalExtended 'CURSOR'
+   {
+     if (!$3) {
+       parser.suggestKeywords(['EXTENDED']);
+     }
+     parser.suggestAggregateFunctions();
+     parser.suggestAnalyticFunctions();
+     parser.suggestFunctions();
+     parser.suggestDatabases({ appendDot: true });
+   }
+ ;

+ 70 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_function.test.json

@@ -0,0 +1,70 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "DESC FUNCTION EXTENDED abs;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FUNCTION"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESC ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FUNCTION"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE FUNCTION ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "EXTENDED"
+      ],
+      "suggestAggregateFunctions": {
+        "tables": []
+      },
+      "suggestAnalyticFunctions": true,
+      "suggestFunctions": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest functions",
+    "beforeCursor": "DESCRIBE FUNCTION EXTENDED ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestAggregateFunctions": {
+        "tables": []
+      },
+      "suggestAnalyticFunctions": true,
+      "suggestFunctions": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE DATABASE EXTENDED `",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {
+        "appendBacktick": true
+      }
+    }
+  }
+]

+ 37 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_query.jison

@@ -0,0 +1,37 @@
+// 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.
+
+Auxiliary
+ : DescribeQuery
+ ;
+
+Auxiliary_EDIT
+ : DescribeQuery_EDIT
+ ;
+
+DescribeQuery
+ : DescribeOrDesc QuerySpecification
+ | DescribeOrDesc 'QUERY' QuerySpecification
+ ;
+
+DescribeQuery_EDIT
+ : DescribeOrDesc QuerySpecification_EDIT
+ | DescribeOrDesc 'QUERY' 'CURSOR'
+   {
+     parser.suggestKeywords(['SELECT', 'WITH']);
+   }
+ | DescribeOrDesc 'QUERY' QuerySpecification_EDIT
+ ;

+ 63 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_query.test.json

@@ -0,0 +1,63 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "DESCRIBE QUERY SELECT age, sum(age) FROM person GROUP BY age;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "DESCRIBE QUERY WITH all_names_cte\n    AS (SELECT name from person) SELECT * FROM all_names_cte;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "QUERY",
+      "SELECT",
+      "WITH"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESC QUERY ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "SELECT",
+        "WITH"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE QUERY SELECT ",
+    "afterCursor": "",
+    "containsKeywords": ["*"]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESC SELECT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "*"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESC WITH b AS (SELECT ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "*"
+    ]
+  }
+]

+ 53 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_table.jison

@@ -0,0 +1,53 @@
+// 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.
+
+Auxiliary
+ : DescribeTable
+ ;
+
+Auxiliary_EDIT
+ : DescribeTable_EDIT
+ ;
+
+DescribeTable
+ : DescribeOrDesc OptionalTable OptionalExtended SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalColumnIdentifier
+   {
+     parser.addTablePrimary($4);
+   }
+ ;
+
+DescribeTable_EDIT
+ : DescribeOrDesc OptionalTable OptionalExtended SchemaQualifiedTableIdentifier_EDIT
+ | DescribeOrDesc OptionalTable OptionalExtended SchemaQualifiedTableIdentifier OptionalPartitionSpec OptionalColumnIdentifier 'CURSOR'
+   {
+     parser.addTablePrimary($4);
+     if (!$5 && !$6) {
+       parser.suggestKeywords(['PARTITION']);
+     }
+     if (!$6) {
+       parser.suggestColumns();
+     }
+   }
+ | DescribeOrDesc OptionalTable OptionalExtended SchemaQualifiedTableIdentifier PartitionSpec_EDIT OptionalColumnIdentifier
+   {
+     parser.addTablePrimary($4);
+   }
+ ;
+
+OptionalColumnIdentifier
+ :
+ | ColumnIdentifier
+ ;

+ 137 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/describe/describe_table.test.json

@@ -0,0 +1,137 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "DESC customer;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "DESCRIBE TABLE EXTENDED customer PARTITION (state = 'AR');",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "EXTENDED",
+      "TABLE"
+    ],
+    "expectedResult": {
+      "suggestTables": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "DESCRIBE TABLE EXTENDED ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestTables": {},
+      "suggestDatabases": {
+        "appendDot": true
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "DESC foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "DESC EXTENDED foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "DESCRIBE TABLE foo.bar ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "PARTITION"
+      ],
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "DESCRIBE TABLE foo.bar PARTITION (a=1,",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "DESC TABLE EXTENDED bar PARTITION (a=1,b=2) ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+]

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

@@ -1,6 +1,6 @@
 [
   {
-    "namePrefix": "should handle",
+    "namePrefix": "should not find errors",
     "beforeCursor": "DROP TEMPORARY FUNCTION IF EXISTS baa;",
     "afterCursor": "",
     "containsKeywords": [

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

@@ -1,6 +1,6 @@
 [
   {
-    "namePrefix": "should handle",
+    "namePrefix": "should not find errors",
     "beforeCursor": "DROP TABLE  IF EXISTS db.tbl;",
     "afterCursor": "",
     "containsKeywords": [

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

@@ -1,6 +1,6 @@
 [
   {
-    "namePrefix": "should handle ",
+    "namePrefix": "should not find errors",
     "beforeCursor": "INSERT OVERWRITE DIRECTORY '/blabla/bla' USING parquet OPTIONS (col1 = 1, col2 = 2, col3 = test) SELECT * FROM boo;",
     "afterCursor": "",
     "noErrors": true,
@@ -12,7 +12,7 @@
     }
   },
   {
-    "namePrefix": "should handle ",
+    "namePrefix": "should not find errors",
     "beforeCursor": "INSERT OVERWRITE DIRECTORY\nUSING parquet\nOPTIONS ('path' '/tmp/destination', col1 1, col2 2, col3 'test')\n    SELECT * FROM test_table;",
     "afterCursor": "",
     "noErrors": true,
@@ -24,7 +24,7 @@
     }
   },
   {
-    "namePrefix": "should handle ",
+    "namePrefix": "should not find errors",
     "beforeCursor": "INSERT OVERWRITE LOCAL DIRECTORY '/tmp/destination'\n    ROW FORMAT DELIMITED FIELDS TERMINATED BY ','\n    SELECT * FROM test_table;",
     "afterCursor": "",
     "noErrors": true,
@@ -279,7 +279,9 @@
     "afterCursor": " VALUES (1,2,3);",
     "expectedResult": {
       "lowerCase": false,
-      "suggestKeywords": ["DELIMITED", "SERDE"]
+      "suggestKeywords": [
+        "DELIMITED", "SERDE"
+      ]
     }
   }
 ]

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

@@ -1,6 +1,6 @@
 [
   {
-    "namePrefix": "should handle",
+    "namePrefix": "should not find errors",
     "beforeCursor": "INSERT INTO TABLE db.tbl PARTITION (a=1,b=2) (c,d) VALUES (NULL , 1), ( 2, 3 ); ",
     "afterCursor": "",
     "noErrors": true,
@@ -12,7 +12,7 @@
     }
   },
   {
-    "namePrefix": "should handle",
+    "namePrefix": "should not find errors",
     "beforeCursor": "INSERT INTO TABLE db.tbl PARTITION (a=1,b=2) (c,d) SELECT 1; ",
     "afterCursor": "",
     "noErrors": true,

+ 35 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_archive.jison

@@ -0,0 +1,35 @@
+// 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.
+
+Auxiliary
+ : ListArchive
+ ;
+
+Auxiliary_EDIT
+ : ListArchive_EDIT
+ ;
+
+ListArchive
+ : 'LIST_ARCHIVE' FilePath
+ ;
+
+ListArchive_EDIT
+ : 'LIST_ARCHIVE' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_ARCHIVE' FilePath_EDIT
+ ;

+ 135 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_archive.test.json

@@ -0,0 +1,135 @@
+[
+  {
+    "namePrefix": "should accept statement",
+    "beforeCursor": "LIST ARCHIVE;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST ARCHIVE /tmp/test;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST ARCHIVE \"/path/to/file/abc.txt\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST ARCHIVE '/path/to/file with space/abc.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LIST ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ARCHIVE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE /boo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/boo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE '",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE '/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE '/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE \"",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE \"/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVE \"/foo bar/partial",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  }
+]

+ 39 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_archives.jison

@@ -0,0 +1,39 @@
+// 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.
+
+Auxiliary
+ : ListArchives
+ ;
+
+Auxiliary_EDIT
+ : ListArchives_EDIT
+ ;
+
+ListArchives
+ : 'LIST_ARCHIVES' FilePaths
+ ;
+
+ListArchives_EDIT
+ : 'LIST_ARCHIVES' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_ARCHIVES' FilePaths 'CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_ARCHIVES' FilePaths_EDIT
+ ;

+ 61 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_archives.test.json

@@ -0,0 +1,61 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST ARCHIVES /tmp/test.txt \"/path with space/cde.txt\" '/path with space/fgh.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LIST ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ARCHIVES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVES /boo/file.txt /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVES /boo/file1.txt \"/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVES '/boo/file2.txt' \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST ARCHIVES '/boo/file2.txt' /foo.txt '/foo /bar/bla",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo /bar/" }
+    }
+  }
+]

+ 24 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_common.jison

@@ -0,0 +1,24 @@
+// 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.
+
+Auxiliary_EDIT
+ : 'LIST' 'CURSOR'
+   {
+     parser.suggestKeywords(['ARCHIVE', 'ARCHIVES', 'FILE', 'FILES', 'JAR', 'JARS']);
+   }
+ ;
+
+// Additional in add_common.jison

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

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

+ 36 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_file.jison

@@ -0,0 +1,36 @@
+// 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.
+
+Auxiliary
+ : ListFile
+ ;
+
+Auxiliary_EDIT
+ : ListFile_EDIT
+ ;
+
+ListFile
+ : 'LIST_FILE' FilePath
+ | 'LIST_FILE'
+ ;
+
+ListFile_EDIT
+ : 'LIST_FILE' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_FILE' FilePath_EDIT
+ ;

+ 135 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_file.test.json

@@ -0,0 +1,135 @@
+[
+  {
+    "namePrefix": "should accept statement",
+    "beforeCursor": "LIST FILE;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST FILE /tmp/test;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST FILE \"/path/to/file/abc.txt\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST FILE '/path/to/file with space/abc.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LIST ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FILE"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE /boo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/boo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE '",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE '/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE '/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE \"",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE \"/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILE \"/foo bar/partial",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  }
+]

+ 39 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_files.jison

@@ -0,0 +1,39 @@
+// 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.
+
+Auxiliary
+ : ListFiles
+ ;
+
+Auxiliary_EDIT
+ : ListFiles_EDIT
+ ;
+
+ListFiles
+ : 'LIST_FILES' FilePaths
+ ;
+
+ListFiles_EDIT
+ : 'LIST_FILES' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_FILES' FilePaths 'CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_FILES' FilePaths_EDIT
+ ;

+ 61 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_files.test.json

@@ -0,0 +1,61 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST FILES /tmp/test.txt \"/path with space/cde.txt\" '/path with space/fgh.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LIST ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FILES"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILES /boo/file.txt /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILES /boo/file1.txt \"/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILES '/boo/file2.txt' \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST FILES '/boo/file2.txt' /foo.txt '/foo /bar/bla",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo /bar/" }
+    }
+  }
+]

+ 35 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_jar.jison

@@ -0,0 +1,35 @@
+// 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.
+
+Auxiliary
+ : ListJar
+ ;
+
+Auxiliary_EDIT
+ : ListJar_EDIT
+ ;
+
+ListJar
+ : 'LIST_JAR' FilePath
+ ;
+
+ListJar_EDIT
+ : 'LIST_JAR' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_JAR' FilePath_EDIT
+ ;

+ 147 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_jar.test.json

@@ -0,0 +1,147 @@
+[
+  {
+    "namePrefix": "should accept statement",
+    "beforeCursor": "LIST JAR;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST JAR /tmp/test;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST JAR \"ivy://group:module:version?exclude=group:module&transitive=true\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST JAR \"/path/to/file/abc.txt\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST JAR '/path/to/file with space/abc.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LIST ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "JAR"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR /boo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/boo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR '",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR '/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR '/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR \"",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR \"/foo bar/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JAR \"/foo bar/partial",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo bar/" }
+    }
+  }
+]

+ 39 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_jars.jison

@@ -0,0 +1,39 @@
+// 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.
+
+Auxiliary
+ : ListJars
+ ;
+
+Auxiliary_EDIT
+ : ListJars_EDIT
+ ;
+
+ListJars
+ : 'LIST_JARS' FilePaths
+ ;
+
+ListJars_EDIT
+ : 'LIST_JARS' 'PARTIAL_CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_JARS' FilePaths 'CURSOR'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'LIST_JARS' FilePaths_EDIT
+ ;

+ 61 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/list/list_jars.test.json

@@ -0,0 +1,61 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "LIST JARS /tmp/test.txt \"/path with space/cde.txt\" '/path with space/fgh.txt';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "LIST ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "JARS"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JARS /boo/file.txt /",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JARS /boo/file1.txt \"/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JARS '/boo/file2.txt' \"/foo/",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo/" }
+    }
+  },
+  {
+    "namePrefix": "should suggest files",
+    "beforeCursor": "LIST JARS '/boo/file2.txt' /foo.txt '/foo /bar/bla",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestHdfs": { "path": "/foo /bar/" }
+    }
+  }
+]

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

@@ -1,6 +1,6 @@
 [
   {
-    "namePrefix": "should handle ",
+    "namePrefix": "should not find errors",
     "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,

+ 1508 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/main.jison

@@ -0,0 +1,1508 @@
+// 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.
+
+SqlSyntax
+ : NewStatement SqlStatements EOF
+ ;
+
+SqlAutocomplete
+ : NewStatement SqlStatements EOF
+   {
+     return parser.yy.result;
+   }
+ | NewStatement SqlStatements_EDIT EOF
+   {
+     return parser.yy.result;
+   }
+ ;
+
+NewStatement
+ : /* empty */
+   {
+     parser.prepareNewStatement();
+   }
+ ;
+
+SqlStatements
+ :
+ | SqlStatement
+   {
+     parser.addStatementLocation(@1);
+   }
+ | SqlStatements ';' NewStatement SqlStatements
+ ;
+
+SqlStatements_EDIT
+ : SqlStatement_EDIT
+   {
+     parser.addStatementLocation(@1);
+   }
+ | SqlStatement_EDIT ';' NewStatement SqlStatements
+   {
+     parser.addStatementLocation(@1);
+   }
+ | SqlStatements ';' NewStatement SqlStatement_EDIT
+   {
+     parser.addStatementLocation(@4);
+   }
+ | SqlStatements ';' NewStatement SqlStatement_EDIT ';' NewStatement SqlStatements
+   {
+     parser.addStatementLocation(@4);
+   }
+ ;
+
+SqlStatement
+ : Auxiliary
+ | DataDefinition
+ | DataManipulation
+ | QuerySpecification
+ ;
+
+SqlStatement_EDIT
+ : AnyCursor
+   {
+     parser.suggestDdlAndDmlKeywords();
+   }
+ | CommonTableExpression 'CURSOR'
+   {
+     parser.suggestKeywords(['SELECT']);
+   }
+ | Auxiliary_EDIT
+ | DataDefinition_EDIT
+ | DataManipulation_EDIT
+ | QuerySpecification_EDIT
+ | SetSpecification_EDIT
+ ;
+
+NonReservedKeyword
+ : 'ADD'
+ | 'ALTER'
+ | 'ANALYZE'
+ | 'ARCHIVE'
+ | 'BETWEEN'
+ | 'BIGINT'
+ | 'BINARY'
+ | 'BOOLEAN'
+ | 'BUCKETS'
+ | 'BY'
+ | 'BYTE'
+ | 'CACHE'
+ | 'CASCADE'
+ | 'CHANGE'
+ | 'CHAR'
+ | 'CLEAR'
+ | 'CLUSTERED'
+ | 'COLLECTION'
+ | 'COMMENT'
+ | 'COMPUTE'
+ | 'CREATE'
+ | 'CSV'
+ | 'CURRENT'
+ | 'DATA'
+ | 'DATABASES'
+ | 'DATE'
+ | 'DAY'
+ | 'DBPROPERTIES'
+ | 'DEC'
+ | 'DECIMAL'
+ | 'DEFINED'
+ | 'DELIMITED'
+ | 'DESCRIBE'
+ | 'DIV'
+ | 'DOUBLE'
+ | 'DROP'
+ | 'ESCAPED'
+ | 'EXTERNAL'
+ | 'FIELDS'
+ | 'FILE'
+ | 'FILEFORMAT'
+ | 'FLOAT'
+ | 'FOLLOWING'
+ | 'FOR'
+ | 'FORMAT'
+ | 'FUNCTIONS'
+ | 'GLOBAL'
+ | 'HOUR'
+ | 'INPATH'
+ | 'INSERT'
+ | 'INT'
+ | 'INTEGER'
+ | 'INTERVAL'
+ | 'IS'
+ | 'ITEMS'
+ | 'JAR'
+ | 'JDBC'
+ | 'JSON'
+ | 'KEYS'
+ | 'LAZY'
+ | 'LINES'
+ | 'LIST'
+ | 'LOAD'
+ | 'LOCATION'
+ | 'LONG'
+ | 'MINUTE'
+ | 'MONTH'
+ | 'MSCK'
+ | 'NAMESPACE'
+ | 'NOSCAN'
+ | 'NUMERIC'
+ | 'OPTION'
+ | 'OPTIONS'
+ | 'ORC'
+ | 'PARQUET'
+ | 'PARTITIONED'
+ | 'PARTITIONS'
+ | 'PRECEDING'
+ | 'PROPERTIES'
+ | 'PURGE'
+ | 'RANGE'
+ | 'REAL'
+ | 'RECOVER'
+ | 'REFRESH'
+ | 'RENAME'
+ | 'REPAIR'
+ | 'REPLACE'
+ | 'RESET'
+ | 'RESTRICT'
+ | 'ROLE'
+ | 'ROW'
+ | 'ROWS'
+ | 'SCHEMA'
+ | 'SCHEMAS'
+ | 'SECOND'
+ | 'SERDE'
+ | 'SERDEPROPERTIES'
+ | 'SET'
+ | 'SHORT'
+ | 'SHOW'
+ | 'SMALLINT'
+ | 'SORTED'
+ | 'STATISTICS'
+ | 'STORED'
+ | 'STRING'
+ | 'STRUCT'
+ | 'SYNC'
+ | 'SYSTEM'
+ | 'TABLES'
+ | 'TBLPROPERTIES'
+ | 'TEMPORARY'
+ | 'TERMINATED'
+ | 'TEXTFILE'
+ | 'TIMESTAMP'
+ | 'TINYINT'
+ | 'TO'
+ | 'TXT'
+ | 'UNBOUNDED'
+ | 'UNCACHE'
+ | 'UNSET'
+ | 'UPDATE'
+ | 'USE'
+ | 'USER'
+ | 'USING'
+ | 'VALUES'
+ | 'VARCHAR'
+ | 'VIEW'
+ | 'VIEWS'
+ | 'YEAR'
+ ;
+
+RegularIdentifier
+ : 'REGULAR_IDENTIFIER'
+ | 'VARIABLE_REFERENCE'
+ | NonReservedKeyword
+ ;
+
+// This is a work-around for error handling when a statement starts with some token that the parser can understand but
+// it's not a valid statement (see ErrorStatement). It contains everything except valid starting tokens ('SELECT', 'USE' etc.)
+NonStartingToken
+ : '!'
+ | '('
+ | ')'
+ | '*'
+ | ','
+ | '-'
+ | '.'
+ | '<'
+ | '='
+ | '>'
+ | '['
+ | ']'
+ | '~'
+ | 'ALL'
+ | 'ANALYTIC'
+ | 'AND'
+ | 'ARITHMETIC_OPERATOR'
+ | 'ARRAY'
+ | 'AS'
+ | 'ASC'
+ | 'AVG'
+ | 'BACKTICK'
+ | 'BETWEEN'
+ | 'BIGINT'
+ | 'BOOLEAN'
+ | 'BY'
+ | 'CASE'
+ | 'CAST'
+ | 'CHAR'
+ | 'COMPARISON_OPERATOR'
+ | 'COUNT'
+ | 'CROSS'
+ | 'CURRENT'
+ | 'DATABASE'
+ | 'DECIMAL'
+ | 'DISTINCT'
+ | 'DOUBLE'
+ | 'DOUBLE_QUOTE'
+ | 'ELSE'
+ | 'END'
+ | 'EXISTS'
+ | 'FALSE'
+ | 'FLOAT'
+ | 'FOLLOWING'
+ | 'FROM'
+ | 'FULL'
+ | 'GROUP'
+ | 'HAVING'
+ | 'HDFS_START_QUOTE'
+ | 'IF'
+ | 'IN'
+ | 'INNER'
+ | 'INT'
+ | 'INTO'
+ | 'IS'
+ | 'JOIN'
+ | 'LEFT'
+ | 'LIKE'
+ | 'LIMIT'
+ | 'MAP'
+ | 'MAX'
+ | 'MIN'
+ | 'NOT'
+ | 'NULL'
+ | 'ON'
+ | 'OPTION'
+ | 'OR'
+ | 'ORDER'
+ | 'OUTER'
+ | 'OVER'
+ | 'PARTITION'
+ | 'PRECEDING'
+ | 'PURGE'
+ | 'RANGE'
+ | 'REGEXP'
+ | 'REGULAR_IDENTIFIER'
+ | 'RIGHT'
+ | 'RLIKE'
+ | 'ROLE'
+ | 'ROW'
+ | 'ROWS'
+ | 'SCHEMA'
+ | 'SEMI'
+ | 'SET'
+ | 'SINGLE_QUOTE'
+ | 'SMALLINT'
+ | 'STDDEV_POP'
+ | 'STDDEV_SAMP'
+ | 'STRING'
+ | 'STRUCT'
+ | 'SUM'
+ | 'TABLE'
+ | 'THEN'
+ | 'TIMESTAMP'
+ | 'TINYINT'
+ | 'TRUE'
+ | 'UNION'
+ | 'UNSIGNED_INTEGER'
+ | 'UNSIGNED_INTEGER_E'
+ | 'VALUES'
+ | 'VAR_POP'
+ | 'VAR_SAMP'
+ | 'VARCHAR'
+ | 'VARIABLE_REFERENCE'
+ | 'VARIANCE'
+ | 'WHEN'
+ | 'WHERE'
+ ;
+
+// ===================================== Commonly used constructs =====================================
+
+Commas
+ : ','
+ | Commas ','
+ ;
+
+AnyCursor
+ : 'CURSOR'
+ | 'PARTIAL_CURSOR'
+ ;
+
+FromOrIn
+ : 'FROM'
+ | 'IN'
+ ;
+
+DatabaseOrSchema
+ : 'DATABASE'
+ | 'SCHEMA'
+ ;
+
+SingleQuotedValue
+ : 'SINGLE_QUOTE' 'VALUE' 'SINGLE_QUOTE'  -> $2
+ | 'SINGLE_QUOTE' 'SINGLE_QUOTE'          -> ''
+ ;
+
+SingleQuotedValue_EDIT
+ : 'SINGLE_QUOTE' 'PARTIAL_VALUE'
+ ;
+
+DoubleQuotedValue
+ : 'DOUBLE_QUOTE' 'VALUE' 'DOUBLE_QUOTE'  -> $2
+ | 'DOUBLE_QUOTE' 'DOUBLE_QUOTE'          -> ''
+ ;
+
+DoubleQuotedValue_EDIT
+ : 'DOUBLE_QUOTE' 'PARTIAL_VALUE'
+ ;
+
+QuotedValue
+ : SingleQuotedValue
+ | DoubleQuotedValue
+ ;
+
+QuotedValue_EDIT
+ : SingleQuotedValue_EDIT
+ | DoubleQuotedValue_EDIT
+ ;
+
+OptionalFromOrInDatabase
+ :
+ | FromOrInDatabases
+ ;
+
+FromOrInDatabases
+ : FromOrIn DatabaseIdentifier
+ ;
+
+FromOrInDatabase_EDIT
+ : FromOrIn DatabaseIdentifier_EDIT
+ ;
+
+OptionalCascade
+ :
+ | 'CASCADE'
+ ;
+
+OptionalIfExists
+ :
+ | 'IF' 'EXISTS'
+   {
+     parser.yy.correlatedSubQuery = false;
+   }
+ ;
+
+IfExists_EDIT
+ : OptionalIfExists_EDIT
+ ;
+
+OptionalIfExists_EDIT
+ : 'IF' 'CURSOR'
+   {
+     parser.suggestKeywords(['EXISTS']);
+   }
+ ;
+
+OptionalIfNotExists
+ :
+ | 'IF' 'NOT' 'EXISTS'
+   {
+     parser.yy.correlatedSubQuery = false;
+   }
+ ;
+
+IfNotExists_EDIT
+ : OptionalIfNotExists_EDIT
+ ;
+
+OptionalIfNotExists_EDIT
+ : 'IF' 'CURSOR'
+   {
+     parser.suggestKeywords(['NOT EXISTS']);
+   }
+ | 'IF' 'NOT' 'CURSOR'
+   {
+     parser.suggestKeywords(['EXISTS']);
+   }
+ ;
+
+OptionalInDatabase
+ :
+ | 'IN' DatabaseIdentifier
+ | 'IN' DatabaseIdentifier_EDIT
+ ;
+
+OptionalPartitionSpec
+ :
+ | PartitionSpec
+ ;
+
+OptionalPartitionSpec_EDIT
+ : PartitionSpec_EDIT
+ ;
+
+PartitionSpec
+ : 'PARTITION' '(' PartitionSpecList ')'
+ ;
+
+PartitionSpec_EDIT
+ : 'PARTITION' '(' PartitionSpecList_EDIT RightParenthesisOrError
+ ;
+
+RangePartitionSpec
+ : UnsignedValueSpecification RangePartitionComparisonOperator 'VALUES' RangePartitionComparisonOperator UnsignedValueSpecification
+ ;
+
+RangePartitionSpec_EDIT
+ : UnsignedValueSpecification 'CURSOR'
+   {
+     parser.suggestKeywords(['<', '<=', '<>', '=', '>', '>=']);
+   }
+ | UnsignedValueSpecification RangePartitionComparisonOperator 'CURSOR'
+   {
+     parser.suggestKeywords(['VALUES']);
+   }
+ | UnsignedValueSpecification RangePartitionComparisonOperator 'VALUES' 'CURSOR'
+   {
+     parser.suggestKeywords(['<', '<=', '<>', '=', '>', '>=']);
+   }
+ | UnsignedValueSpecification 'CURSOR' 'VALUES' RangePartitionComparisonOperator UnsignedValueSpecification
+   {
+     parser.suggestKeywords(['<', '<=', '<>', '=', '>', '>=']);
+   }
+ | UnsignedValueSpecification RangePartitionComparisonOperator 'CURSOR' RangePartitionComparisonOperator UnsignedValueSpecification
+   {
+     parser.suggestKeywords(['VALUES']);
+   }
+ | UnsignedValueSpecification RangePartitionComparisonOperator 'VALUES' 'CURSOR' UnsignedValueSpecification
+   {
+     parser.suggestKeywords(['<', '<=', '<>', '=', '>', '>=']);
+   }
+ ;
+
+RangePartitionComparisonOperator
+ : 'COMPARISON_OPERATOR'
+ | '='
+ | '<'
+ | '>'
+ ;
+
+ConfigurationName
+ : RegularIdentifier
+ | 'CURSOR'
+ ;
+
+PartialBacktickedOrAnyCursor
+ : AnyCursor
+ | PartialBacktickedIdentifier
+ ;
+
+PartialBacktickedOrCursor
+ : 'CURSOR'
+ | PartialBacktickedIdentifier
+ ;
+
+PartialBacktickedOrPartialCursor
+ : 'PARTIAL_CURSOR'
+ | PartialBacktickedIdentifier
+ ;
+
+PartialBacktickedIdentifier
+ : 'BACKTICK' 'PARTIAL_VALUE'
+ ;
+
+RightParenthesisOrError
+ : ')'
+ | error
+ ;
+
+OptionalParenthesizedColumnList
+ :
+ | ParenthesizedColumnList
+ ;
+
+OptionalParenthesizedColumnList_EDIT
+ : ParenthesizedColumnList_EDIT
+ ;
+
+ParenthesizedColumnList
+ : '(' ColumnList ')'
+ ;
+
+ParenthesizedColumnList_EDIT
+ : '(' ColumnList_EDIT RightParenthesisOrError
+ | '(' AnyCursor RightParenthesisOrError
+   {
+     parser.suggestColumns();
+   }
+ ;
+
+ColumnList
+ : ColumnIdentifier
+ | ColumnList ',' ColumnIdentifier
+ ;
+
+ColumnList_EDIT
+ : ColumnList ',' AnyCursor
+   {
+     parser.suggestColumns();
+   }
+ | ColumnList ',' AnyCursor ',' ColumnList
+   {
+     parser.suggestColumns();
+   }
+ ;
+
+ParenthesizedSimpleValueList
+ : '(' SimpleValueList ')'
+ ;
+
+SimpleValueList
+ : UnsignedValueSpecification
+ | SimpleValueList ',' UnsignedValueSpecification
+ ;
+
+SchemaQualifiedTableIdentifier
+ : RegularOrBacktickedIdentifier
+   {
+     parser.addTableLocation(@1, [ { name: $1 } ]);
+     $$ = { identifierChain: [ { name: $1 } ] };
+   }
+ | RegularOrBacktickedIdentifier '.' RegularOrBacktickedIdentifier
+   {
+     parser.addDatabaseLocation(@1, [ { name: $1 } ]);
+     parser.addTableLocation(@3, [ { name: $1 }, { name: $3 } ]);
+     $$ = { identifierChain: [ { name: $1 }, { name: $3 } ] };
+   }
+ ;
+
+SchemaQualifiedTableIdentifier_EDIT
+ : PartialBacktickedIdentifier
+   {
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | PartialBacktickedIdentifier '.' RegularOrBacktickedIdentifier
+   {
+     parser.suggestDatabases();
+     $$ = { identifierChain: [{ name: $1 }] };
+   }
+ | RegularOrBacktickedIdentifier '.' PartialBacktickedOrPartialCursor
+   {
+     parser.suggestTablesOrColumns($1);
+   }
+ ;
+
+SchemaQualifiedIdentifier
+ : RegularOrBacktickedIdentifier                                       -> [{ name: $1 }]
+ | RegularOrBacktickedIdentifier '.' RegularOrBacktickedIdentifier  -> [{ name: $1 }, { name: $2 }]
+ ;
+
+SchemaQualifiedIdentifier_EDIT
+ : PartialBacktickedIdentifier
+   {
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | PartialBacktickedIdentifier '.' RegularOrBacktickedIdentifier
+   {
+     parser.suggestDatabases();
+     $$ = { identifierChain: [{ name: $1 }] };
+   }
+ | RegularOrBacktickedIdentifier '.' PartialBacktickedOrPartialCursor
+ ;
+
+DatabaseIdentifier
+ : RegularOrBacktickedIdentifier
+ ;
+
+DatabaseIdentifier_EDIT
+ : PartialBacktickedOrCursor
+   {
+     parser.suggestDatabases();
+   }
+ ;
+
+PartitionSpecList
+ : PartitionExpression
+ | PartitionSpecList ',' PartitionExpression
+ ;
+
+PartitionSpecList_EDIT
+ : PartitionExpression_EDIT
+ | PartitionSpecList ',' PartitionExpression_EDIT
+ | PartitionExpression_EDIT ',' PartitionSpecList
+ | PartitionSpecList ',' PartitionExpression_EDIT ',' PartitionSpecList
+ ;
+
+PartitionExpression
+ : ColumnIdentifier '=' ValueExpression
+ ;
+
+PartitionExpression_EDIT
+ : ColumnIdentifier '=' ValueExpression_EDIT
+ | ColumnIdentifier '=' AnyCursor
+   {
+     parser.valueExpressionSuggest();
+   }
+ | PartialBacktickedIdentifier '=' ValueExpression
+   {
+     parser.suggestColumns();
+   }
+ | AnyCursor
+   {
+     parser.suggestColumns();
+   }
+ ;
+
+RegularOrBacktickedIdentifier
+ : RegularIdentifier
+ | 'BACKTICK' 'VALUE' 'BACKTICK'  -> $2
+ | 'BACKTICK' 'BACKTICK'          -> ''
+ ;
+
+// TODO: Same as SchemaQualifiedTableIdentifier?
+RegularOrBackTickedSchemaQualifiedName
+ : RegularOrBacktickedIdentifier
+   {
+     parser.addTableLocation(@1, [ { name: $1 } ]);
+     $$ = { identifierChain: [ { name: $1 } ] };
+   }
+ | RegularOrBacktickedIdentifier '.' RegularOrBacktickedIdentifier
+   {
+     parser.addDatabaseLocation(@1, [ { name: $1 } ]);
+     parser.addTableLocation(@3, [ { name: $1 }, { name: $3 } ]);
+     $$ = { identifierChain: [ { name: $1 }, { name: $3 } ] };
+   }
+ ;
+
+RegularOrBackTickedSchemaQualifiedName_EDIT
+ : PartialBacktickedIdentifier
+   {
+     parser.suggestTables();
+     parser.suggestDatabases({ prependDot: true });
+   }
+ | RegularOrBacktickedIdentifier '.' PartialBacktickedOrPartialCursor
+   {
+     parser.suggestTablesOrColumns($1);
+   }
+ ;
+
+
+LocalOrSchemaQualifiedName
+ : RegularOrBackTickedSchemaQualifiedName
+ | RegularOrBackTickedSchemaQualifiedName RegularOrBacktickedIdentifier  -> { identifierChain: $1.identifierChain, alias: $2 }
+ ;
+
+LocalOrSchemaQualifiedName_EDIT
+ : RegularOrBackTickedSchemaQualifiedName_EDIT
+ | RegularOrBackTickedSchemaQualifiedName_EDIT RegularOrBacktickedIdentifier
+ ;
+
+ColumnReference
+ : BasicIdentifierChain
+   {
+     parser.yy.locations[parser.yy.locations.length - 1].type = 'column';
+   }
+ | BasicIdentifierChain '.' '*'
+   {
+     parser.addAsteriskLocation(@3, $1.concat({ asterisk: true }));
+   }
+ ;
+
+ColumnReference_EDIT
+ : BasicIdentifierChain_EDIT
+ ;
+
+BasicIdentifierChain
+ : ColumnIdentifier
+   {
+     $$ = [ $1.identifier ];
+     parser.yy.firstChainLocation = parser.addUnknownLocation($1.location, [ $1.identifier ]);
+   }
+ | BasicIdentifierChain '.' ColumnIdentifier
+   {
+     if (parser.yy.firstChainLocation) {
+       parser.yy.firstChainLocation.firstInChain = true;
+       delete parser.yy.firstChainLocation;
+     }
+     $1.push($3.identifier);
+     parser.addUnknownLocation($3.location, $1.concat());
+   }
+ ;
+
+// TODO: Merge with DerivedColumnChain_EDIT ( issue is starting with PartialBacktickedOrPartialCursor)
+BasicIdentifierChain_EDIT
+ : BasicIdentifierChain '.' PartialBacktickedOrPartialCursor
+   {
+     parser.suggestColumns({
+       identifierChain: $1
+     });
+     $$ = { suggestKeywords: [{ value: '*', weight: 10000 }] };
+   }
+ | BasicIdentifierChain '.' PartialBacktickedOrPartialCursor '.' BasicIdentifierChain
+   {
+     parser.suggestColumns({
+       identifierChain: $1
+     });
+     $$ = { suggestKeywords: [{ value: '*', weight: 10000 }] };
+   }
+ ;
+
+DerivedColumnChain
+ : ColumnIdentifier  -> [ $1.identifier ]
+ | DerivedColumnChain '.' ColumnIdentifier
+   {
+     $1.push($3.identifier);
+   }
+ ;
+
+DerivedColumnChain_EDIT
+ : PartialBacktickedIdentifierOrPartialCursor
+   {
+     parser.suggestColumns();
+   }
+ | DerivedColumnChain '.' PartialBacktickedIdentifierOrPartialCursor
+   {
+     parser.suggestColumns({ identifierChain: $1 });
+   }
+ | DerivedColumnChain '.' PartialBacktickedIdentifierOrPartialCursor '.' DerivedColumnChain
+   {
+     parser.suggestColumns({ identifierChain: $1 });
+   }
+ | PartialBacktickedIdentifierOrPartialCursor '.' DerivedColumnChain
+   {
+     parser.suggestColumns();
+   }
+ ;
+
+ColumnIdentifier
+ : RegularOrBacktickedIdentifier                                                                               -> { identifier: { name: $1 }, location: @1 }
+ ;
+
+PartialBacktickedIdentifierOrPartialCursor
+ : PartialBacktickedIdentifier
+ | 'PARTIAL_CURSOR'
+ ;
+
+PrimitiveType
+ : 'BIGINT'
+ | 'BOOLEAN'
+ | 'CHAR' OptionalTypeLength
+ | 'DECIMAL' OptionalTypePrecision
+ | 'DOUBLE'
+ | 'FLOAT'
+ | 'INT'
+ | 'SMALLINT'
+ | 'STRING'
+ | 'TIMESTAMP'
+ | 'TINYINT'
+ | 'VARCHAR' OptionalTypeLength
+ ;
+
+OptionalTypeLength
+ :
+ | '(' 'UNSIGNED_INTEGER' ')'
+ ;
+
+OptionalTypePrecision
+ :
+ | '(' 'UNSIGNED_INTEGER' ')'
+ | '(' 'UNSIGNED_INTEGER' ',' 'UNSIGNED_INTEGER' ')'
+ ;
+
+ValueExpression
+ : NonParenthesizedValueExpressionPrimary
+ ;
+
+ValueExpression_EDIT
+ : NonParenthesizedValueExpressionPrimary_EDIT
+ ;
+
+ValueExpression_EDIT
+ : ValueExpression 'NOT' 'CURSOR'
+   {
+     parser.suggestKeywords(['BETWEEN', 'EXISTS', 'IN', 'LIKE', 'REGEXP', 'RLIKE']);
+     $$ = { types: [ 'BOOLEAN' ] };
+   }
+ ;
+
+ValueExpressionList
+ : ValueExpression
+   {
+     $1.position = 1;
+   }
+ | ValueExpressionList ',' ValueExpression
+   {
+     $3.position = $1.position + 1;
+     $$ = $3;
+   }
+ ;
+
+ValueExpressionList_EDIT
+ : ValueExpression_EDIT
+   {
+     $1.position = 1;
+   }
+ | ValueExpressionList ',' ValueExpression_EDIT
+   {
+     $1.position += 1;
+   }
+ | ValueExpression_EDIT ',' ValueExpressionList
+   {
+     $1.position = 1;
+   }
+ | ValueExpressionList ',' ValueExpression_EDIT ',' ValueExpressionList
+   {
+     $1.position += 1;
+   }
+ | ValueExpressionList ',' AnyCursor
+   {
+     parser.valueExpressionSuggest();
+     $1.position += 1;
+   }
+ | ValueExpressionList ',' AnyCursor ',' ValueExpressionList
+   {
+     parser.valueExpressionSuggest();
+     $1.position += 1;
+   }
+ | ValueExpressionList 'CURSOR' ',' ValueExpressionList
+   {
+     parser.suggestValueExpressionKeywords($1);
+   }
+ | AnyCursor ',' ValueExpressionList
+   {
+     parser.valueExpressionSuggest();
+     $$ = { cursorAtStart : true, position: 1 };
+   }
+ | AnyCursor ','
+   {
+     parser.valueExpressionSuggest();
+     $$ = { cursorAtStart : true, position: 1 };
+   }
+ | ',' AnyCursor
+   {
+     parser.valueExpressionSuggest();
+     $$ = { position: 2 };
+   }
+ | ',' AnyCursor ',' ValueExpressionList
+   {
+     parser.valueExpressionSuggest();
+     $$ = { position: 2 };
+   }
+ ;
+
+InValueList
+ : NonParenthesizedValueExpressionPrimary
+ | InValueList ',' NonParenthesizedValueExpressionPrimary
+ ;
+
+NonParenthesizedValueExpressionPrimary
+ : UnsignedValueSpecification
+ | ColumnOrArbitraryFunctionRef  -> { types: ['COLREF'], columnReference: $1.chain }
+ | 'NULL'                        -> { types: [ 'NULL' ], text: $1 }
+ ;
+
+NonParenthesizedValueExpressionPrimary_EDIT
+ : UnsignedValueSpecification_EDIT
+ | ColumnOrArbitraryFunctionRef_EDIT
+   {
+     if ($1.suggestKeywords) {
+       $$ = { types: ['COLREF'], columnReference: $1, suggestKeywords: $1.suggestKeywords };
+     } else {
+       $$ = { types: ['COLREF'], columnReference: $1 };
+     }
+   }
+ ;
+
+ColumnOrArbitraryFunctionRef
+ : BasicIdentifierChain
+   {
+     var lastLoc = parser.yy.locations[parser.yy.locations.length - 1];
+     if (lastLoc.type !== 'variable') {
+       lastLoc.type = 'column';
+     }
+     // used for function references with db prefix
+     var firstLoc = parser.yy.locations[parser.yy.locations.length - $1.length];
+     $$ = { chain: $1, firstLoc: firstLoc, lastLoc: lastLoc }
+   }
+ | BasicIdentifierChain '.' '*'
+   {
+     parser.addAsteriskLocation(@3, $1.concat({ asterisk: true }));
+   }
+ ;
+
+ColumnOrArbitraryFunctionRef_EDIT
+ : BasicIdentifierChain_EDIT
+ ;
+
+SignedInteger
+ : UnsignedNumericLiteral
+ | '-' UnsignedNumericLiteral
+ | '+' UnsignedNumericLiteral
+ ;
+
+UnsignedValueSpecification
+ : UnsignedLiteral
+ ;
+
+UnsignedValueSpecification_EDIT
+ : UnsignedLiteral_EDIT
+   {
+     parser.suggestValues($1);
+   }
+ ;
+
+UnsignedLiteral
+ : UnsignedNumericLiteral  -> { types: [ 'NUMBER' ], text: $1 }
+ | GeneralLiteral
+ ;
+
+UnsignedLiteral_EDIT
+ : GeneralLiteral_EDIT
+ ;
+
+UnsignedNumericLiteral
+ : ExactNumericLiteral
+ | ApproximateNumericLiteral
+ ;
+
+ExactNumericLiteral
+ : 'UNSIGNED_INTEGER'
+ | 'UNSIGNED_INTEGER' '.'                     -> $1 + $2
+ | 'UNSIGNED_INTEGER' '.' 'UNSIGNED_INTEGER'  -> $1 + $2 + $3
+ | '.' 'UNSIGNED_INTEGER'                     -> $1 + $2
+ ;
+
+ApproximateNumericLiteral
+ : UNSIGNED_INTEGER_E 'UNSIGNED_INTEGER'                        -> $1 + $2
+ | '.' UNSIGNED_INTEGER_E 'UNSIGNED_INTEGER'                    -> $1 + $2 + $3
+ | 'UNSIGNED_INTEGER' '.' UNSIGNED_INTEGER_E 'UNSIGNED_INTEGER' -> $1 + $2 + $3 + $4
+ ;
+
+GeneralLiteral
+ : SingleQuotedValue
+   {
+     if (/\$\{[^}]*\}/.test($1)) {
+       parser.addVariableLocation(@1, $1);
+       $$ = { types: [ 'STRING' ], columnReference: [{ name: $1 }], text: "'" + $1 + "'" }
+     } else {
+       $$ = { types: [ 'STRING' ] }
+     }
+   }
+ | DoubleQuotedValue
+   {
+     if (/\$\{[^}]*\}/.test($1)) {
+       parser.addVariableLocation(@1, $1);
+       $$ = { types: [ 'STRING' ], columnReference: [{ name: $1 }], text: '"' + $1 + '"' }
+     } else {
+       $$ = { types: [ 'STRING' ], text: '"' + $1 + '"' }
+     }
+   }
+ | TruthValue         -> { types: [ 'BOOLEAN' ], text: $1 }
+ ;
+
+GeneralLiteral_EDIT
+ : SingleQuotedValue_EDIT
+  {
+    $$ = { partialQuote: '\'', missingEndQuote: parser.yy.missingEndQuote };
+  }
+ | DoubleQuotedValue_EDIT
+  {
+    $$ = { partialQuote: '"', missingEndQuote: parser.yy.missingEndQuote };
+  }
+ ;
+
+TruthValue
+ : 'TRUE'
+ | 'FALSE'
+ ;
+
+OptionalNot
+ :
+ | 'NOT'
+ ;
+
+TableReference
+ : TablePrimaryOrJoinedTable
+ ;
+
+TableReference_EDIT
+ : TablePrimaryOrJoinedTable_EDIT
+ ;
+
+TablePrimaryOrJoinedTable
+ : TablePrimary
+   {
+     $$ = $1;
+
+     if (parser.yy.latestTablePrimaries.length > 0) {
+       var idx = parser.yy.latestTablePrimaries.length - 1;
+       var tables = [];
+       do {
+         var tablePrimary = parser.yy.latestTablePrimaries[idx];
+         if (!tablePrimary.subQueryAlias) {
+           tables.unshift(tablePrimary.alias ? { identifierChain: tablePrimary.identifierChain, alias: tablePrimary.alias } : { identifierChain: tablePrimary.identifierChain })
+         }
+         idx--;
+       } while (idx >= 0 && tablePrimary.join && !tablePrimary.subQueryAlias)
+
+       if (tables.length > 0) {
+         $$.suggestJoins = {
+           prependJoin: true,
+           tables: tables
+         };
+       }
+      }
+   }
+ | JoinedTable
+ ;
+
+TablePrimaryOrJoinedTable_EDIT
+ : TablePrimary_EDIT
+ | JoinedTable_EDIT
+ ;
+
+JoinedTable
+ : TablePrimary Joins  -> $2
+ ;
+
+JoinedTable_EDIT
+ : TablePrimary Joins_EDIT
+ | TablePrimary_EDIT Joins
+ ;
+
+TablePrimary
+ : TableOrQueryName OptionalCorrelationName
+   {
+     $$ = {
+       primary: $1
+     }
+     if ($1.identifierChain) {
+       if ($2) {
+         $1.alias = $2.alias
+         parser.addTableAliasLocation($2.location, $2.alias, $1.identifierChain);
+       }
+       parser.addTablePrimary($1);
+     }
+
+     var keywords = [];
+     if (!$2) {
+       keywords = ['AS'];
+     } else if ($2.suggestKeywords) {
+       keywords = $2.suggestKeywords;
+     }
+     if (keywords.length > 0) {
+       $$.suggestKeywords = keywords;
+     }
+   }
+ | DerivedTable OptionalCorrelationName
+   {
+     $$ = {
+       primary: $1
+     };
+
+     if ($2) {
+       $$.primary.alias = $2.alias;
+       parser.addTablePrimary({ subQueryAlias: $2.alias });
+       parser.addSubqueryAliasLocation($2.location, $2.alias, $1.identifierChain);
+     }
+
+     var keywords = [];
+     if (!$2) {
+       keywords = ['AS'];
+     }
+     if (keywords.length > 0) {
+       $$.suggestKeywords = keywords;
+     }
+   }
+ ;
+
+TablePrimary_EDIT
+ : TableOrQueryName_EDIT OptionalCorrelationName
+   {
+     if ($2) {
+       parser.addTableAliasLocation($2.location, $2.alias, $1.identifierChain);
+     }
+   }
+ | DerivedTable_EDIT OptionalCorrelationName
+   {
+     if ($2) {
+       parser.addTablePrimary({ subQueryAlias: $2.alias });
+       parser.addSubqueryAliasLocation($2.location, $2.alias);
+     }
+   }
+ | DerivedTable OptionalCorrelationName_EDIT
+ ;
+
+TableOrQueryName
+ : SchemaQualifiedTableIdentifier
+ ;
+
+TableOrQueryName_EDIT
+ : SchemaQualifiedTableIdentifier_EDIT
+ ;
+
+DerivedTable
+ : TableSubQuery
+ ;
+
+DerivedTable_EDIT
+ : TableSubQuery_EDIT
+ ;
+
+OptionalOnColumn
+ :
+ | 'ON' ValueExpression
+ ;
+
+OptionalOnColumn_EDIT
+ : 'ON' 'CURSOR'
+   {
+     parser.valueExpressionSuggest();
+   }
+ | 'ON' ValueExpression_EDIT
+ ;
+
+PushQueryState
+ :
+   {
+     parser.pushQueryState();
+   }
+ ;
+
+PopQueryState
+ :
+   {
+     parser.popQueryState();
+   }
+ ;
+
+TableSubQuery
+ : '(' TableSubQueryInner ')'  -> $2
+ | '(' DerivedTable OptionalCorrelationName ')'
+   {
+     if ($3) {
+       $2.alias = $3.alias;
+       parser.addTablePrimary({ subQueryAlias: $3.alias });
+       parser.addSubqueryAliasLocation($3.location, $3.alias, $2.identifierChain);
+     }
+     $$ = $2;
+   }
+ ;
+
+TableSubQuery_EDIT
+ : '(' TableSubQueryInner_EDIT RightParenthesisOrError
+ | '(' AnyCursor RightParenthesisOrError
+   {
+     parser.suggestKeywords(['SELECT']);
+   }
+ ;
+
+TableSubQueryInner
+ : PushQueryState SubQuery
+   {
+     var subQuery = parser.getSubQuery($2);
+     subQuery.columns.forEach(function (column) {
+       parser.expandIdentifierChain({ wrapper: column });
+       delete column.linked;
+     });
+     parser.popQueryState(subQuery);
+     $$ = subQuery;
+   }
+ ;
+
+TableSubQueryInner_EDIT
+ : PushQueryState SubQuery_EDIT PopQueryState
+ ;
+
+SubQuery
+ : QueryExpression
+ ;
+
+SubQuery_EDIT
+ : QueryExpression_EDIT
+ ;
+
+QueryExpression
+ : QueryExpressionBody
+ ;
+
+QueryExpression_EDIT
+ : QueryExpressionBody_EDIT
+ ;
+
+QueryExpressionBody
+ : NonJoinQueryExpression
+ ;
+
+QueryExpressionBody_EDIT
+ : NonJoinQueryExpression_EDIT
+ ;
+
+NonJoinQueryExpression
+ : NonJoinQueryTerm
+ ;
+
+NonJoinQueryExpression_EDIT
+ : NonJoinQueryTerm_EDIT
+ ;
+
+NonJoinQueryTerm
+ : NonJoinQueryPrimary
+ ;
+
+NonJoinQueryTerm_EDIT
+ : NonJoinQueryPrimary_EDIT
+ ;
+
+NonJoinQueryPrimary
+ : SimpleTable
+ ;
+
+NonJoinQueryPrimary_EDIT
+ : SimpleTable_EDIT
+ ;
+
+SimpleTable
+ : QuerySpecification
+ ;
+
+SimpleTable_EDIT
+ : QuerySpecification_EDIT
+ ;
+
+OptionalCorrelationName
+ :
+ | RegularOrBacktickedIdentifier        -> { alias: $1, location: @1 }
+ | QuotedValue                          -> { alias: $1, location: @1 }
+ | 'AS' RegularOrBacktickedIdentifier  -> { alias: $2, location: @2 }
+ | 'AS' QuotedValue                    -> { alias: $2, location: @2 }
+ ;
+
+OptionalCorrelationName_EDIT
+ : PartialBacktickedIdentifier
+ | QuotedValue_EDIT
+ | 'AS' PartialBacktickedIdentifier
+ | 'AS' QuotedValue_EDIT
+ | 'AS' 'CURSOR'
+ ;
+
+WindowExpression
+ : '(' OptionalPartitionBy OptionalOrderByAndWindow ')'
+ ;
+
+WindowExpression_EDIT
+ : '(' PartitionBy_EDIT OptionalOrderByAndWindow RightParenthesisOrError
+   {
+     if (parser.yy.result.suggestFunctions) {
+       parser.suggestAggregateFunctions();
+     }
+   }
+ | '(' OptionalPartitionBy OptionalOrderByAndWindow_EDIT RightParenthesisOrError
+   {
+     if (parser.yy.result.suggestFunctions) {
+       parser.suggestAggregateFunctions();
+     }
+   }
+ | '(' AnyCursor OptionalPartitionBy OptionalOrderByAndWindow RightParenthesisOrError
+   {
+     if (!$3 && !$4) {
+       parser.suggestKeywords([{ value: 'PARTITION BY', weight: 2 }, { value: 'ORDER BY', weight: 1 }]);
+     } else if (!$3) {
+       parser.suggestKeywords(['PARTITION BY']);
+     }
+   }
+ | '(' 'PARTITION' 'BY' ValueExpressionList 'CURSOR' OptionalOrderByAndWindow RightParenthesisOrError
+    {
+      if (!$6) {
+        parser.suggestValueExpressionKeywords($4, [{ value: 'ORDER BY', weight: 2 }]);
+      } else {
+        parser.suggestValueExpressionKeywords($4);
+      }
+    }
+  ;
+
+OptionalPartitionBy
+ :
+ | PartitionBy
+ ;
+
+PartitionBy
+ : 'PARTITION' 'BY' ValueExpressionList  -> $3
+ ;
+
+PartitionBy_EDIT
+ : 'PARTITION' 'CURSOR'
+   {
+     parser.suggestKeywords(['BY']);
+   }
+ | 'PARTITION' 'BY' 'CURSOR'
+   {
+     parser.valueExpressionSuggest();
+   }
+ | 'PARTITION' 'BY' ValueExpressionList_EDIT
+ ;
+
+OptionalOrderByAndWindow
+ :
+ | OrderByClause OptionalWindowSpec
+ ;
+
+OptionalOrderByAndWindow_EDIT
+  : OrderByClause_EDIT
+    {
+      // Only allowed in last order by
+      delete parser.yy.result.suggestAnalyticFunctions;
+    }
+  | OrderByClause 'CURSOR' OptionalWindowSpec
+    {
+      var keywords = [];
+      if ($1.suggestKeywords) {
+        keywords = parser.createWeightedKeywords($1.suggestKeywords, 2);
+      }
+      if (!$3) {
+        keywords = keywords.concat([{ value: 'RANGE BETWEEN', weight: 1 }, { value: 'ROWS BETWEEN', weight: 1 }]);
+      }
+      parser.suggestKeywords(keywords);
+    }
+  | OrderByClause WindowSpec_EDIT
+  ;
+
+OptionalWindowSpec
+ :
+ | WindowSpec
+ ;
+
+WindowSpec
+ : RowsOrRange 'BETWEEN' PopLexerState OptionalCurrentOrPreceding OptionalAndFollowing
+ | RowsOrRange 'UNBOUNDED' PopLexerState OptionalCurrentOrPreceding OptionalAndFollowing
+ ;
+
+WindowSpec_EDIT
+ : RowsOrRange 'CURSOR'
+   {
+     parser.suggestKeywords(['BETWEEN']);
+   }
+ | RowsOrRange 'BETWEEN' PopLexerState OptionalCurrentOrPreceding OptionalAndFollowing 'CURSOR'
+   {
+     if (!$4 && !$5) {
+       parser.suggestKeywords(['CURRENT ROW', 'UNBOUNDED PRECEDING']);
+     } else if (!$5) {
+       parser.suggestKeywords(['AND']);
+     }
+   }
+ | RowsOrRange 'BETWEEN' PopLexerState OptionalCurrentOrPreceding_EDIT OptionalAndFollowing
+ | RowsOrRange 'BETWEEN' PopLexerState OptionalCurrentOrPreceding OptionalAndFollowing_EDIT
+ | RowsOrRange 'UNBOUNDED' PopLexerState OptionalCurrentOrPreceding 'CURSOR'
+ | RowsOrRange 'UNBOUNDED' PopLexerState OptionalCurrentOrPreceding_EDIT
+ ;
+
+PopLexerState
+ :
+  {
+    lexer.popState();
+  }
+ ;
+
+PushHdfsLexerState
+ :
+  {
+    lexer.begin('hdfs');
+  }
+ ;
+
+HdfsPath
+ : 'HDFS_START_QUOTE' 'HDFS_PATH' 'HDFS_END_QUOTE'
+ ;
+
+HdfsPath_EDIT
+ : 'HDFS_START_QUOTE' 'HDFS_PATH' 'PARTIAL_CURSOR' 'HDFS_PATH' 'HDFS_END_QUOTE'
+    {
+      parser.suggestHdfs({ path: $2 });
+    }
+ | 'HDFS_START_QUOTE' 'HDFS_PATH' 'PARTIAL_CURSOR' 'HDFS_END_QUOTE'
+   {
+     parser.suggestHdfs({ path: $2 });
+   }
+ | 'HDFS_START_QUOTE' 'HDFS_PATH' 'PARTIAL_CURSOR'
+    {
+      parser.suggestHdfs({ path: $2 });
+    }
+ | 'HDFS_START_QUOTE' 'PARTIAL_CURSOR' 'HDFS_END_QUOTE'
+   {
+     parser.suggestHdfs({ path: '' });
+   }
+ | 'HDFS_START_QUOTE' 'PARTIAL_CURSOR'
+    {
+      parser.suggestHdfs({ path: '' });
+    }
+ ;
+
+RowsOrRange
+ : 'ROWS'
+ | 'RANGE'
+ ;
+
+OptionalCurrentOrPreceding
+ :
+ | IntegerOrUnbounded 'PRECEDING'
+ | 'CURRENT' 'ROW'
+ ;
+
+OptionalCurrentOrPreceding_EDIT
+ : IntegerOrUnbounded 'CURSOR'
+   {
+     parser.suggestKeywords(['PRECEDING']);
+   }
+ | 'CURRENT' 'CURSOR'
+   {
+     parser.suggestKeywords(['ROW']);
+   }
+ ;
+
+OptionalAndFollowing
+ :
+ | 'AND' 'CURRENT' 'ROW'
+ | 'AND' IntegerOrUnbounded 'FOLLOWING'
+ ;
+
+OptionalAndFollowing_EDIT
+ : 'AND' 'CURSOR'
+   {
+     parser.suggestKeywords(['CURRENT ROW', 'UNBOUNDED FOLLOWING']);
+   }
+ | 'AND' 'CURRENT' 'CURSOR'
+   {
+     parser.suggestKeywords(['ROW']);
+   }
+ | 'AND' IntegerOrUnbounded 'CURSOR'
+   {
+     parser.suggestKeywords(['FOLLOWING']);
+   }
+ ;
+
+IntegerOrUnbounded
+ : 'UNSIGNED_INTEGER'
+ | 'UNBOUNDED'
+ ;

+ 46 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/main.test.json

@@ -0,0 +1,46 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "[;;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": ";",
+    "afterCursor": ";",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "",
+    "afterCursor": ";;;;",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "foo",
+    "afterCursor": "bar",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": false
+    }
+  }
+]

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

@@ -1,6 +1,6 @@
 [
   {
-    "namePrefix": "should handle",
+    "namePrefix": "should not find errors",
     "beforeCursor": "MSCK REPAIR TABLE db.tbl ADD PARTITIONS;",
     "afterCursor": "",
     "containsKeywords": [

+ 24 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_common.jison

@@ -0,0 +1,24 @@
+// 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.
+
+Auxiliary_EDIT
+ : 'REFRESH' 'CURSOR'
+   {
+     parser.suggestKeywords(['FUNCTION', 'TABLE']);
+     parser.suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+   }
+ ;

+ 10 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_common.test.json

@@ -0,0 +1,10 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "",
+    "afterCursor": "",
+    "containsKeywords": [
+      "REFRESH"
+    ]
+  }
+]

+ 34 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_function.jison

@@ -0,0 +1,34 @@
+// 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.
+
+Auxiliary
+ : RefreshFunction
+ ;
+
+Auxiliary_EDIT
+ : RefreshFunction_EDIT
+ ;
+
+RefreshFunction
+ : 'REFRESH' 'FUNCTION' ColumnOrArbitraryFunctionRef
+ ;
+
+RefreshFunction_EDIT
+ : 'REFRESH' 'FUNCTION' 'CURSOR'
+   {
+     parser.suggestDatabases({ appendDot: true });
+   }
+ ;

+ 37 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_function.test.json

@@ -0,0 +1,37 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "REFRESH FUNCTION func1; ",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "REFRESH FUNCTION `foo db1`.`bar fun1`;`",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "REFRESH ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FUNCTION"
+    ]
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "REFRESH FUNCTION ",
+    "afterCursor": "",
+    "expectedResult": {
+      "lowerCase": false,
+      "suggestDatabases": { "appendDot": true }
+    }
+  }
+]

+ 23 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_resource.jison

@@ -0,0 +1,23 @@
+// 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.
+
+Auxiliary
+ : RefreshResource
+ ;
+
+RefreshResource
+ : 'REFRESH' QuotedValue
+ ;

+ 11 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_resource.test.json

@@ -0,0 +1,11 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "REFRESH \"hdfs://path/to/table\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  }
+]

+ 38 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_table.jison

@@ -0,0 +1,38 @@
+// 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.
+
+Auxiliary
+ : RefreshTable
+ ;
+
+Auxiliary_EDIT
+ : RefreshTable_EDIT
+ ;
+
+RefreshTable
+ : 'REFRESH' SchemaQualifiedTableIdentifier
+ | 'REFRESH' 'TABLE' SchemaQualifiedTableIdentifier
+ ;
+
+RefreshTable_EDIT
+ : 'REFRESH' SchemaQualifiedTableIdentifier_EDIT
+ | 'REFRESH' 'TABLE' 'CURSOR'
+   {
+     parser.suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+   }
+ | 'REFRESH' 'TABLE' SchemaQualifiedTableIdentifier_EDIT
+ ;

+ 45 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/refresh/refresh_table.test.json

@@ -0,0 +1,45 @@
+[
+  {
+    "namePrefix": "should accept statement",
+    "beforeCursor": "REFRESH TABLE tempDB.view1; ",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "REFRESH `foo db1`.`bar fun1`;`",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "REFRESH ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLE"
+    ],
+    "expectedResult": {
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "REFRESH TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {}
+    }
+  }
+]

+ 28 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/reset/reset_config.jison

@@ -0,0 +1,28 @@
+// 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.
+
+Auxiliary
+ : ResetConfig
+ ;
+
+Auxiliary_EDIT
+ : ResetConfig_EDIT
+ ;
+
+ResetConfig
+ : 'RESET'
+ | 'RESET' SetOption
+ ;

+ 28 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/reset/reset_config.test.json

@@ -0,0 +1,28 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "RESET;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "RESET foo.bar.baz;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "",
+    "afterCursor": "",
+    "containsKeywords": [
+      "RESET"
+    ]
+  }
+]

+ 20 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/set/set_common.jison

@@ -0,0 +1,20 @@
+// 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.
+
+SetOption
+ : RegularIdentifier
+ | SetOption '.' RegularIdentifier
+ ;

+ 35 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/set/set_config.jison

@@ -0,0 +1,35 @@
+// 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.
+
+Auxiliary
+ : SetConfig
+ ;
+
+SetConfig
+ : 'SET' SetOption
+ | 'SET' SetOption '=' SetValue
+ | 'SET' '-' RegularIdentifier
+ ;
+
+SetValue
+ : RegularIdentifier
+ | SignedInteger
+ | SignedInteger RegularIdentifier
+ | QuotedValue
+ | 'TRUE'
+ | 'FALSE'
+ | 'NULL'
+ ;

+ 50 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/set/set_config.test.json

@@ -0,0 +1,50 @@
+[
+  {
+    "namePrefix": "should not report errors",
+    "beforeCursor": "set bla.bla=\"ble\";",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "expectedResult": {
+      "lowerCase": true
+    }
+  },
+  {
+    "namePrefix": "should not report errors",
+    "beforeCursor": "SET bla.bla='ble';",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not report errors",
+    "beforeCursor": "SET mem_limit;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not report errors",
+    "beforeCursor": "SET RESERVATION_REQUEST_TIMEOUT=900000;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  },
+  {
+    "namePrefix": "should not report errors",
+    "beforeCursor": "SET -v;",
+    "afterCursor": "",
+    "noErrors": true,
+    "containsKeywords": [
+      "SELECT"
+    ]
+  }
+]

+ 52 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_columns.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.
+
+Auxiliary
+ : ShowColumns
+ ;
+
+Auxiliary_EDIT
+ : ShowColumns_EDIT
+ ;
+
+ShowColumns
+ : 'SHOW' 'COLUMNS' FromOrIn SchemaQualifiedTableIdentifier
+   {
+     parser.addTablePrimary($4);
+   }
+ | 'SHOW' 'COLUMNS' FromOrIn RegularOrBacktickedIdentifier FromOrIn RegularOrBacktickedIdentifier
+ ;
+
+ShowColumns_EDIT
+ : 'SHOW' 'COLUMNS' 'CURSOR'
+   {
+     parser.suggestKeywords(['FROM', 'IN']);
+   }
+ | 'SHOW' 'COLUMNS' FromOrIn 'CURSOR'
+   {
+     parser.suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+   }
+ | 'SHOW' 'COLUMNS' FromOrIn SchemaQualifiedTableIdentifier_EDIT
+ | 'SHOW' 'COLUMNS' FromOrIn RegularOrBacktickedIdentifier 'CURSOR'
+   {
+     parser.suggestKeywords(['FROM', 'IN']);
+   }
+ | 'SHOW' 'COLUMNS' FromOrIn RegularOrBacktickedIdentifier FromOrIn 'CURSOR'
+   {
+     parser.suggestDatabases();
+   }
+ ;

+ 91 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_columns.test.json

@@ -0,0 +1,91 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW COLUMNS IN customer;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW COLUMNS IN salesdb.customer;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW COLUMNS FROM customer IN salesdb;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "COLUMNS FROM",
+      "COLUMNS IN"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW COLUMNS ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "FROM",
+      "IN"
+    ]
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW COLUMNS IN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW COLUMNS FROM ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW COLUMNS FROM foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW COLUMNS FROM foo IN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  }
+]

+ 45 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_common.jison

@@ -0,0 +1,45 @@
+// 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.
+
+Auxiliary_EDIT
+ : 'SHOW' OptionalUserSystemOrAll 'CURSOR'
+   {
+     if (!$2) {
+       parser.suggestKeywords(['ALL FUNCTIONS', 'COLUMNS FROM', 'COLUMNS IN', 'CREATE TABLE', 'DATABASES', 'FUNCTIONS',
+         'PARTITIONS', 'SCHEMAS', 'TABLE EXTENDED', 'TABLES', 'TBLPROPERTIES', 'SYSTEM FUNCTIONS', 'USER FUNCTIONS',
+         'VIEWS']);
+     } else {
+       parser.suggestKeywords(['FUNCTIONS']);
+     }
+   }
+ ;
+
+OptionalUserSystemOrAll
+ :
+ | 'ALL'
+ | 'SYSTEM'
+ | 'USER'
+ ;
+
+
+OptionalLikeRegex
+ :
+ | LikeRegex
+ ;
+
+LikeRegex
+ : 'LIKE' QuotedValue
+ ;

+ 10 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_common.test.json

@@ -0,0 +1,10 @@
+[
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SHOW"
+    ]
+  }
+]

+ 64 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_create_table.jison

@@ -0,0 +1,64 @@
+// 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.
+
+Auxiliary
+ : ShowCreateTable
+ ;
+
+Auxiliary_EDIT
+ : ShowCreateTable_EDIT
+ ;
+
+ShowCreateTable
+ : 'SHOW' 'CREATE' 'TABLE' SchemaQualifiedTableIdentifier OptionalAsSerde
+   {
+     parser.addTablePrimary($4);
+   }
+ ;
+
+ShowCreateTable_EDIT
+ : 'SHOW' 'CREATE' 'CURSOR'
+   {
+     parser.suggestKeywords(['TABLE']);
+   }
+ | 'SHOW' 'CREATE' 'TABLE' 'CURSOR'
+   {
+     parser.suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+   }
+ | 'SHOW' 'CREATE' 'TABLE' SchemaQualifiedTableIdentifier_EDIT
+ | 'SHOW' 'CREATE' 'TABLE' SchemaQualifiedTableIdentifier 'CURSOR'
+   {
+     parser.suggestKeywords(["AS SERDE"]);
+   }
+ | 'SHOW' 'CREATE' 'TABLE' SchemaQualifiedTableIdentifier AsSerde_EDIT
+ ;
+
+OptionalAsSerde
+ :
+ | AsSerde
+ ;
+
+AsSerde
+ : 'AS' 'SERDE'
+ ;
+
+AsSerde_EDIT
+ : 'AS' 'CURSOR'
+   {
+     parser.suggestKeywords(["SERDE"]);
+   }
+ ;

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

@@ -0,0 +1,77 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW CREATE TABLE test;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW CREATE TABLE foo.test AS SERDE;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "CREATE TABLE"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW CREATE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["TABLE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW CREATE TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW CREATE TABLE foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW CREATE TABLE foo ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["AS SERDE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW CREATE TABLE foo AS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["SERDE"]
+    }
+  }
+]

+ 41 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_databases.jison

@@ -0,0 +1,41 @@
+// 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.
+
+Auxiliary
+ : ShowDatabases
+ ;
+
+Auxiliary_EDIT
+ : ShowDatabases_EDIT
+ ;
+
+ShowDatabases
+ : 'SHOW' DatabasesOrSchemas OptionalLikeRegex
+ ;
+
+ShowDatabases_EDIT
+ : 'SHOW' DatabasesOrSchemas OptionalLikeRegex 'CURSOR'
+   {
+     if (!$3) {
+       parser.suggestKeywords(["LIKE"]);
+     }
+   }
+ ;
+
+DatabasesOrSchemas
+ : 'DATABASES'
+ | 'SCHEMAS'
+ ;

+ 45 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_databases.test.json

@@ -0,0 +1,45 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW SCHEMAS;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW DATABASES LIKE 'pay*';",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "DATABASES",
+      "SCHEMAS"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW DATABASES ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["LIKE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW SCHEMAS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["LIKE"]
+    }
+  }
+]

+ 47 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_functions.jison

@@ -0,0 +1,47 @@
+// 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.
+
+Auxiliary
+ : ShowFunctions
+ ;
+
+Auxiliary_EDIT
+ : ShowFunctions_EDIT
+ ;
+
+ShowFunctions
+ : 'SHOW' OptionalUserSystemOrAll 'FUNCTIONS' OptionalFromOrInDatabase OptionalLikeRegex OptionalFunctionName
+ ;
+
+ShowFunctions_EDIT
+ : 'SHOW' OptionalUserSystemOrAll 'FUNCTIONS' OptionalFromOrInDatabase OptionalLikeRegex OptionalFunctionName 'CURSOR'
+   {
+     if (!$6 && !$5 && !$4) {
+       parser.suggestKeywords([{ value: 'FROM', weight: 2 }, { value: 'IN', weight: 2 }, { value: 'LIKE', weight: 1 }]);
+       parser.suggestAggregateFunctions();
+       parser.suggestAnalyticFunctions();
+       parser.suggestFunctions();
+     } else if (!$6 && !$5) {
+       parser.suggestKeywords(["LIKE"]);
+     }
+   }
+ | 'SHOW' OptionalUserSystemOrAll 'FUNCTIONS' FromOrInDatabase_EDIT OptionalLikeRegex OptionalFunctionName
+ ;
+
+OptionalFunctionName
+ :
+ | RegularIdentifier
+ ;

+ 104 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_functions.test.json

@@ -0,0 +1,104 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW SYSTEM FUNCTIONS concat;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW SYSTEM FUNCTIONS FROM salesdb LIKE 'max';",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "ALL FUNCTIONS",
+      "FUNCTIONS",
+      "SYSTEM FUNCTIONS",
+      "USER FUNCTIONS"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ALL ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "FUNCTIONS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW SYSTEM ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "FUNCTIONS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW USER ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "FUNCTIONS"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW USER FUNCTIONS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "FROM",
+        "IN",
+        "LIKE"
+      ],
+      "suggestAggregateFunctions": {
+        "tables": []
+      },
+      "suggestAnalyticFunctions": true,
+      "suggestFunctions": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW FUNCTIONS FROM ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW SYSTEM FUNCTIONS IN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ALL FUNCTIONS IN foo ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "LIKE"
+      ]
+    }
+  }
+]

+ 49 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_partitions.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.
+
+Auxiliary
+ : ShowPartitions
+ ;
+
+Auxiliary_EDIT
+ : ShowPartitions_EDIT
+ ;
+
+ShowPartitions
+ : 'SHOW' 'PARTITIONS' SchemaQualifiedTableIdentifier OptionalPartitionSpec
+   {
+     parser.addTablePrimary($3);
+   }
+ ;
+
+ShowPartitions_EDIT
+ : 'SHOW' 'PARTITIONS' 'CURSOR'
+   {
+     parser.suggestTables();
+     parser.suggestDatabases({ appendDot: true });
+   }
+ | 'SHOW' 'PARTITIONS' SchemaQualifiedTableIdentifier_EDIT
+ | 'SHOW' 'PARTITIONS' SchemaQualifiedTableIdentifier OptionalPartitionSpec 'CURSOR'
+   {
+     if (!$4) {
+       parser.suggestKeywords(['PARTITION']);
+     }
+   }
+ | 'SHOW' 'PARTITIONS' SchemaQualifiedTableIdentifier PartitionSpec_EDIT
+   {
+     parser.addTablePrimary($3);
+   }
+ ;

+ 93 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_partitions.test.json

@@ -0,0 +1,93 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW PARTITIONS customer;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW PARTITIONS salesdb.customer;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW PARTITIONS customer PARTITION (state = 'CA', city = 'Fremont');",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "PARTITIONS"
+    ]
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW PARTITIONS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW PARTITIONS foo.",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW PARTITIONS foo ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": [
+        "PARTITION"
+      ]
+    }
+  },
+  {
+    "namePrefix": "should suggest columns",
+    "beforeCursor": "SHOW PARTITIONS foo.bar PARTITION (",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestColumns": {
+        "tables": [
+          {
+            "identifierChain": [
+              {
+                "name": "foo"
+              },
+              {
+                "name": "bar"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+]

+ 51 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_table_extended.jison

@@ -0,0 +1,51 @@
+// 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.
+
+Auxiliary
+ : ShowTableExtended
+ ;
+
+Auxiliary_EDIT
+ : ShowTableExtended_EDIT
+ ;
+
+ShowTableExtended
+ : 'SHOW' 'TABLE' 'EXTENDED' OptionalFromOrInDatabase LikeRegex OptionalPartitionSpec
+ ;
+
+ShowTableExtended_EDIT
+ : 'SHOW' 'TABLE' 'CURSOR'
+   {
+     parser.suggestKeywords(['EXTENDED']);
+   }
+ | 'SHOW' 'TABLE' 'EXTENDED' OptionalFromOrInDatabase 'CURSOR'
+   {
+     if (!$4) {
+       parser.suggestKeywords([{ value: 'FROM', weight: 2 }, { value: 'IN', weight: 2 }, { value: 'LIKE', weight: 1 }]);
+     } else {
+       parser.suggestKeywords(['LIKE']);
+     }
+   }
+ | 'SHOW' 'TABLE' 'EXTENDED' FromOrInDatabase_EDIT
+ | 'SHOW' 'TABLE' 'EXTENDED' OptionalFromOrInDatabase LikeRegex OptionalPartitionSpec 'CURSOR'
+   {
+     if (!$6) {
+       parser.suggestKeywords(['PARTITION']);
+     }
+   }
+ | 'SHOW' 'TABLE' 'EXTENDED' OptionalFromOrInDatabase LikeRegex PartitionSpec_EDIT
+ | 'SHOW' 'TABLE' 'EXTENDED' FromOrInDatabase_EDIT LikeRegex OptionalPartitionSpec
+ ;

+ 76 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_table_extended.test.json

@@ -0,0 +1,76 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW TABLE EXTENDED LIKE 'employee';",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW TABLE EXTENDED IN default LIKE 'employee' PARTITION (grade=1);",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLE EXTENDED"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW TABLE ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["EXTENDED"]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW TABLE EXTENDED ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["FROM", "IN", "LIKE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW TABLE EXTENDED FROM ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW TABLE EXTENDED IN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW TABLE EXTENDED IN foo ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["LIKE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW TABLE EXTENDED IN `foo bar` LIKE 'abc' ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["PARTITION"]
+    }
+  }
+]

+ 39 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_tables.jison

@@ -0,0 +1,39 @@
+// 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.
+
+Auxiliary
+ : ShowTables
+ ;
+
+Auxiliary_EDIT
+ : ShowTables_EDIT
+ ;
+
+ShowTables
+ : 'SHOW' 'TABLES' OptionalFromOrInDatabase OptionalLikeRegex
+ ;
+
+ShowTables_EDIT
+ : 'SHOW' 'TABLES' OptionalFromOrInDatabase OptionalLikeRegex 'CURSOR'
+   {
+     if (!$4 && !$3) {
+       parser.suggestKeywords([{ value: 'FROM', weight: 2 }, { value: 'IN', weight: 2 }, { value: 'LIKE', weight: 1 }]);
+     } else if (!$4) {
+       parser.suggestKeywords(['LIKE']);
+     }
+   }
+ | 'SHOW' 'TABLES' FromOrInDatabase_EDIT OptionalLikeRegex
+ ;

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

@@ -0,0 +1,77 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW TABLES;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW TABLES IN userdb;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW TABLES FROM default LIKE 'sam*';",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TABLES"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW TABLES ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["FROM", "IN", "LIKE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW TABLES FROM ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW TABLES IN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW TABLES IN foo ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["LIKE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW TABLES FROM `bar foo` ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["LIKE"]
+    }
+  }
+]

+ 46 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_tblproperties.jison

@@ -0,0 +1,46 @@
+// 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.
+
+Auxiliary
+ : ShowTblproperties
+ ;
+
+Auxiliary_EDIT
+ : ShowTblproperties_EDIT
+ ;
+
+ShowTblproperties
+ : 'SHOW' 'TBLPROPERTIES' SchemaQualifiedTableIdentifier OptionalTableProperty
+ ;
+
+ShowTblproperties_EDIT
+ : 'SHOW' 'TBLPROPERTIES' 'CURSOR'
+   {
+     parser.suggestDatabases({ appendDot: true });
+     parser.suggestTables();
+   }
+ | 'SHOW' 'TBLPROPERTIES' SchemaQualifiedTableIdentifier_EDIT OptionalTableProperty
+ ;
+
+OptionalTableProperty
+ :
+ | TableProperty
+ ;
+
+TableProperty
+ : '(' SetOption ')'
+ | '(' QuotedValue ')'
+ ;

+ 62 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_tblproperties.test.json

@@ -0,0 +1,62 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW TBLPROPERTIES bar;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW TBLPROPERTIES bar (created.by.user);",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW TBLPROPERTIES foo.bar ('created.date');",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "TBLPROPERTIES"
+    ]
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW TBLPROPERTIES ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {
+        "appendDot": true
+      },
+      "suggestTables": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest tables",
+    "beforeCursor": "SHOW TBLPROPERTIES `foo`.",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestTables": {
+        "identifierChain": [
+          {
+            "name": "foo"
+          }
+        ]
+      }
+    }
+  }
+]

+ 39 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/show/show_views.jison

@@ -0,0 +1,39 @@
+// 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.
+
+Auxiliary
+ : ShowViews
+ ;
+
+Auxiliary_EDIT
+ : ShowViews_EDIT
+ ;
+
+ShowViews
+ : 'SHOW' 'VIEWS' OptionalFromOrInDatabase OptionalLikeRegex
+ ;
+
+ShowViews_EDIT
+ : 'SHOW' 'VIEWS' OptionalFromOrInDatabase OptionalLikeRegex 'CURSOR'
+   {
+     if (!$4 && !$3) {
+       parser.suggestKeywords([{ value: 'FROM', weight: 2 }, { value: 'IN', weight: 2 }, { value: 'LIKE', weight: 1 }]);
+     } else if (!$4) {
+       parser.suggestKeywords(['LIKE']);
+     }
+   }
+ | 'SHOW' 'VIEWS' FromOrInDatabase_EDIT OptionalLikeRegex
+ ;

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

@@ -0,0 +1,77 @@
+[
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW VIEWS;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW VIEWS IN userdb;",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should not find errors",
+    "beforeCursor": "SHOW VIEWS FROM default LIKE 'sam*';",
+    "afterCursor": "",
+    "containsKeywords": [
+      "SELECT"
+    ],
+    "noErrors": true
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW ",
+    "afterCursor": "",
+    "containsKeywords": [
+      "VIEWS"
+    ]
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW VIEWS ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["FROM", "IN", "LIKE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW VIEWS FROM ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest databases",
+    "beforeCursor": "SHOW VIEWS IN ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestDatabases": {}
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW VIEWS IN foo ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["LIKE"]
+    }
+  },
+  {
+    "namePrefix": "should suggest keywords",
+    "beforeCursor": "SHOW VIEWS FROM `bar foo` ",
+    "afterCursor": "",
+    "expectedResult": {
+      "suggestKeywords": ["LIKE"]
+    }
+  }
+]

+ 100 - 62
desktop/core/src/desktop/js/parse/sql/sparksql/jison/sql.jisonlex

@@ -16,7 +16,7 @@
 
 %options case-insensitive flex
 %s between
-%x hdfs hdfsv2 doubleQuotedValue singleQuotedValue backtickedValue
+%x hdfs sparkfile doubleQuotedValue singleQuotedValue backtickedValue
 %%
 
 \s                                         { /* skip whitespace */ }
@@ -30,50 +30,37 @@
 
 // Reserved Keywords
 'ALL'                                      { return 'ALL'; }
-'ALTER'                                    { parser.determineCase(yytext); parser.addStatementTypeLocation('ALTER', yylloc, yy.lexer.upcomingInput()); return 'ALTER'; }
 'AND'                                      { return 'AND'; }
 'AS'                                       { return 'AS'; }
 'ASC'                                      { return 'ASC'; }
-'BETWEEN'                                  { this.begin('between'); return 'BETWEEN'; }
 'BIGINT'                                   { return 'BIGINT'; }
-'BOOLEAN'                                  { return 'BOOLEAN'; }
 'BY'                                       { return 'BY'; }
-'CASCADE'                                  { return 'CASCADE'; }
 'CASE'                                     { return 'CASE'; }
-'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'; }
-'DECIMAL'                                  { return 'DECIMAL'; }
-'DESC'                                     { return 'DESC'; }
+'DESC'                                     { parser.determineCase(yytext); return 'DESC'; }
+'DIRECTORY'                                { return 'DIRECTORY'; }
 'DISTINCT'                                 { return 'DISTINCT'; }
-'DIV'                                      { return 'ARITHMETIC_OPERATOR'; }
-'DOUBLE'                                   { return 'DOUBLE'; }
-'DROP'                                     { parser.determineCase(yytext); parser.addStatementTypeLocation('DROP', yylloc, yy.lexer.upcomingInput()); return 'DROP'; }
+'EXTENDED'                                 { return 'EXTENDED'; }
+'FUNCTION'                                 { return 'FUNCTION'; }
 'ELSE'                                     { return 'ELSE'; }
 'END'                                      { return 'END'; }
 'EXISTS'                                   { parser.yy.correlatedSubQuery = true; return 'EXISTS'; }
 'FALSE'                                    { return 'FALSE'; }
-'FLOAT'                                    { return 'FLOAT'; }
-'FOLLOWING'                                { return 'FOLLOWING'; }
 'FROM'                                     { parser.determineCase(yytext); return 'FROM'; }
 'FULL'                                     { return 'FULL'; }
 'GROUP'                                    { return 'GROUP'; }
 'HAVING'                                   { return 'HAVING'; }
 'IF'                                       { return 'IF'; }
 'IN'                                       { return 'IN'; }
-'INNER'                                    { return 'INNER'; }
-'INSERT'                                   { parser.determineCase(yytext); return 'INSERT'; }
-'INT'                                      { return 'INT'; }
 'INTO'                                     { return 'INTO'; }
-'IS'                                       { return 'IS'; }
 'JOIN'                                     { return 'JOIN'; }
 'LEFT'                                     { return 'LEFT'; }
 'LIKE'                                     { return 'LIKE'; }
 'LIMIT'                                    { return 'LIMIT'; }
+'LOCAL'                                    { return 'LOCAL'; }
 'NOT'                                      { return 'NOT'; }
 'NULL'                                     { return 'NULL'; }
 'ON'                                       { return 'ON'; }
@@ -82,122 +69,153 @@
 'ORDER'                                    { return 'ORDER'; }
 'OUTER'                                    { return 'OUTER'; }
 'PARTITION'                                { return 'PARTITION'; }
-'PRECEDING'                                { return 'PRECEDING'; }
-'PURGE'                                    { return 'PURGE'; }
-'RANGE'                                    { return 'RANGE'; }
 'REGEXP'                                   { return 'REGEXP'; }
 'RIGHT'                                    { return 'RIGHT'; }
 'RLIKE'                                    { return 'RLIKE'; }
-'ROW'                                      { return 'ROW'; }
 'ROLE'                                     { return 'ROLE'; }
-'ROWS'                                     { return 'ROWS'; }
-'SCHEMA'                                   { return 'SCHEMA'; }
-'SCHEMAS'                                  { return 'SCHEMAS'; }
 'SELECT'                                   { parser.determineCase(yytext); parser.addStatementTypeLocation('SELECT', yylloc); return 'SELECT'; }
 'SEMI'                                     { return 'SEMI'; }
-'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'; }
 'THEN'                                     { return 'THEN'; }
-'TIMESTAMP'                                { return 'TIMESTAMP'; }
-'TINYINT'                                  { return 'TINYINT'; }
-'TO'                                       { return 'TO'; }
 'TRUE'                                     { return 'TRUE'; }
 'TRUNCATE'                                 { parser.determineCase(yytext); parser.addStatementTypeLocation('TRUNCATE', yylloc, yy.lexer.upcomingInput()); return 'TRUNCATE'; }
-'UNBOUNDED'                                { return 'UNBOUNDED'; }
 'UNION'                                    { return 'UNION'; }
-'UPDATE'                                   { parser.determineCase(yytext); return 'UPDATE'; }
-'USE'                                      { parser.determineCase(yytext); parser.addStatementTypeLocation('USE', yylloc); return 'USE'; }
-'VALUES'                                   { return 'VALUES'; }
-'VARCHAR'                                  { return 'VARCHAR'; }
-'VIEW'                                     { return 'VIEW'; }
 'WHEN'                                     { return 'WHEN'; }
 'WHERE'                                    { return 'WHERE'; }
 'WITH'                                     { parser.determineCase(yytext); parser.addStatementTypeLocation('WITH', yylloc); return 'WITH'; }
+'MAP'                                      { return 'MAP'; }
+'OVERWRITE'                                { return 'OVERWRITE'; }
+'QUERY'                                    { return 'QUERY'; }
+'USER'                                     { return 'USER'; }
 
-// Unknown if reserved or not
-'ADD'                                      { return 'ADD'; }
+// Non-reserved Keywords
+'ADD'                                      { parser.determineCase(yytext); return 'ADD'; }
+'ALTER'                                    { parser.determineCase(yytext); parser.addStatementTypeLocation('ALTER', yylloc, yy.lexer.upcomingInput()); return 'ALTER'; }
+'ANALYZE'                                  { parser.determineCase(yytext); return 'ANALYZE'; }
 'ARCHIVE'                                  { return 'ARCHIVE'; }
+'BETWEEN'                                  { this.begin('between'); return 'BETWEEN'; }
 'BINARY'                                   { return 'BINARY'; }
+'BOOLEAN'                                  { return 'BOOLEAN'; }
 'BUCKETS'                                  { return 'BUCKETS'; }
 'BYTE'                                     { return 'BYTE'; }
+'CACHE'                                    { parser.determineCase(yytext); return 'CACHE'; }
+'CASCADE'                                  { return 'CASCADE'; }
 'CHANGE'                                   { return 'CHANGE'; }
+'CHAR'                                     { return 'CHAR'; }
+'CLEAR'                                    { parser.determineCase(yytext); return 'CLEAR'; }
 'CLUSTERED'                                { return 'CLUSTERED'; }
 'COLLECTION'                               { return 'COLLECTION'; }
-'COLUMN'                                   { return 'COLUMN'; }
+'COMMENT'                                  { return 'COMMENT'; }
+'COMPUTE'                                  { return 'COMPUTE'; }
+'CREATE'                                   { parser.determineCase(yytext); return 'CREATE'; }
+'CSV'                                      { return 'CSV'; }
+'CURRENT'                                  { return 'CURRENT'; }
 'DATA'                                     { return 'DATA'; }
+'DATABASES'                                { return 'DATABASES'; }
 'DATE'                                     { return 'DATE'; }
 'DAY'                                      { return 'DAY'; }
 'DBPROPERTIES'                             { return 'DBPROPERTIES'; }
 'DEC'                                      { return 'DEC'; }
+'DECIMAL'                                  { return 'DECIMAL'; }
 'DEFINED'                                  { return 'DEFINED'; }
 'DELIMITED'                                { return 'DELIMITED'; }
-'DIRECTORY'                                { return 'DIRECTORY'; }
+'DESCRIBE'                                 { parser.determineCase(yytext); return 'DESCRIBE'; }
+'DIV'                                      { return 'ARITHMETIC_OPERATOR'; }
+'DOUBLE'                                   { return 'DOUBLE'; }
+'DROP'                                     { parser.determineCase(yytext); parser.addStatementTypeLocation('DROP', yylloc, yy.lexer.upcomingInput()); return 'DROP'; }
 'ESCAPED'                                  { return 'ESCAPED'; }
 'EXTERNAL'                                 { return 'EXTERNAL'; }
 'FIELDS'                                   { return 'FIELDS'; }
 'FILE'                                     { return 'FILE'; }
 'FILEFORMAT'                               { return 'FILEFORMAT'; }
+'FLOAT'                                    { return 'FLOAT'; }
+'FOLLOWING'                                { return 'FOLLOWING'; }
+'FOR'                                      { return 'FOR'; }
 'FORMAT'                                   { return 'FORMAT'; }
-'FUNCTION'                                 { return 'FUNCTION'; }
+'FUNCTIONS'                                { return 'FUNCTIONS'; }
 'GLOBAL'                                   { return 'GLOBAL'; }
 'HOUR'                                     { return 'HOUR'; }
+'INNER'                                    { return 'INNER'; }
 'INPATH'                                   { this.begin('hdfs'); return 'INPATH'; }
+'INSERT'                                   { parser.determineCase(yytext); return 'INSERT'; }
+'INT'                                      { return 'INT'; }
 'INTEGER'                                  { return 'INTEGER'; }
 'INTERVAL'                                 { return 'INTERVAL'; }
+'IS'                                       { return 'IS'; }
 'ITEMS'                                    { return 'ITEMS'; }
 'JAR'                                      { return 'JAR'; }
+'JDBC'                                     { return 'JDBC'; }
+'JSON'                                     { return 'JSON'; }
 'KEYS'                                     { return 'KEYS'; }
+'LAZY'                                     { return 'LAZY'; }
 'LINES'                                    { return 'LINES'; }
+'LIST'                                     { return 'LIST'; }
 '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'; }
+'NOSCAN'                                   { return 'NOSCAN'; }
 'NUMERIC'                                  { return 'NUMERIC'; }
 'OPTIONS'                                  { return 'OPTIONS'; }
-'OVERWRITE'                                { return 'OVERWRITE'; }
+'ORC'                                      { return 'ORC'; }
+'OVER'                                     { return 'OVER'; }
+'PARQUET'                                  { return 'PARQUET'; }
 'PARTITIONED'                              { return 'PARTITIONED'; }
 'PARTITIONS'                               { return 'PARTITIONS'; }
+'PRECEDING'                                { return 'PRECEDING'; }
 'PROPERTIES'                               { return 'PROPERTIES'; }
+'PURGE'                                    { return 'PURGE'; }
+'RANGE'                                    { return 'RANGE'; }
 'REAL'                                     { return 'REAL'; }
 'RECOVER'                                  { return 'RECOVER'; }
+'REFRESH'                                  { parser.determineCase(yytext); return 'REFRESH'; }
 'RENAME'                                   { return 'RENAME'; }
-'REPLACE'                                  { return 'REPLACE'; }
 'REPAIR'                                   { return 'REPAIR'; }
+'REPLACE'                                  { return 'REPLACE'; }
+'RESET'                                    { parser.determineCase(yytext); return 'RESET'; }
 'RESTRICT'                                 { return 'RESTRICT'; }
+'ROLE'                                     { return 'ROLE'; }
+'ROW'                                      { return 'ROW'; }
+'ROWS'                                     { return 'ROWS'; }
+'SCHEMA'                                   { return 'SCHEMA'; }
+'SCHEMAS'                                  { return 'SCHEMAS'; }
 'SECOND'                                   { return 'SECOND'; }
 'SERDE'                                    { return 'SERDE'; }
 'SERDEPROPERTIES'                          { return 'SERDEPROPERTIES'; }
+'SET'                                      { parser.determineCase(yytext); parser.addStatementTypeLocation('SET', yylloc); return 'SET'; }
 'SHORT'                                    { return 'SHORT'; }
+'SHOW'                                     { parser.determineCase(yytext); parser.addStatementTypeLocation('SHOW', yylloc); return 'SHOW'; }
+'SMALLINT'                                 { return 'SMALLINT'; }
 'SORTED'                                   { return 'SORTED'; }
+'STATISTICS'                               { return 'STATISTICS'; }
 'STORED'                                   { return 'STORED'; }
+'STRING'                                   { return 'STRING'; }
 'SYNC'                                     { return 'SYNC'; }
+'SYSTEM'                                   { return 'SYSTEM'; }
+'TABLES'                                   { return 'TABLES'; }
 'TBLPROPERTIES'                            { return 'TBLPROPERTIES'; }
 'TEMPORARY'                                { return 'TEMPORARY'; }
 'TERMINATED'                               { return 'TERMINATED'; }
+'TEXTFILE'                                 { return 'TEXTFILE'; }
+'TIMESTAMP'                                { return 'TIMESTAMP'; }
+'TINYINT'                                  { return 'TINYINT'; }
+'TO'                                       { return 'TO'; }
+'TXT'                                      { return 'TXT'; }
+'UNBOUNDED'                                { return 'UNBOUNDED'; }
+'UNCACHE'                                  { return 'UNCACHE'; }
 'UNSET'                                    { return 'UNSET'; }
+'UPDATE'                                   { parser.determineCase(yytext); return 'UPDATE'; }
+'USE'                                      { parser.determineCase(yytext); parser.addStatementTypeLocation('USE', yylloc); return 'USE'; }
 'USING'                                    { return 'USING'; }
+'VALUES'                                   { return 'VALUES'; }
+'VARCHAR'                                  { return 'VARCHAR'; }
+'VIEW'                                     { return 'VIEW'; }
+'VIEWS'                                    { return 'VIEWS'; }
 'YEAR'                                     { return 'YEAR'; }
 
-// Non-reserved Keywords
-'CSV'                                      { return 'CSV'; }
-'JDBC'                                     { return 'JDBC'; }
-'JSON'                                     { return 'JSON'; }
-'ORC'                                      { return 'ORC'; }
-'OVER'                                     { return 'OVER'; }
-'PARQUET'                                  { return 'PARQUET'; }
-'ROLE'                                     { return 'ROLE'; }
-'TEXTFILE'                                 { return 'TEXTFILE'; }
-'TXT'                                      { return 'TXT'; }
-
 // --- UDFs ---
 AVG\s*\(                                   { yy.lexer.unput('('); yytext = 'avg'; parser.addFunctionLocation(yylloc, yytext); return 'AVG'; }
 CAST\s*\(                                  { yy.lexer.unput('('); yytext = 'cast'; parser.addFunctionLocation(yylloc, yytext); return 'CAST'; }
@@ -234,6 +252,26 @@ DIRECTORY\s+['"]                           { this.begin('hdfs'); return 'DIRECTO
 <hdfs>['"]                                 { this.popState(); return 'HDFS_END_QUOTE'; }
 <hdfs><<EOF>>                              { return 'EOF'; }
 
+ADD\s+ARCHIVE\s+                           { this.begin('sparkfile'); return 'ADD_ARCHIVE'; }
+ADD\s+ARCHIVES\s+                          { this.begin('sparkfile'); return 'ADD_ARCHIVES'; }
+ADD\s+FILE\s+                              { this.begin('sparkfile'); return 'ADD_FILE'; }
+ADD\s+FILES\s+                             { this.begin('sparkfile'); return 'ADD_FILES'; }
+ADD\s+JAR\s+                               { this.begin('sparkfile'); return 'ADD_JAR'; }
+ADD\s+JARS\s+                              { this.begin('sparkfile'); return 'ADD_JARS'; }
+LIST\s+ARCHIVE\s+                          { this.begin('sparkfile'); return 'LIST_ARCHIVE'; }
+LIST\s+ARCHIVES\s+                         { this.begin('sparkfile'); return 'LIST_ARCHIVES'; }
+LIST\s+FILE\s+                             { this.begin('sparkfile'); return 'LIST_FILE'; }
+LIST\s+FILES\s+                            { this.begin('sparkfile'); return 'LIST_FILES'; }
+LIST\s+JAR\s+                              { this.begin('sparkfile'); return 'LIST_JAR'; }
+LIST\s+JARS\s+                             { this.begin('sparkfile'); return 'LIST_JARS'; }
+<sparkfile>'\u2020'                        { parser.yy.cursorFound = true; return 'CURSOR'; }
+<sparkfile>'\u2021'                        { parser.yy.cursorFound = true; return 'PARTIAL_CURSOR'; }
+<sparkfile>[^;\s'"\u2020\u2021]+           { parser.addFileLocation(yylloc, yytext); return 'FILE_PATH'; }
+<sparkfile>[\s]+                           { return 'WHITESPACE'; }
+<sparkfile>['"]                            { return 'FILE_QUOTE'; }
+<sparkfile>';'                             { this.popState(); return ';'; }
+<sparkfile><<EOF>>                         { this.popState(); return 'EOF'; }
+
 '&&'                                       { return 'AND'; }
 '||'                                       { return 'OR'; }
 
@@ -288,7 +326,7 @@ DIRECTORY\s+['"]                           { this.begin('hdfs'); return 'DIRECTO
 <singleQuotedValue>\'                      { this.popState(); return 'SINGLE_QUOTE'; }
 
 \"                                         { this.begin('doubleQuotedValue'); return 'DOUBLE_QUOTE'; }
-<doubleQuotedValue>(?:\\\\|\\["]|[^"])+         {
+<doubleQuotedValue>(?:\\\\|\\["]|[^"])+    {
                                              if (parser.handleQuotedValueWithCursor(this, yytext, yylloc, '"')) {
                                                return 'PARTIAL_VALUE';
                                              }

+ 92 - 4
desktop/core/src/desktop/js/parse/sql/sparksql/jison/structure.json

@@ -2,11 +2,24 @@
   "lexer": "sql.jisonlex",
   "autocomplete": [
     "../../generic/jison/autocomplete_header.jison",
+    "add/add_common.jison",
+    "add/add_archive.jison",
+    "add/add_archives.jison",
+    "add/add_file.jison",
+    "add/add_files.jison",
+    "add/add_jar.jison",
+    "add/add_jars.jison",
     "alter/alter_common.jison",
     "alter/alter_database.jison",
     "alter/alter_table.jison",
     "alter/alter_view.jison",
-    "common.jison",
+    "analyze/analyze_common.jison",
+    "analyze/analyze_table.jison",
+    "analyze/analyze_tables.jison",
+    "cache/cache_common.jison",
+    "cache/cache_table.jison",
+    "clear/clear_common.jison",
+    "clear/clear_cache.jison",
     "../../hive/jison/create/clustered_by.jison",
     "create/create_common.jison",
     "create/create_database.jison",
@@ -14,6 +27,11 @@
     "create/create_table.jison",
     "create/create_view.jison",
     "../../hive/jison/create/row_format.jison",
+    "describe/describe_common.jison",
+    "describe/describe_database.jison",
+    "describe/describe_function.jison",
+    "describe/describe_query.jison",
+    "describe/describe_table.jison",
     "drop/drop_common.jison",
     "../../impala/jison/drop/drop_database.jison",
     "drop/drop_function.jison",
@@ -22,9 +40,21 @@
     "insert/insert_common.jison",
     "insert/insert_overwrite_directory.jison",
     "insert/insert_table.jison",
+    "list/list_common.jison",
+    "list/list_archive.jison",
+    "list/list_archives.jison",
+    "list/list_file.jison",
+    "list/list_files.jison",
+    "list/list_jar.jison",
+    "list/list_jars.jison",
     "load/load_data.jison",
     "msck/msck_common.jison",
     "msck/msck_repair_table.jison",
+    "refresh/refresh_common.jison",
+    "refresh/refresh_function.jison",
+    "refresh/refresh_resource.jison",
+    "refresh/refresh_table.jison",
+    "reset/reset_config.jison",
     "../../generic/jison/select/cte_select_statement.jison",
     "../../generic/jison/select/from_clause.jison",
     "../../generic/jison/select/group_by_clause.jison",
@@ -55,20 +85,47 @@
     "../../generic/jison/udf/function/truncate.jison",
     "../../generic/jison/udf/udf_common.jison",
     "../../generic/jison/sql_error.jison",
-    "../../generic/jison/sql_main.jison",
+    "main.jison",
     "../../generic/jison/sql_valueExpression.jison",
+    "set/set_common.jison",
+    "set/set_config.jison",
+    "show/show_common.jison",
+    "show/show_columns.jison",
+    "show/show_create_table.jison",
+    "show/show_databases.jison",
+    "show/show_functions.jison",
+    "show/show_partitions.jison",
+    "show/show_table_extended.jison",
+    "show/show_tables.jison",
+    "show/show_tblproperties.jison",
+    "show/show_views.jison",
     "truncate/truncate_common.jison",
     "truncate/truncate_table.jison",
+    "uncache/uncache_common.jison",
+    "uncache/uncache_table.jison",
     "../../generic/jison/use/use.jison",
     "../../generic/jison/autocomplete_footer.jison"
   ],
   "syntax": [
     "../../generic/jison/syntax_header.jison",
+    "add/add_common.jison",
+    "add/add_archive.jison",
+    "add/add_archives.jison",
+    "add/add_file.jison",
+    "add/add_files.jison",
+    "add/add_jar.jison",
+    "add/add_jars.jison",
     "alter/alter_common.jison",
     "alter/alter_database.jison",
     "alter/alter_table.jison",
     "alter/alter_view.jison",
-    "common.jison",
+    "analyze/analyze_common.jison",
+    "analyze/analyze_table.jison",
+    "analyze/analyze_tables.jison",
+    "cache/cache_common.jison",
+    "cache/cache_table.jison",
+    "clear/clear_common.jison",
+    "clear/clear_cache.jison",
     "../../hive/jison/create/clustered_by.jison",
     "create/create_common.jison",
     "create/create_database.jison",
@@ -76,6 +133,11 @@
     "create/create_table.jison",
     "create/create_view.jison",
     "../../hive/jison/create/row_format.jison",
+    "describe/describe_common.jison",
+    "describe/describe_database.jison",
+    "describe/describe_function.jison",
+    "describe/describe_query.jison",
+    "describe/describe_table.jison",
     "drop/drop_common.jison",
     "../../impala/jison/drop/drop_database.jison",
     "drop/drop_function.jison",
@@ -84,9 +146,21 @@
     "insert/insert_common.jison",
     "insert/insert_overwrite_directory.jison",
     "insert/insert_table.jison",
+    "list/list_common.jison",
+    "list/list_archive.jison",
+    "list/list_archives.jison",
+    "list/list_file.jison",
+    "list/list_files.jison",
+    "list/list_jar.jison",
+    "list/list_jars.jison",
     "load/load_data.jison",
     "msck/msck_common.jison",
     "msck/msck_repair_table.jison",
+    "refresh/refresh_common.jison",
+    "refresh/refresh_function.jison",
+    "refresh/refresh_resource.jison",
+    "refresh/refresh_table.jison",
+    "reset/reset_config.jison",
     "../../generic/jison/select/cte_select_statement.jison",
     "../../generic/jison/select/from_clause.jison",
     "../../generic/jison/select/group_by_clause.jison",
@@ -116,10 +190,24 @@
     "../../generic/jison/udf/function/map.jison",
     "../../generic/jison/udf/function/truncate.jison",
     "../../generic/jison/udf/udf_common.jison",
-    "../../generic/jison/sql_main.jison",
+    "main.jison",
     "../../generic/jison/sql_valueExpression.jison",
+    "set/set_common.jison",
+    "set/set_config.jison",
+    "show/show_common.jison",
+    "show/show_columns.jison",
+    "show/show_create_table.jison",
+    "show/show_databases.jison",
+    "show/show_functions.jison",
+    "show/show_partitions.jison",
+    "show/show_table_extended.jison",
+    "show/show_tables.jison",
+    "show/show_tblproperties.jison",
+    "show/show_views.jison",
     "truncate/truncate_common.jison",
     "truncate/truncate_table.jison",
+    "uncache/uncache_common.jison",
+    "uncache/uncache_table.jison",
     "../../generic/jison/use/use.jison",
     "../../generic/jison/syntax_footer.jison"
   ]

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

@@ -1,6 +1,6 @@
 [
   {
-    "namePrefix": "should handle",
+    "namePrefix": "should not find errors",
     "beforeCursor": "TRUNCATE TABLE table_identifier PARTITION (a = 1, b = 2);",
     "afterCursor": "",
     "containsKeywords": [

+ 22 - 0
desktop/core/src/desktop/js/parse/sql/sparksql/jison/uncache/uncache_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.
+
+Auxiliary_EDIT
+ : 'UNCACHE' 'CURSOR'
+   {
+     parser.suggestKeywords(['TABLE']);
+   }
+ ;

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно