Nueva publicación

Encontrar

Artículo
· 22 ene, 2025 Lectura de 4 min

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

 

3 comentarios
Comentarios (3)3
Inicie sesión o regístrese para continuar
Artículo
· 22 ene, 2025 Lectura de 1 min

Destacados de Interoperabilidad HTTP 2024.3 - Nuevos Ajustes de OAuth 2.0 para Salidas

En vuestra Producción de Interoperabilidad, siempre podíais tener una Business Operation (BO) que fuera un cliente HTTP y que utilizara OAuth 2.0 para la autenticación. Sin embargo, teníais que personalizar la BO para esta metodología de autenticación. Desde la versión 2024.3, que se lanzó recientemente, hay una nueva capacidad que proporciona nuevos ajustes para gestionar esto de forma más sencilla.

En vuestra BO que utiliza el Adaptador HTTP de Salida, encontraréis nuevos ajustes bajo el grupo OAuth.  

Por ejemplo:

  • Ubicación del Token de Acceso (Header | Body | Query)  
  • Tipo de Concesión (Password | JWT Authorization | Client Credentials

Consultad toda la documentación sobre los nuevos ajustes relacionados con OAuth aquí.

Y aquí tenéis una captura de pantalla de ejemplo de los ajustes de una BO relacionada:

Comentarios (0)1
Inicie sesión o regístrese para continuar
Comentarios (0)1
Inicie sesión o regístrese para continuar
Artículo
· 22 ene, 2025 Lectura de 1 min

Probando la función FOREIGN SERVER y FOREIGN TABLE

¡Hola! He ampliado mi repositorio de demostración, andreas5588/demo-dbs-iris, para facilitar las pruebas de las funciones FOREIGN SERVER y FOREIGN TABLE en IRIS.

Para lograrlo, creé un espacio de nombres llamado FEDERATION. La idea es la siguiente:

  1. Configurad conexiones JDBC para cada espacio de nombres.
  2. Cread un FOREIGN SERVER dentro del espacio de nombres FEDERATION para cada conexión.
  3. Definid al menos una FOREIGN TABLE basada en cada servidor externo.

El Script:  demo-dbs-iris/src/sql/02_create_foreign_server.sql

IRIS no permite ejecutar sentencias SQL que combinen tablas de diferentes NAMESPACES. Para abordar esta limitación, este NAMESPACE federado aprovecha el concepto de crear foreign servers para incluir otros NAMESPACES. Al definir foreign tables, se hace posible combinar tablas de diferentes NAMESPACES de forma fluida, permitiendo que escribáis sentencias SQL que unifiquen datos en una sola consulta.

Este NAMESPACE se utiliza para explorar esta función y sirve como una demostración práctica de esta capacidad, mostrando cómo explorarla y utilizarla.

Ejecutad este contenedor de demostración directamente mediante:

docker pull andreasschneiderixdbde/demo-dbs-iris:latest

Después de eso, podéis hacer consultas como esta:

¡Divertíos probando y mejorando la demostración!

 

Traducción del post original de Andreas

Comentarios (0)1
Inicie sesión o regístrese para continuar
Artículo
· 22 ene, 2025 Lectura de 2 min

如何查询某张数据表占用的磁盘空间?

近期有些小伙伴需要查询某张特定的表所占用的磁盘大小,可能其他小伙伴也有类似的需求。

给大家一个例子供参考。

应当考虑到IRIS的表底层使用global存储数据,包括表数据、索引数据和流数据(如果表中有流属性的话),因此一张表的完整占用应当包含至少上述三种global的求和,如下所示:

Class GlbUtil.GlobalSearch Extends %RegisteredObject
{



ClassMethod GetTableSize(databaseName As %String, tableName As %String) As %Integer [ SqlProc ]

{

set currentNS = $namespace
//在%SYS命名空间中用API获得数据库的文件所在的路径
zn "%SYS"
set bdDirectory = $replace(##Class(Config.Databases).DatabaseByName(databaseName),"^","")

//回到表所在的命名空间,通过API获得表存储数据所用的global名称
zn currentNS

set totalSize = 0
set dataSize = 0
set idxSize = 0
set streamSize = 0
//Data location
set dataGlbName = $replace(##class(%Dictionary.ClassDefinition).%OpenId(tableName).Storages.GetAt(1).DataLocation,"^","")

//计算data global占用的磁盘大小,这里计算的是已经分配给这个global的大小(但不一定占完了),也可以计算实际占用了的大小,可以查询该API获得详情
set sc=##class(%Library.GlobalEdit).GetGlobalSize(bdDirectory,dataGlbName,.dataSize,,1)

//Index location
set idxGlbName = $replace(##class(%Dictionary.ClassDefinition).%OpenId(tableName).Storages.GetAt(1).IndexLocation,"^","")

set sc=##class(%Library.GlobalEdit).GetGlobalSize(bdDirectory,idxGlbName,.idxSize,,1)

//Stream location
set streamGlbName = $replace(##class(%Dictionary.ClassDefinition).%OpenId(tableName).Storages.GetAt(1).StreamLocation,"^","")

set sc=##class(%Library.GlobalEdit).GetGlobalSize(bdDirectory,streamGlbName,.streamSize,,1)

//求和返回
set totalSize = dataSize + idxSize + streamSize

Quit totalSize

}



}

上述代码定义了一个SQL函数,可以通过SQL直接查询,效果如下:

其中,HCC为表所在的数据库,Test.Test是测试用的数据表。返回的结果统计单位是MB。

读者可以在这个demo基础上添加些自己需要的其他特性和异常处理。现在这个函数返回的是系统分配给表的占用(不一定真用完了),读者可以参考在线文档中的API说明,获得更多详细的信息,例如要获取实际占用的空间而不是已分配的空间,应该如何调用API等。

Comentarios (0)1
Inicie sesión o regístrese para continuar