Repository: DerekStride/tree-sitter-sql (language: python)

Issue:
Insert overwrite with and without partition aren't parsed properly
Hi, the following queries aren't parsed properly. Please have a look.
[sparksql syntax reference](https://spark.apache.org/docs/3.0.0/sql-ref-syntax-dml-insert-overwrite-table.html)
```
insert overwrite data_base_name.tb_name_01 
partition ( key1 = '20230522' ,key2 = 'bb')
SELECT *
  FROM 
data_base_name.tb_name_00
;

insert overwrite data_base_name.tb_name_02
SELECT
  a1.col_a,
  a1.col_b
FROM 
(
  SELECT
    *
  FROM
    data_base_name.tb_name_01 
  WHERE
    key1 >= 'bb'
) a1
```
two queries:
![image](https://github.com/DerekStride/tree-sitter-sql/assets/22954918/cd2c20dc-53b5-498f-ac48-0865e83f62b3)

just the second query
![image](https://github.com/DerekStride/tree-sitter-sql/assets/22954918/3d647371-c862-4473-82d8-2d664c968c09)



Discussion / hints:

Fix patch:
diff --git a/grammar.js b/grammar.js
index 02384b8c..508c7457 100644
--- a/grammar.js
+++ b/grammar.js
@@ -44,6 +44,7 @@ module.exports = grammar({
     keyword_replace: _ => make_keyword("replace"),
     keyword_update: _ => make_keyword("update"),
     keyword_into: _ => make_keyword("into"),
+    keyword_overwrite: _ => make_keyword("overwrite"),
     keyword_values: _ => make_keyword("values"),
     keyword_set: _ => make_keyword("set"),
     keyword_from: _ => make_keyword("from"),
@@ -1270,8 +1271,14 @@ module.exports = grammar({
         ),
       ),
       optional($.keyword_ignore),
-      optional($.keyword_into),
+      optional(
+        choice(
+          $.keyword_into,
+          $.keyword_overwrite, // Spark SQL
+        ),
+      ),
       $.table_reference,
+      optional($.table_partition), // Spark SQL
       optional(
         seq(
           $.keyword_as,
@@ -1418,26 +1425,35 @@ module.exports = grammar({
     ),
 
     table_partition: $ => seq(
-        choice(
-            // Postgres/MySQL style
-            seq(
-                $.keyword_partition,
-                $.keyword_by,
-                choice(
-                    $.keyword_range,
-                    $.keyword_hash,
-                )
-            ),
-            // Hive style
-            seq(
-                $.keyword_partitioned,
-                $.keyword_by,
-            ),
+      choice(
+        // Postgres/MySQL style
+        seq(
+          $.keyword_partition,
+          $.keyword_by,
+          choice(
+            $.keyword_range,
+            $.keyword_hash,
+          )
         ),
-        choice(
-            seq('(', $.identifier, ')'), // postgres
-            $.column_definitions // impala/hive
-        )
+        // Hive style
+        seq(
+          $.keyword_partitioned,
+          $.keyword_by,
+        ),
+        // Spark SQL
+        $.keyword_partition,
+      ),
+      choice(
+        seq('(', $.identifier, ')'), // postgres
+        $.column_definitions, // impala/hive
+        seq('(', $._key_value_pair, repeat(seq(',', $._key_value_pair)), ')',), // Spark SQL
+      )
+    ),
+
+    _key_value_pair: $ => seq(
+      field('key',$.identifier),
+      '=',
+      field('value', alias($._literal_string, $.literal)),
     ),
 
     stored_as: $ => seq(


Test patch:
diff --git a/test/corpus/insert.txt b/test/corpus/insert.txt
index f8abbeee..532245d1 100644
--- a/test/corpus/insert.txt
+++ b/test/corpus/insert.txt
@@ -404,3 +404,124 @@ VALUES('foo','bar', 3);
         (literal)
         (literal)
         (literal)))))
+
+================================================================================
+Insert overwrite
+================================================================================
+
+INSERT OVERWRITE tab1
+SELECT
+  col1,
+  col2
+FROM
+(
+  SELECT
+    *
+  FROM
+    tab2
+  WHERE
+    key1 >= 'val'
+) a1;
+
+--------------------------------------------------------------------------------
+
+(program
+  (statement
+    (insert
+      (keyword_insert)
+      (keyword_overwrite)
+      (table_reference
+        (identifier))
+      (select
+        (keyword_select)
+        (select_expression
+          (term
+            (field
+              (identifier)))
+          (term
+            (field
+              (identifier)))))
+      (from
+        (keyword_from)
+        (relation
+          (subquery
+            (select
+              (keyword_select)
+              (select_expression
+                (all_fields)))
+            (from
+              (keyword_from)
+              (relation
+                (table_reference
+                  (identifier)))
+              (where
+                (keyword_where)
+                (binary_expression
+                  (field
+                    (identifier))
+                  (literal)))))
+          (identifier))))))
+
+================================================================================
+Insert overwrite with partition
+================================================================================
+
+INSERT OVERWRITE tab1
+PARTITION (key1 = 'val1', key2 = 'val2')
+SELECT
+  col1,
+  col2
+FROM
+(
+  SELECT
+    *
+  FROM
+    tab2
+  WHERE
+    key1 >= 'val'
+) a1;
+
+--------------------------------------------------------------------------------
+
+(program
+  (statement
+    (insert
+      (keyword_insert)
+      (keyword_overwrite)
+      (table_reference
+        (identifier))
+      (table_partition
+        (keyword_partition)
+        (identifier)
+        (literal)
+        (identifier)
+        (literal))
+      (select
+        (keyword_select)
+        (select_expression
+          (term
+            (field
+              (identifier)))
+          (term
+            (field
+              (identifier)))))
+      (from
+        (keyword_from)
+        (relation
+          (subquery
+            (select
+              (keyword_select)
+              (select_expression
+                (all_fields)))
+            (from
+              (keyword_from)
+              (relation
+                (table_reference
+                  (identifier)))
+              (where
+                (keyword_where)
+                (binary_expression
+                  (field
+                    (identifier))
+                  (literal)))))
+          (identifier))))))