SQLite -> Operator

In SQLite, the -> operator extracts a subcomponent from a JSON document and returns a JSON representation of that subcomponent.

The -> operator was first introduced in SQLite version 3.38.0 (released on 22 February 2022).

Syntax

The syntax goes like this:

json -> path

Where json is the JSON document and path is the path to the subcomponent that we want to extract from it.

So we provide a JSON document to the left of the operator, and we specify the path we want to extract to its right.

The -> operator always returns a JSON representation of the specified subcomponent. To return a SQL representation, use the ->> operator instead.

Examples

Here’s a simple example to demonstrate how the -> operator works:

SELECT '{ "name" : "Wag", "type" : "Dog" }' -> '$';

Result:

{"name":"Wag","type":"Dog"}

In this case, I specified a path of '$' which returns the whole document.

Let’s specify another path:

SELECT '{ "name" : "Wag", "type" : "Dog" }' -> '$.type';

Result:

"Dog"

We can also omit the dollar sign and full stop altogether, like this:

SELECT '{ "name" : "Wag", "type" : "Dog" }' -> 'type';

Result:

"Dog"

Here it is with a larger JSON document:

SELECT '[
        { 
        "user" : "Spike",
        "age" : 30,
        "scores" : [ 9, 7, 3 ]
        },
        { 
        "user" : "Faye",
        "age" : 25,
        "scores" : [ 90, 87, 93 ]
        },
        { 
        "user" : "Jet",
        "age" : 40,
        "scores" : [ 50, 38, 67 ]
        }
        ]' -> '$[2]';

Result:

{"user":"Jet","age":40,"scores":[50,38,67]}

In SQLite, arrays are zero based, and so specifying [2] returns the third array element.

If we only wanted to get that user’s scores, we could do this:

SELECT '[
        { 
        "user" : "Spike",
        "age" : 30,
        "scores" : [ 9, 7, 3 ]
        },
        { 
        "user" : "Faye",
        "age" : 25,
        "scores" : [ 90, 87, 93 ]
        },
        { 
        "user" : "Jet",
        "age" : 40,
        "scores" : [ 50, 38, 67 ]
        }
        ]' -> '$[2].scores';

Result:

[50,38,67]

We can go even deeper and extract a specific score:

SELECT '[
        { 
        "user" : "Spike",
        "age" : 30,
        "scores" : [ 9, 7, 3 ]
        },
        { 
        "user" : "Faye",
        "age" : 25,
        "scores" : [ 90, 87, 93 ]
        },
        { 
        "user" : "Jet",
        "age" : 40,
        "scores" : [ 50, 38, 67 ]
        }
        ]' -> '$[2].scores[1]';

Result:

38

Non-Existent Path

If the path doesn’t exist in the JSON, a null value is returned:

SELECT '{ "name" : "Wag", "type" : "Dog" }' -> '$.age';

Result:

null

Note that In SQLite, you can use .nullvalue to specify a string to output whenever a null value is returned. In my case, I had previously run the following command:

.nullvalue null

That specifies that the text null should be output whenever a null value is returned. That is why the above example output the text null. If I hadn’t done this, the result might have been blank.

Invalid JSON

If the first argument is not valid JSON, an error is thrown:

SELECT '{ "name" }' -> '$';

Result:

Runtime error: malformed JSON

Invalid Path

And if the second argument is not a valid path, an error is thrown:

SELECT '{ "name" : "Wag", "type" : "Dog" }' -> '$name';

Result:

Runtime error: JSON path error near 'name'

In this case, I forgot to include the full stop (.) between the dollar sign ($) and name.

However as mentioned, it is possible to omit the dollar sign and full stop altogether:

SELECT '{ "name" : "Wag", "type" : "Dog" }' -> 'name';

Result:

"Wag"