JSON Functions and Operators

json

JSON scalar type

json[i]

JSON array/string indexing.

json[from:to]

JSON array/string slicing.

json ++ json

JSON concatenation.

json[name]

JSON object property access.

= != ?= ?!= < > <= >=

Comparison operators

to_json()

Return JSON value represented by the input string.

to_str()

Render JSON value to a string.

json_get()

Return the JSON value at the end of the specified path or an empty set.

json_set()

Return an updated JSON target with a new value.

json_array_unpack()

Return elements of JSON array as a set of json.

json_object_unpack()

Return set of key/value tuples that make up the JSON object.

json_typeof()

Return the type of the outermost JSON value as a string.

Constructing JSON Values

JSON in EdgeDB is one of the scalar types. This scalar doesn’t have its own literal and instead can be obtained by casting a value into json or by using to_json():

  1. db>
  1. select to_json('{"hello": "world"}');
  1. {'{"hello": "world"}'}
  1. db>
  1. select <json>'hello world';
  1. {'"hello world"'}

Anything in EdgeDB can be cast into json:

  1. db>
  1. select <json>2019;
  1. {'2019'}
  1. db>
  1. select <json>cal::to_local_date(datetime_current(), 'UTC');
  1. {'"2019-04-02"'}

Any Object can be cast into json. This produces the same JSON value as the JSON serialization of that object. That is, the result is the same as the output of select expression in JSON mode, including the type shape.

  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  6. ...
  7. ...
  1. select <json>(
  2. select schema::Object {
  3. name,
  4. timestamp := cal::to_local_date(
  5. datetime_current(), 'UTC')
  6. }
  7. filter .name = 'std::bool');
  1. {'{"name": "std::bool", "timestamp": "2019-04-02"}'}

JSON values can also be cast back into scalars. This casting is symmetrical meaning that if a scalar can be cast into JSON, only that particular JSON type can be cast back into that scalar:

  • JSON string can be cast into str. Casting uuid and date and time types to JSON results in a JSON string representing the original value. This means that it is also possible to cast a JSON string back into these types. The string value has to be properly formatted (much like in case of a str value being cast) or else the cast will raise an exception.

  • JSON number can be cast into any of the numeric types

  • JSON boolean can be cast into bool

  • JSON null is special since it can be cast into an {} of any type

  • JSON array can be cast into any valid EdgeDB array, so it must be homogeneous, and must not contain null

A regular tuple is converted into a JSON array when cast into json, whereas a named tuple is converted into a JSON object. These casts are not reversible, i.e. it is not possible to cast a JSON value directly into a tuple.

type

json

JSON - 图1

JSON - 图2

JSON - 图3

json

Arbitrary JSON data.

Any other type can be cast to and from JSON:

  1. db>
  1. select <json>42;
  1. {'42'}
  1. db>
  1. select <bool>to_json('true');
  1. {true}

Note that a json value can be cast into a str only when it is a JSON string. Therefore, while the following will work as expected:

  1. db>
  1. select <str>to_json('"something"');
  1. {'something'}

The operation below (casting a JSON array of string ["a", "b", "c"] to a str) will result in an error:

  1. db>
  1. select <str>to_json('["a", "b", "c"]');
  1. InvalidValueError: expected json string or null; got JSON array

Use the to_json() and to_str() functions to dump or parse a json value to or from a str:

  1. db>
  1. select to_json('[1, "a"]');
  1. {'[1, "a"]'}
  1. db>
  1. select to_str(<json>[1, 2]);
  1. {'[1, 2]'}

operator

json[i]

JSON - 图4

JSON - 图5

JSON - 图6

json [ int64 ] -> json

JSON array/string indexing.

The contents of JSON arrays and strings can also be accessed via []:

  1. db>
  1. select <json>'hello'[1];
  1. {'"e"'}
  1. db>
  1. select <json>'hello'[-1];
  1. {'"o"'}
  1. db>
  1. select to_json('[1, "a", null]')[1];
  1. {'"a"'}
  1. db>
  1. select to_json('[1, "a", null]')[-1];
  1. {'null'}

The element access operator [] will raise an exception if the specified index is not valid for the base JSON value. To access potentially out of bound indexes use the json_get() function.

