JSON support in Spice is based on datafusion-functions-json, which provides functions and operators to extract, query, and manipulate JSON data stored as strings. Advanced features for JSON creation, modification, or complex path expressions are not supported.
:::warning[Limitations]
:::
Enables extracting and manipulating data from JSON strings. Each function takes a JSON string as the first argument, followed by one or more keys or indices to specify the path.
json_containsReturns true if a JSON string contains a specific key at the specified path.
json_getRetrieves a value from a JSON string based on its path.
json_get_strRetrieves a string value from a JSON string based on its path.
json_get_intRetrieves an integer value from a JSON string based on its path.
json_get_floatRetrieves a float value from a JSON string based on its path.
json_get_boolRetrieves a boolean value from a JSON string based on its path.
json_get_jsonRetrieves a nested JSON object or array as a raw JSON string from a JSON string based on its path.
json_get_arrayRetrieves an arrow array from a JSON string based on its path.
json_as_textRetrieves any value from a JSON string based on its path and represents it as a string. This is useful for converting JSON values to text format.
json_lengthReturns the length of a JSON string, array, or object. For objects, returns the number of key-value pairs. For arrays, returns the number of elements. For strings, returns the character count.
json_object_keysReturns the top-level keys of a JSON object as an array of strings. If a path is provided, returns the keys of the object at that path. Returns NULL if the value at the path is not an object.
Alias: json_keys.
-> {#op_json_get}JSON access operator. Retrieves a value from a JSON string based on its path. This operator is an alias for json_get.
->> {#op_json_as_text}JSON access operator for text extraction. Retrieves any value from a JSON string and converts it to text. This operator is an alias for json_as_text.
? {#op_json_contains}JSON containment operator. Returns true if a JSON string contains the specified key. This operator is an alias for json_contains.
JSON functions can be used in views to simplify access to nested JSON data:
Spice includes table-valued functions for decomposing JSON structures into relational rows. Each function is available as both a UDTF (in the FROM clause with literal input) and a scalar UDF returning a list of structs (for per-row use with UNNEST).
flatten_jsonWalks an arbitrary JSON value and emits one row per reachable leaf.
Options (named arguments):
| Option | Type | Default | Description |
|---|---|---|---|
max_depth | UInt | 64 | Maximum recursion depth. |
max_rows | UInt | 1000000 | Per-document row cap. |
max_bytes | UInt | 8388608 | Input size limit (bytes). |
path_style | Utf8 | "dot" | "dot" or "json-pointer". |
include_internal | Bool | false | Also emit interior object/array rows. |
array_wildcard | Bool | false | Collapse array indices to [*] instead of , , etc. |
UDTF example:
| path | value | type |
|---|---|---|
user.name | Alice | string |
user.scores[0] | 95 | integer |
user.scores[1] | 87 | integer |
Scalar UDF example (per-row with UNNEST):
flatten_json_propertiesDecomposes a JSON Schema document into one row per field, extracting metadata such as types, descriptions, required status, enums, and format.
Handles properties recursion, items.properties (arrays of objects), additionalProperties maps, allOf/oneOf/anyOf merging, and local $ref pointers with cycle detection.
Options (named arguments):
| Option | Type | Default | Description |
|---|---|---|---|
max_depth | UInt | 32 | Maximum recursion depth. |
max_rows | UInt | 100000 | Per-document row cap. |
max_bytes | UInt | 8388608 | Input size limit (bytes). |
path_style | Utf8 | "dot" | "dot" or "json-pointer". |
dialect | Utf8 | "json-schema" | "json-schema" or "openapi" (metrics tagging). |
include_internal | Bool | false |
Example:
| path | type | required | description |
|---|---|---|---|
name | string | true | User name |
age | integer | false |
Expanding maps:
When a JSON Schema uses additionalProperties to describe map values, enable expand_maps to produce JSONPath-style paths:
| path | type |
|---|---|
[*].id | string |
[*].primary | boolean |
json_treeRecursive depth-first walk of an arbitrary JSON document. Schema-agnostic sibling of flatten_json_properties that mirrors the json_tree table function in DuckDB and SQLite: one row per node (interior and leaf) in depth-first order, with JSON-Path addresses and a parent pointer for reconstructing the tree.
Options (named arguments, UDTF form only):
| Option | Type | Default | Description |
|---|---|---|---|
max_depth | UInt | 64 | Maximum recursion depth. |
max_rows | UInt | 1000000 | Per-document row cap. |
max_bytes | UInt | 8388608 | Input size limit (bytes). |
UDTF example:
| id | parent | fullkey | type | atom |
|---|---|---|---|---|
0 | $ | object | ||
1 | 0 | $.user | object | |
2 | 1 | $.user.name | string | Alice |
3 | 1 | $.user.scores | array | |
4 |
Scalar UDF example (per-row with UNNEST):
The scalar form takes only the JSON argument and always runs with default caps; the named options above are only accepted in the UDTF (FROM clause) form.
[0][1]| Also emit container rows (objects, arrays). |
expand_maps | Bool | false | Walk into additionalProperties and emit child paths with a wildcard segment (e.g., parent.[*].child). |
map_wildcard | Utf8 | "[*]" | Wildcard segment for map values when expand_maps is true. |
3$.user.scores[0] |
integer |
95 |
5 | 3 | $.user.scores[1] | integer | 87 |