Article
· Jan 22 4m read

JSON Support in IRIS SQL

While working on getting JSON support for some Python libraries, I discovered some capabilities IRIS provided.

  • JSON_OBJECT - A conversion function that returns data as a JSON object.
  • JSON_ARRAY - A conversion function that returns data as a JSON array.
  • IS JSON - Determines if a data value is in JSON format.
  • JSON_TABLE function returns a table that can be used in a SQL query by mapping JSON.
  • JSONPath support - is a query language for querying values in JSON.

Well, let's test what these functions really can do.

JSON_OBJECT

JSON_OBJECT(key:value [,key:value][,...] 
  [NULL ON NULL | ABSENT ON NULL])

JSON_OBJECT takes a comma-separated list of key:value pairs (for example, 'mykey':colname) and returns a JSON object containing those values. You can specify any single-quoted string as a key name; JSON_OBJECT does not enforce any naming conventions or uniqueness check for key names. You can specify for value a column name or other expression.

Let's try it out

  • Instead of empty value get '\u0000', or just $char(0). Yes, this is how an empty value is represented in IRIS SQL, but I did not expect it in JSON.
  • No way to make JSON booleans, IRIS SQL does not have booleans only 1 or 0
  • Nested objects supported
  • It is possible to omit null values in the resulting JSON

JSON_ARRAY

JSON_ARRAY takes an expression or (more commonly) a comma-separated list of expressions and returns a JSON array containing those values. JSON_ARRAY can be combined in a SELECT statement with other types of select-items. JSON_ARRAY can be specified in other locations where an SQL function can be used, such as in a WHERE clause.

Let's try it out

  • The same issue with empty values, and booleans
  • 1e12 is a real type, and supposed to keep type
  • to make an empty array, require put null and set an option to omit it

IS JSON

scalar-expression IS [NOT] JSON [keyword]

The IS JSON predicate determines if a data value is in JSON format.

IS JSON (with or without the optional VALUE keyword) returns true for any JSON array or JSON object. This includes an empty JSON array '[]' or an empty JSON object '{}'.

The VALUE keyword and the SCALAR keyword are synonyms.

scalar-expression

A scalar expression that is being checked for JSON formatting.

keyword

An optional argument. One of the following: VALUE, SCALAR, ARRAY, or OBJECT. The default is VALUE.

Let's try it out

USER>do ##class(%SQL.Statement).%ExecDirect(, "SELECT 'yes' is_json_object WHERE ? IS JSON OBJECT", {}).%Display()
is_json_object
yes

1 Rows(s) Affected
USER>do ##class(%SQL.Statement).%ExecDirect(, "SELECT 'yes' is_json_array WHERE ? IS JSON ARRAY", []).%Display()
is_json_array
yes

1 Rows(s) Affected

Seems good, but this is totally ObjectScript way. Let's try with JDBC

  • Now there is no more json object or json array, only value or scalar
  • Null value not even a json, and not a not json as well, it's just something in between
  • JSON_OBJECT, JSON_ARRAY from above, not an object and not an array anyway, it's something else
  • JSON is JSON but not an object not an array, so what it is
  • There is no way to get is json object/array working via ODBC/JDBC

JSON_TABLE

JSON_TABLE( json-value, json-path col-mapping )

The JSON_TABLE function returns a table that can be used in a SQL query by mapping JSONOpens in a new tab values into columns. Mappings from a JSON value to a column are written as SQL/JSON path language expressions.

As a table-valued function, JSON_TABLE returns a table that can be used in the FROM clause of a SELECT statement to access data stored in a JSON value; this table does not persist across queries. Multiple calls to JSON_TABLE can be made within a single FROM clause and can appear alongside other table-valued functions.

  • empty string or null values, are the same
  • supported even nested use of json_array/json_object

JSONPath

A SQL/JSON path language expression is a sequence of operators that define a path through a JSON document to a desired set of values.  

In addition to JSON_TABLE, it can be directly used on JSON using ObjectScript using apply method on any json object

Extract values from JSON Array

USER>zwrite [{"value":"test"},{"value":123},{"value":1.23},{"value":""},{"value":null}].apply("$.value")
["test",123,1.23,"",""]   ; <DYNAMIC ARRAY,refs=1>
USER>zwrite [{"value":null}].apply("$.value")
[""]   ; <DYNAMIC ARRAY,refs=1>
USER>zwrite [].apply("$.value")
[]   ; <DYNAMIC ARRAY,refs=1>

And from one JSON Object

USER>zwrite {"value":null}.apply("$.value")
[""]   ; <DYNAMIC ARRAY,refs=1>
USER>zwrite {"value":123}.apply("$.value")
[123]   ; <DYNAMIC ARRAY,refs=1>
USER>zwrite {}.apply("$.value")
[]   ; <DYNAMIC ARRAY,refs=1>
USER>zwrite {"value":""}.apply("$.value")
[""]   ; <DYNAMIC ARRAY,refs=1>
  • Again there is no difference between empty string and null
  • Even for a single object it still returns an array

Conclusion

Every function tested has problems distinguishing between null and empty strings, which have a difference in SQL or JSON. No way to generate boolean values in JSON.

Working with JSON from Python, would require even more out of this, such as more value types, but it will be so 

At this point, I don't see any purpose for any of these functions. And not sure if it can be used in Python libraries.

 
What I expect

 

Discussion (3)3
Log in or sign up to continue

JSON_Table got a deep dive in the context of the Document DB functionality.  @Stefan Wittmann presented an excellent session about this at last year's Global Summit

https://www.youtube.com/embed/T7RzkugC7QQ
[This is an embedded link, but you cannot view embedded content directly on the site because you have declined the cookies necessary to access it. To view embedded content, you would need to accept all cookies in your Cookies Settings]