operator

json[from:to]

JSON - 图7

JSON - 图8

JSON - 图9

json [ int64 : int64 ] -> json

JSON array/string slicing.

JSON arrays and strings can be sliced in the same way as regular arrays, producing a new JSON array or string:

  1. db>
  1. select <json>'hello'[0:2];
  1. {'"he"'}
  1. db>
  1. select <json>'hello'[2:];
  1. {'"llo"'}
  1. db>
  1. select to_json('[1, 2, 3]')[0:2];
  1. {'[1, 2]'}
  1. db>
  1. select to_json('[1, 2, 3]')[2:];
  1. {'[3]'}
  1. db>
  1. select to_json('[1, 2, 3]')[:1];
  1. {'[1]'}
  1. db>
  1. select to_json('[1, 2, 3]')[:-2];
  1. {'[1]'}

operator

json ++ json

JSON - 图10

JSON - 图11

JSON - 图12

json ++ json -> json

JSON concatenation.

JSON arrays, objects and strings can be concatenated with JSON values of the same type into a new JSON value.

If you concatenate two JSON objects, you get a new object whose keys will be a union of the keys of the input objects. If a key is present in both objects, the value from the second object is taken.

  1. db>
  1. select to_json('[1, 2]') ++ to_json('[3]');
  1. {'[1, 2, 3]'}
  1. db>
  1. select to_json('{"a": 1}') ++ to_json('{"b": 2}');
  1. {'{"a": 1, "b": 2}'}
  1. db>
  1. select to_json('{"a": 1, "b": 2}') ++ to_json('{"b": 3}');
  1. {'{"a": 1, "b": 3}'}
  1. db>
  1. select to_json('"123"') ++ to_json('"456"');
  1. {'"123456"'}

operator

json[name]

JSON - 图13

JSON - 图14

JSON - 图15

json [ str ] -> json

JSON object property access.

The fields of JSON objects can also be accessed via []:

  1. db>
  1. select to_json('{"a": 2, "b": 5}')['b'];
  1. {'5'}
  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select j := <json>(schema::Type {
  2. name,
  3. timestamp := cal::to_local_date(datetime_current(), 'UTC')
  4. })
  5. filter j['name'] = <json>'std::bool';
  1. {'{"name": "std::bool", "timestamp": "2019-04-02"}'}

The field access operator [] will raise an exception if the specified field does not exist for the base JSON value. To access potentially non-existent fields use the json_get() function.

function

to_json()

JSON - 图16

JSON - 图17

JSON - 图18

std::to_json(string: str) -> json

Return JSON value represented by the input string.

  1. db>
  1. select to_json('[1, "hello", null]')[1];
  1. {'"hello"'}
  1. db>
  1. select to_json('{"hello": "world"}')['hello'];
  1. {'"world"'}

function

json_array_unpack()

JSON - 图19

JSON - 图20

JSON - 图21

std::json_array_unpack(json: json) -> set of json

Return elements of JSON array as a set of json.

Calling this function on anything other than a JSON array will cause a runtime error.

This function should be used if the ordering of elements is not important or when set ordering is preserved (such as an immediate input to an aggregate function).

  1. db>
  1. select json_array_unpack(to_json('[1, "a"]'));
  1. {'1', '"a"'}

function

json_get()

JSON - 图22

JSON - 图23

JSON - 图24

std::json_get(json: json, variadic path: str) -> optional json

Return the JSON value at the end of the specified path or an empty set.

