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

Issue:
Parsing PostgreSQL JSON operators
I've noticed [PostgreSQL JSON operators](https://www.postgresql.org/docs/9.3/functions-json.html) are not parsed correctly.

For example, the following query has parsing errors:

```sql
SELECT "user"->>'login' AS username FROM users;
```

Parsed AST:

```
(program
  (statement
    (select
      (keyword_select)
      (select_expression
        (term
          (binary_expression
            (literal)
            (ERROR)
            (literal))
          (keyword_as)
          (identifier))))
    (from
      (keyword_from)
      (relation
        (object_reference
          (identifier))))))
```
alternative implementation using binary_expression
Alternative to #170 that uses the `binary_expression` node.

```
➜ tree-sitter-sql tree-sitter parse tmp/json.sql
(program [0, 0] - [7, 0]
  (statement [0, 0] - [6, 10]
    (select [0, 0] - [5, 35]
      (keyword_select [0, 0] - [0, 6])
      (select_expression [1, 4] - [5, 35]
        (term [1, 4] - [1, 29]
          value: (binary_expression [1, 4] - [1, 20]
            left: (literal [1, 4] - [1, 10])
            right: (literal [1, 13] - [1, 20]))
          (keyword_as [1, 21] - [1, 23])
          alias: (identifier [1, 24] - [1, 29]))
        (term [2, 4] - [2, 32]
          value: (binary_expression [2, 4] - [2, 32]
            left: (binary_expression [2, 4] - [2, 21]
              left: (literal [2, 4] - [2, 10])
              right: (literal [2, 12] - [2, 21]))
            right: (literal [2, 26] - [2, 32])))
        (term [3, 4] - [3, 46]
          value: (binary_expression [3, 4] - [3, 33]
            left: (binary_expression [3, 4] - [3, 21]
              left: (literal [3, 4] - [3, 10])
              right: (literal [3, 12] - [3, 21]))
            right: (literal [3, 26] - [3, 33]))
          (keyword_as [3, 34] - [3, 36])
          alias: (identifier [3, 37] - [3, 46]))
        (term [4, 4] - [4, 21]
          value: (binary_expression [4, 4] - [4, 21]
            left: (literal [4, 4] - [4, 10])
            right: (literal [4, 14] - [4, 21])))
        (term [5, 4] - [5, 35]
          value: (binary_expression [5, 4] - [5, 27]
            left: (literal [5, 4] - [5, 10])
            right: (literal [5, 15] - [5, 27]))
          (keyword_as [5, 28] - [5, 30])
          alias: (identifier [5, 31] - [5, 35]))))
    (from [6, 0] - [6, 10]
      (keyword_from [6, 0] - [6, 4])
      (relation [6, 5] - [6, 10]
        (object_reference [6, 5] - [6, 10]
          name: (identifier [6, 5] - [6, 10]))))))
```


Discussion / hints:
JSON ist not implemented yet. Thanks for reporting. This will probably be a bigger undertaking.


Fix patch:
diff --git a/grammar.js b/grammar.js
index 617a6a64..1204acd4 100644
--- a/grammar.js
+++ b/grammar.js
@@ -2338,6 +2338,10 @@ module.exports = grammar({
         ['>=', 'binary_relation'],
         ['>', 'binary_relation'],
         ['<>', 'binary_relation'],
+        ['->', 'binary_relation'],
+        ['->>', 'binary_relation'],
+        ['#>', 'binary_relation'],
+        ['#>>', 'binary_relation'],
         [$.keyword_is, 'binary_is'],
         [$.is_not, 'binary_is'],
         [$.keyword_like, 'pattern_matching'],
diff --git a/queries/highlights.scm b/queries/highlights.scm
index 6b324ff3..2b58af60 100644
--- a/queries/highlights.scm
+++ b/queries/highlights.scm
@@ -298,6 +298,10 @@
   ">="
   ">"
   "<>"
+  "->"
+  "->>"
+  "#>"
+  "#>>"
 ] @operator
 
 [


Test patch:
diff --git a/test/corpus/json.txt b/test/corpus/json.txt
new file mode 100644
index 00000000..522b2cf7
--- /dev/null
+++ b/test/corpus/json.txt
@@ -0,0 +1,54 @@
+================================================================================
+JSON traversal
+================================================================================
+
+SELECT
+    "user"->>'login' as login,
+    "user"->'address' ->> 'city',
+    "user"->'address' ->> 'state' as userstate,
+    "user" #> 'items',
+    "user" #>> 'more_items' AS more
+FROM users;
+
+--------------------------------------------------------------------------------
+
+(program
+  (statement
+    (select
+      (keyword_select)
+      (select_expression
+        (term
+          value: (binary_expression
+            left: (literal)
+            right: (literal))
+          (keyword_as)
+          alias: (identifier))
+        (term
+          value: (binary_expression
+            left: (binary_expression
+              left: (literal)
+              right: (literal))
+            right: (literal)))
+        (term
+          value: (binary_expression
+            left: (binary_expression
+              left: (literal)
+              right: (literal))
+            right: (literal))
+          (keyword_as)
+          alias: (identifier))
+        (term
+          value: (binary_expression
+            left: (literal)
+            right: (literal)))
+        (term
+          value: (binary_expression
+            left: (literal)
+            right: (literal))
+          (keyword_as)
+          alias: (identifier))))
+    (from
+      (keyword_from)
+      (relation
+        (object_reference
+          name: (identifier))))))