Skip to main content

mergedJSONPatch

Introduzido em: v26.8.0 Agrega valores JSON mesclando-os com a semântica “last-write-wins” (a última gravação prevalece), implementando o comportamento essencial de mesclagem do RFC 7396 JSON Merge Patch no nível de caminho. A função de agregação armazena o estado como trios (key, value, sorting_key), em que cada chave (caminho JSON) mantém apenas o registro efetivo mais recente de acordo com o sorting_key. Gravações de objetos são achatadas em caminhos descendentes nos caminhos que o tipo JSON armazena como folhas escalares dinâmicas. Gravações de valores que não são objetos em caminhos ancestrais sobrepõem os descendentes conflitantes. Todo caminho com tipo explícito (declarado com JSON(a Map(...)), JSON(a Tuple(...)), JSON(a Variant(...)), JSON(a Dynamic), etc.) é tratado como um valor atômico: o valor inteiro do caminho é substituído pelo patch mais recente, em vez de passar por mesclagem profunda. Apenas caminhos escalares sem tipo (dinâmicos) seguem a semântica de mesclagem profunda da RFC 7396. O sort_key determina qual valor prevalece para cada caminho JSON. A linha com o maior sort_key é mantida. Se dois patches em conflito tiverem chaves de ordenação iguais, o resultado depende da ordem: o patch processado por último vence o empate. Os usuários não devem depender de ORDER BY para desempatar de forma determinística. LIMITAÇÕES (herdadas de ColumnObject):
  1. Exclusão de nulos: um patch {"key": null} não remove a chave. ColumnObject descarta membros com valor nulo na inserção, portanto a função não consegue distinguir “chave ausente” de “chave nula”.
  2. Substituição por objeto vazio: um patch {"a": {}} não consegue substituir um escalar ou array mais antigo no caminho a. ColumnObject descarta silenciosamente caminhos cujo valor é um objeto vazio {}, então o patch mais recente não contribui com nada e o valor antigo é mantido.
  3. Ausência em caminho tipado não Nullable: quando uma coluna JSON declara um caminho tipado com um tipo não anulável (por exemplo, JSON(a UInt32)), uma linha que omite a é armazenada com o valor default do tipo (por exemplo, 0). A agregação não consegue distinguir “ausente” de “gravado explicitamente como valor default”, então um patch mais recente que omite a apaga silenciosamente um valor mais antigo diferente de zero. Para evitar isso, declare os caminhos tipados como Nullable (por exemplo, JSON(a Nullable(UInt32))). Um nulo em um caminho tipado anulável é tratado como “caminho ausente” e é corretamente ignorado.
  4. Todos os caminhos tipados são atômicos: todo caminho tipado (Map(K,V), JSON, Dynamic, Tuple(…), Variant(…), Array(…) ou qualquer outro tipo declarado) é armazenado como um único valor. A agregação substitui o valor inteiro de forma atômica, em vez de mesclar seu conteúdo em profundidade. Apenas os caminhos dinâmicos (não tipados, escalares) são mesclados em profundidade, caminho a caminho.
  5. Ambiguidade de ponto na chave: o tipo JSON representa {"a":{"b":1}} e {"a.b":1} com o mesmo caminho interno a.b. Assim, uma única linha pode expor tanto a quanto a.b como pares independentes. Quando um patch mais recente grava apenas a, a regra de conflito entre ancestral e descendente apaga a.b; quando grava apenas a.b, a mesma regra apaga a. Para evitar isso, defina json_type_escape_dots_in_keys = 1. Com essa configuração, os pontos literais nas chaves JSON recebem percent-encoding (por exemplo, a.b passa a ser a%2Eb), o que os diferencia dos caminhos aninhados e elimina o falso conflito.
Sintaxe
Argumentos
  • json — Coluna JSON a ser agregada. JSON
  • sort_key — Coluna comparável que determina qual gravação prevalece para cada caminho. A linha com o maior valor de sort_key é mantida.
Valor retornado Retorna um único objeto JSON resultante da mesclagem de todos os objetos JSON de entrada. JSON Exemplos Uso básico com chave de ordenação
Query
Response
Última modificação em 14 de outubro de 2026