This function provides “safe” navigation of a JSON value. If the input path is a valid path for the input JSON object/array, the JSON value at the end of that path is returned. If the path cannot be followed for any reason, the empty set is returned.

  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select json_get(to_json('{
  2. "q": 1,
  3. "w": [2, "foo"],
  4. "e": true
  5. }'), 'w', '1');
  1. {'"foo"'}

This is useful when certain structure of JSON data is assumed, but cannot be reliably guaranteed:

  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select json_get(to_json('{
  2. "q": 1,
  3. "w": [2, "foo"],
  4. "e": true
  5. }'), 'w', '2');
  1. {}

Also, a default value can be supplied by using the coalescing operator:

  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select json_get(to_json('{
  2. "q": 1,
  3. "w": [2, "foo"],
  4. "e": true
  5. }'), 'w', '2') ?? <json>'mydefault';
  1. {'"mydefault"'}

function

json_set()

JSON - 图25

JSON - 图26

JSON - 图27

std::json_set( target: json, variadic path: str, named only value: optional json, named only create_if_missing: bool = true, named only empty_treatment: JsonEmpty = JsonEmpty.ReturnEmpty) -> optional json

Return an updated JSON target with a new value.

This function is only available in EdgeDB 2.0 or later.

  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select json_set(
  2. to_json('{"a": 10, "b": 20}'),
  3. 'a',
  4. value := <json>true,
  5. );
  1. {'{"a": true, "b": 20}'}
  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select json_set(
  2. to_json('{"a": {"b": {}}}'),
  3. 'a', 'b', 'c',
  4. value := <json>42,
  5. );
  1. {'{"a": {"b": {"c": 42}}}'}

If create_if_missing is set to false, a new path for the value won’t be created.

  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select json_set(
  2. to_json('{"a": 10, "b": 20}'),
  3. 'с',
  4. value := <json>42,
  5. );
  1. {'{"a": 10, "b": 20, "c": 42}'}
  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  6. ...
  1. select json_set(
  2. to_json('{"a": 10, "b": 20}'),
  3. 'с',
  4. value := <json>42,
  5. create_if_missing := false,
  6. );
  1. {'{"a": 10, "b": 20}'}

empty_treatment is an enumeration responsible for the behavior of the function if an empty set is passed to new_value. It contains one of the following values:

  • ReturnEmpty: return empty set, default

  • ReturnTarget: return target unmodified

  • Error: raise an InvalidValueError

  • UseNull: use a null JSON value

  • DeleteKey: delete the object key

  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select json_set(
  2. to_json('{"a": 10, "b": 20}'),
  3. 'a',
  4. value := <json>{}
  5. );
  1. {}
  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  6. ...
  1. select json_set(
  2. to_json('{"a": 10, "b": 20}'),
  3. 'a',
  4. value := <json>{},
  5. empty_treatment := JsonEmpty.ReturnTarget,
  6. );
  1. {'{"a": 10, "b": 20}'}
  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  6. ...
  1. select json_set(
  2. to_json('{"a": 10, "b": 20}'),
  3. 'a',
  4. value := <json>{},
  5. empty_treatment := JsonEmpty.Error,
  6. );
  1. InvalidValueError: invalid empty JSON value
  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  6. ...
  1. select json_set(
  2. to_json('{"a": 10, "b": 20}'),
  3. 'a',
  4. value := <json>{},
  5. empty_treatment := JsonEmpty.UseNull,
  6. );
  1. {'{"a": null, "b": 20}'}
  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  6. ...
  1. select json_set(
  2. to_json('{"a": 10, "b": 20}'),
  3. 'a',
  4. value := <json>{},
  5. empty_treatment := JsonEmpty.DeleteKey,
  6. );
  1. {'{"b": 20}'}

function

json_object_unpack()

JSON - 图28

JSON - 图29

JSON - 图30

std::json_object_unpack(json: json) -> set of tuple<str, json>

Return set of key/value tuples that make up the JSON object.

Calling this function on anything other than a JSON object will cause a runtime error.

  1. db>
  2. ...
  3. ...
  4. ...
  5. ...
  1. select json_object_unpack(to_json('{
  2. "q": 1,
  3. "w": [2, "foo"],
  4. "e": true
  5. }'));
  1. {('e', 'true'), ('q', '1'), ('w', '[2, "foo"]')}

function

json_typeof()

JSON - 图31

JSON - 图32

JSON - 图33

std::json_typeof(json: json) -> str

Return the type of the outermost JSON value as a string.

Possible return values are: 'object', 'array', 'string', 'number', 'boolean', 'null'.

  1. db>
  1. select json_typeof(<json>2);
  1. {'number'}
  1. db>
  1. select json_typeof(to_json('null'));
  1. {'null'}
  1. db>
  1. select json_typeof(to_json('{"a": 2}'));
  1. {'object'}