Artigo
· 8 hr atrás 4min de leitura

Suporte JSON no IRIS SQL

Enquanto trabalhava para obter suporte JSON para algumas bibliotecas Python, descobri alguns recursos fornecidos pelo IRIS.

  • JSON_OBJECT - Uma função de conversão que retorna dados como um objeto JSON.
  • JSON_ARRAY - Uma função de conversão que retorna dados como um array JSON.
  • IS JSON -Determina se um valor de dados está no formato JSON.
  • JSON_TABLE Retorna uma tabela que pode ser usada em uma consulta SQL mapeando JSON.
  • JSONPath é uma linguagem de consulta para consultar valores em JSON.

Bem, vamos testar o que essas funções realmente podem fazer.

JSON_OBJECT

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

JSON_OBJECT recebe uma lista separada por vírgulas de pares chave:valor (por exemplo, 'mykey':colname) e retorna um objeto JSON contendo esses valores. Você pode especificar qualquer string entre aspas simples como nome da chave; JSON_OBJECT não impõe nenhuma convenção de nomenclatura ou verificação de unicidade para nomes de chaves. Você pode especificar para o valor um nome de coluna ou outra expressão.

Vamos testar

  • Em vez de um valor vazio, obtenho '\u0000', ou simplesmente $char(0). Sim, esta é a forma como um valor vazio é representado no IRIS SQL, mas eu não esperava isso em JSON.
  • Não há como criar booleanos JSON, o IRIS SQL não possui booleanos, apenas 1 ou 0.
  • Objetos aninhados são suportados.
  • É possível omitir valores nulos no JSON resultante.

JSON_ARRAY

JSON_ARRAY ecebe uma expressão ou (mais comumente) uma lista de expressões separadas por vírgulas e retorna um array JSON contendo esses valores. JSON_ARRAY pode ser combinado em uma instrução SELECT com outros tipos de itens selecionados. JSON_ARRAY pode ser especificado em outros locais onde uma função SQL pode ser usada, como em uma cláusula WHERE.

Vamos testar

  • O mesmo problema com valores vazios e booleanos.
  • 1e12 é um tipo real e deveria manter o tipo.
  • Para criar um array vazio, é necessário colocar nulo e definir uma opção para omiti-lo.

IS JSON

scalar-expression IS [NOT] JSON [keyword]

O predicado IS JSON determina se um valor de dados está no formato JSON.

IS JSON (com ou sem a palavra-chave opcional VALUE) retorna verdadeiro para qualquer array JSON ou objeto JSON. Isso inclui um array JSON vazio '[]' ou um objeto JSON vazio '{}'.

As palavras-chave VALUE e SCALAR são sinônimos.

scalar-expression

Uma expressão escalar que está sendo verificada quanto ao formato JSON.

keyword

Um argumento opcional. Pode ser um dos seguintes: VALUE, SCALAR, ARRAY ou OBJECT. O padrão é VALUE.

Vamos testar

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

Parece bom, mas isso é totalmente no estilo ObjectScript. Vamos tentar com JDBC.

  • Agora não há mais objeto JSON ou array JSON, apenas valor ou escalar.
  • Valor nulo nem mesmo é JSON e também não é não-JSON, é apenas algo intermediário
  • JSON_OBJECT, JSON_ARRAY do exemplo acima, não são um objeto e nem um array de qualquer maneira, são algo diferente.
  • JSON é JSON, mas não é um objeto nem um array, então o que é?
  • Não há como fazer com que  is json object/arrayfuncione via ODBC/JDBC.

JSON_TABLE

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

A função JSON_TABLE retorna uma tabela que pode ser usada em uma consulta SQL mapeando valores JSON em colunas. Mapeamentos de um valor JSON para uma coluna são escritos como expressões de linguagem de caminho SQL/JSON.

Como uma função de valor de tabela, JSON_TABLE retorna uma tabela que pode ser usada na cláusula FROM de uma instrução SELECT para acessar dados armazenados em um valor JSON; essa tabela não persiste entre consultas. Múltiplas chamadas para JSON_TABLE podem ser feitas dentro de uma única cláusula FROM e podem aparecer ao lado de outras funções de valor de tabela.

  • Cadeias de caracteres vazias ou valores nulos são a mesma coisa."
  • Suportado mesmo o uso aninhado de json_array/json_object.

JSONPath

Uma expressão de linguagem de caminho SQL/JSON é uma sequência de operadores que definem um caminho através de um documento JSON para um conjunto desejado de valores.

Além de JSON_TABLE, pode ser usado diretamente em JSON usando ObjectScript usando o método apply em qualquer objeto JSON.

Extrair valores de um Array JSON

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>

E de um 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>
  • Novamente, não há diferença entre string vazia e nulo.
  • Mesmo para um único objeto, ele ainda retorna um array.

Conclusão

Todas as funções testadas apresentam problemas para distinguir entre nulo e strings vazias, que possuem diferença em SQL ou JSON. Não há como gerar valores booleanos em JSON.

Trabalhando com JSON a partir do Python, isso exigiria ainda mais, como mais tipos de valores, mas será assim.

Neste momento, não vejo utilidade para nenhuma dessas funções. E não tenho certeza se elas podem ser usadas em bibliotecas Python.

 
O que eu espero

 

Discussão (0)1
Entre ou crie uma conta para continuar