Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vLKIr-00CeLg-2L for pgsql-docs@arkaria.postgresql.org; Tue, 18 Nov 2025 11:55:22 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vLKIp-005r6t-2N for pgsql-docs@arkaria.postgresql.org; Tue, 18 Nov 2025 11:55:20 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vLKIp-005r6k-1M for pgsql-docs@lists.postgresql.org; Tue, 18 Nov 2025 11:55:19 +0000 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vLKIn-000Aab-0S for pgsql-docs@lists.postgresql.org; Tue, 18 Nov 2025 11:55:19 +0000 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-298145fe27eso72586425ad.1 for ; Tue, 18 Nov 2025 03:55:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763466914; x=1764071714; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=rHVfbVbBQYJOVtpkUUd+UgxW3H64vbIqD9emCpwKrBA=; b=hn4HlvlCBOIn6gxUHtUvvWKWFaAZddFnrlzUmjn/qq5fQsvGnrrexxIyrT4EELELWQ efH0dORdJ1TPRC4lMERPlJUcvX8wjiFrePj9flkzXeFNYAVGA+goVBSfqTXACOhTLqtk GtxNEgKWDECBiQWa9Nrf0F/8BYlyNO3qx8A4wS96e9VVGXUy6uwJa9sB4Bwjk1CPTsc9 1auvijL4D0B+vaj/YY38WgXz2SU4aSAtJ+JJ0MgromuHJP9R7hPQRMo+vmrNKctamWxr EbDqphv7IxevCJRKdk9DPPPythp5axEDluRAUcMDQqpiDpdOwseDQtBtpIn5CNgz6emW cNmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763466914; x=1764071714; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=rHVfbVbBQYJOVtpkUUd+UgxW3H64vbIqD9emCpwKrBA=; b=eSGBJRXNqqySkKgyNr1/Aj/kj7TWVDEMjh3QfbooS9KFM7/nGN93rm6XcQnYtW1vxJ JjDRZsBz2QycD/mtBHan9CaA9GSlLc7ybbKrVxqwW368V9pZcQdM5Cq14zG1NUWYKlp7 zXEakKixX1eXnRe16LESpX0X0s05nNFbUyGdBc2WUiPCsrczB5pazG/HdxOLetKlJ3/5 lawxE9bR7WqCw0nJCCAED6wD1yssss4m3Y+wuHAZWpWUg8JhSOE+IlJWetENlSdjMVPR grwZbkYND7pLDtiP10IXln6cbF3WGZHr+jthrxDyIvG3WXuvJRBO/ZTrKKvgIZCo2XCF axwA== X-Forwarded-Encrypted: i=1; AJvYcCWWcOL75j2MYLZCHOdlObzUGRdxQI0FNDNjD7OPILlMB71nuKQTSr9SrOLDRxJozSN3EfWPN39yRqYB@lists.postgresql.org X-Gm-Message-State: AOJu0Yztj1yP1aInKwGHhfJ6ogmviWqmsGqNbXDBNrUMgW5fgxJv9vbh 9wNtmWFOhM29P40QmbLkd3s0kWZRd7TgTxUPIpjpoeSgF+RvWES2xeXbFgfSUEy5ejwyoRaiCCp ADFPCsSoBzccuXNGLrnet5t9azwGQUrY= X-Gm-Gg: ASbGncu8x5fuhMcmHhgxe35VtIBkfb+ukMiuG3S6GE10hvvDbUUzqqIqbaYzfUwto7b 1i9nJzH2fyQEFnQIj9GXZf0faEBcTjRogm4VwvSkFQIlqEuY3aUinCtCnyZjLs2FLTuVrXk6ycs D/9sH8XXE8U/oKc4QNH2Vhd0XReEtoyaZcrEao2nI/d8hUm++GWzlJ1TkQ+Ga/+1nxQcHY6kFrP cSrKpwDMXwjV2+imxQh9Ko5FwJ13CHLqsDugjcRV8p4ZxHaLhWjBpcS7tjp X-Google-Smtp-Source: AGHT+IHEbdfC+wDT2LcqYG2qTyKnepWfqIh4c5xQXyhcOrmH31Z/1JmANmnKtcKZtcKFi/SrDrrPHNdNaWvfDrtN6ME= X-Received: by 2002:a17:903:18b:b0:295:592f:94a3 with SMTP id d9443c01a7336-2986a752bbfmr207869845ad.48.1763466913869; Tue, 18 Nov 2025 03:55:13 -0800 (PST) MIME-Version: 1.0 References: <174238647361.682.12732328104350596711@wrigleys.postgresql.org> In-Reply-To: From: r314tive Date: Tue, 18 Nov 2025 16:55:00 +0500 X-Gm-Features: AWmQ_bkhLvD6FBBV5WgvjcRDnQOGRwkRpZaxMejWZ4AYb9f6Dr4gHjPpqHvVSkc Message-ID: Subject: Re: Ambiguity in IS JSON description and logic To: "David G. Johnston" Cc: Kirk Parker , vavankaru@gmail.com, pgsql-docs@lists.postgresql.org Content-Type: multipart/mixed; boundary="000000000000f993250643dd2257" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000f993250643dd2257 Content-Type: multipart/alternative; boundary="000000000000f993240643dd2255" --000000000000f993240643dd2255 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, Based on this discussion, I=E2=80=99ve prepared a small documentation patch= that tries to clarify the behavior of the IS JSON ... UNIQUE KEYS clause. The patch explains that: - the WITH/WITHOUT UNIQUE KEYS clause controls an additional test on duplicate object keys, - WITH UNIQUE KEYS requires that no object contained in the expression (recursively) have duplicate keys, and - WITHOUT UNIQUE KEYS, which is also the default, just disables this additional test and does not require duplicates to be present. Patch is attached. Regards, Ilmar Yunusov =D0=B2=D1=82, 18 =D0=BD=D0=BE=D1=8F=D0=B1. 2025=E2=80=AF=D0=B3. =D0=B2 16:5= 0, David G. Johnston : > On Thu, Mar 20, 2025 at 7:22=E2=80=AFAM Kirk Parker wr= ote: > >> On Thu, Mar 20, 2025 at 7:08=E2=80=AFAM Kirk Parker w= rote: >> >>> >>> On Thu, Mar 20, 2025 at 2:46=E2=80=AFAM PG Doc comments form < >>> noreply@postgresql.org> wrote: >>> >>>> The following documentation comment has been logged on the website: >>>> >>>> Page: https://www.postgresql.org/docs/17/functions-json.html >>>> Description: >>>> >>>> On the manual page >>>> https://www.postgresql.org/docs/current/functions-json.html, in the >>>> Table >>>> 9.48. "SQL/JSON Testing Functions" there is a description of IS JSON. = It >>>> includes the next sentence: "If WITH UNIQUE KEYS is specified, then an= y >>>> object in the expression is also tested to see if it has duplicate >>>> keys." >>>> And such text is ambiguous, because the term "object" has certain >>>> meaning >>>> regarding json format. In reality the option WITH UNIQUE KEYS allows t= o >>>> check for duplicated keys any array element not object. For objects, >>>> both >>>> WITH UNIQUE KEYS and WITHOUT UNIQUE KEYS return false, and both IS JSO= N >>>> ARRAY WITH UNIQUE KEY and IS JSON ARRAY WITHOUT UNIQUE KEY return true >>>> (it >>>> is at the same time with and without unique values, how it is >>>> possible?), >>>> i.e. it works the same as just IS JSON ARRAY. The example code that >>>> confirms >>>> my reasoning: >>>> SELECT >>>> js.vl AS "tested str", >>>> >>>> >>>> js.vl IS JSON OBJECT WITH UNIQUE KEYS AS ".. object w. UQ >>>> keys", >>>> >>>> js.vl IS JSON OBJECT WITHOUT UNIQUE KEYS AS ".. object w/o UQ >>>> keys", >>>> js.vl IS JSON ARRAY WITH UNIQUE KEYS AS ".. array w. UQ >>>> keys", >>>> >>>> js.vl IS JSON ARRAY WITHOUT UNIQUE KEYS AS ".. array w/o UQ >>>> keys", >>>> js.vl IS JSON ARRAY ".. array" >>>> FROM (VALUES ('{{"a": "a1"}, {"a": "a2"}}'), ('[{"a": "a1"}, {"a": >>>> "a2"}]'), >>>> ('["a", "a"]')) AS js(vl); >>>> >>>> I'm not sure what should be the right logic for this option, for me it >>>> looks >>>> now the same as simple IS JSON ARRAY without any UNIQUE KEY option, bu= t >>>> if >>>> we use an option it should be either true for WITH UNIQUE KEYS or >>>> WITHOUT >>>> UNIQUE KEYS but not for both at the same time. But anyway the sentence= I >>>> showed above should contain "array" instead of "object" because for >>>> objects >>>> it returns false independently of applied option. I tested it on >>>> "PostgreSQL 17.0 on x86_64-windows, compiled by msvc-19.41.34120, >>>> 64-bit". >>>> >>> >>> First, WITHOUT UNIQUE KEYS does not mean "confirm that there are >>> duplicate keys", it's just a way of stating the default explicitly. In >>> other words it means "w/o testing for duplicate keys". Thus IS JSON OBJ= ECT >>> and IS JSON OBJECT WITHOUT UNIQUE KEYS will both always return identica= l >>> results on the same JSON expression. >>> >>> Secondly, the UNIQUE test is recursive; for objects maybe the meaning i= s >>> intuitive, but for JSON arrays -- which don't have any concept of keys; >>> JSON arrays are just ordered lists -- it means "does this array contain= any >>> embedded objects with duplicate keys". >>> >>> See: >>> >>> SELECT js, >>> js IS JSON "json?", >>> js IS JSON OBJECT "object?", >>> js IS JSON OBJECT WITH UNIQUE KEYS "object w. UK?", >>> js IS JSON OBJECT WITHOUT UNIQUE KEYS "object w/o UK?", >>> js IS JSON ARRAY "array?", >>> js IS JSON ARRAY WITH UNIQUE KEYS "array w. UK?", >>> js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?" >>> FROM (VALUES >>> ('[{"a":1},{"b":2,"b":3}]'), -- expect t for array, array w/o U= K >>> ('[{"a":1},{"b":2,"c":3}]'), -- expect t for ALL array tests >>> ('{"b":2,"b":3}'), -- expect t for object, object w/o >>> UK >>> ('{"c":2,"d":3}'), -- expect t for ALL object tests >>> ('{"c":2,"d":{ "e": 0, "e": 1}}'), -- WITH UNIQUE is recursive for >>> nested objects >>> ('{"c":2,"d":{ "e": 0, "f": {"g":1,"g":2}}}'), -- no matter how deep >>> ('[{"a":1},{"b":2,"c":{"d":1, "d":2}}]') -- and also tests arrays >>> recursively for embedded objecs >>> ) foo(js); >>> >>> >>> A couple of side notes: >>> >>> 1. Your first data example is not JSON at all. It's helpful for this >>> kind of test to include a plain IS JSON column, since any of the IS JSO= N X >>> tests can fail for two reasons: (a) it's not JSON, or (b) it is JSON bu= t >>> it's not an X. >>> >>> 2. Curiously, the JSON spec itself is completely silent on the meaning >>> of objects with duplicate keys. PostgreSQL is more helpful in this >>> regard--the docs explicitly state that the last value is the one that i= s >>> retained by JSONB and used in processing functions. >>> >>> >> To improve the documentation here, I would suggest simply adding the wor= d >> "recursively" after "tested": >> >> If WITH UNIQUE KEYS is specified, then any object in the *expression= * is >> also tested recursively to see if it has duplicate keys >> >> > I think the existing word "any" sufficiently implies "recursively". It > also doesn't really address the complaint here. I'm thinking something > more like: > > (this is changed intentionally, see below) > > expression IS [ NOT ] JSON [ { SCALAR | ARRAY | OBJECT } ] [ WITH UNIQUE = ] > -> boolean > > This predicate tests whether expression can be parsed as JSON. Two > additional properties can be tested at the same time: the type of the JSO= N > value, and whether it passes the unique object keys constraint. Enable t= he > first test by specifying one of SCALAR, ARRAY, or OBJECT. Enable the > second test by specifying WITH UNIQUE: This test is applied to all object= s > contained within the JSON value. The return value is true only if > expression can be parsed as JSON and all enabled tests pass. The return > value is inverted if NOT is specified. > > The test label "array w/o UK?" has to go. Coupling with the "additional > tests" idea introduced above, and the recommended syntax, we should do > something like: > > SELECT js, > js IS JSON "parses ok, no tests", > js IS JSON OBJECT "object test only", > js IS JSON ARRAY "array test only", > js IS JSON WITH UNIQUE "unique test only", > js IS JSON ARRAY WITH UNIQUE "array and unique tests" > > > Then, to keep the technical reference thorough, re-add the full syntax at > the end. > > > This is the full syntax accepted for this predicate. Both VALUE and > WITHOUT, the default explicit keywords to disable the two additional test= s, > as well as KEYS, are omitted above for clarity. > expression IS [ NOT ] JSON [ { VALUE | SCALAR | ARRAY | OBJECT } ] [ { > WITH | WITHOUT } UNIQUE [ KEYS ] ] > > David J. > > --000000000000f993240643dd2255 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

Based on this discussion, I=E2= =80=99ve prepared a small documentation patch that
tries to clarify the = behavior of the IS JSON ... UNIQUE KEYS clause.

The patch explains t= hat:
- the WITH/WITHOUT UNIQUE KEYS clause controls an additional test o= n
=C2=A0 duplicate object keys,
- WITH UNIQUE KEYS requires that no o= bject contained in the expression
=C2=A0 (recursively) have duplicate ke= ys, and
- WITHOUT UNIQUE KEYS, which is also the default, just disables = this
=C2=A0 additional test and does not require duplicates to be presen= t.

Patch is attached.

Regards,
Ilmar Yunusov
=D0=B2=D1=82, 18 =D0=BD=D0=BE=D1=8F=D0=B1. 2025=E2=80=AF=D0= =B3. =D0=B2 16:50, David G. Johnston <david.g.johnston@gmail.com>:
On Thu, Mar 20, 2025 at 7= :22=E2=80=AFAM Kirk Parker <khp@equatoria.us> wrote:
On Thu, Mar 20, 2025 at 7:08=E2=80=AFAM Kirk Parker = <khp@equatoria.us<= /a>> wrote:

The following documentation = comment has been logged on the website:

Page: https://www.postgresql.org/docs/17/funct= ions-json.html
Description:

On the manual page
https://www.postgresql.org/docs/current/f= unctions-json.html, in the Table
9.48. "SQL/JSON Testing Functions" there is a description of IS J= SON. It
includes the next sentence: "If WITH UNIQUE KEYS is specified, then an= y
object in the expression is also tested to see if it has duplicate keys.&qu= ot;
And such text is ambiguous, because the term "object" has certain= meaning
regarding json format. In reality the option WITH UNIQUE KEYS allows to
check for duplicated keys any array element not object. For objects, both WITH UNIQUE KEYS and WITHOUT UNIQUE KEYS return false, and both IS JSON
ARRAY WITH UNIQUE KEY and IS JSON ARRAY WITHOUT UNIQUE KEY return true (it<= br> is at the same time with and without unique values, how it is possible?), i.e. it works the same as just IS JSON ARRAY. The example code that confirm= s
my reasoning:=C2=A0
SELECT
=C2=A0 =C2=A0 js.vl AS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 "tested str",=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0

=C2=A0 =C2=A0 js.vl IS JSON OBJECT WITH UNIQUE KEYS AS=C2=A0 =C2=A0 =C2=A0 = ".. object w. UQ keys",=C2=A0 =C2=A0

=C2=A0 =C2=A0 js.vl IS JSON OBJECT WITHOUT UNIQUE KEYS AS=C2=A0 =C2=A0"= ;.. object w/o UQ keys",
=C2=A0 =C2=A0 js.vl IS JSON ARRAY WITH UNIQUE KEYS AS=C2=A0 =C2=A0 =C2=A0 = =C2=A0".. array w. UQ keys",=C2=A0 =C2=A0

=C2=A0 =C2=A0 js.vl IS JSON ARRAY WITHOUT UNIQUE KEYS AS=C2=A0 =C2=A0 "= ;.. array w/o UQ keys",
=C2=A0 =C2=A0 js.vl IS JSON ARRAY ".. array"
FROM (VALUES ('{{"a": "a1"}, {"a": "= a2"}}'), ('[{"a": "a1"}, {"a": &= quot;a2"}]'),
('["a", "a"]')) AS js(vl);

I'm not sure what should be the right logic for this option, for me it = looks
now the same as simple IS JSON ARRAY without any UNIQUE KEY option, but if<= br> we use an option it should be either true for WITH UNIQUE KEYS or WITHOUT UNIQUE KEYS but not for both at the same time. But anyway the sentence I showed above should contain "array" instead of "object"= because for objects
it returns false independently of applied option.=C2=A0 I tested it on
"PostgreSQL 17.0 on x86_64-windows, compiled by msvc-19.41.34120, 64-b= it".

First, WITHOUT UNIQUE KEYS do= es not mean "confirm that there are duplicate keys", it's jus= t a way of stating the default explicitly. In other words it means "w/= o testing for duplicate keys". Thus IS JSON OBJECT and IS JSON OBJECT = WITHOUT UNIQUE KEYS will both always return identical results on the same J= SON expression.=C2=A0

Secondly, the UNIQUE test is= recursive; for objects maybe the meaning is intuitive, but for JSON arrays= -- which don't have any concept of keys; JSON arrays are just ordered = lists -- it means "does this array contain any embedded objects with d= uplicate keys".

See:
=C2=A0SELECT js,
<= div class=3D"gmail_quote">
=C2=A0 js IS JSON &= quot;json?",
=C2=A0 js IS JSON OBJECT "object?",
=C2=A0 js I= S JSON OBJECT WITH UNIQUE KEYS "object w. UK?",
=C2=A0 js IS JSON= OBJECT WITHOUT UNIQUE KEYS "object w/o UK?",
<= div class=3D"gmail_quote">
=C2=A0 js IS JSON A= RRAY "array?",
= =C2=A0 js IS JSON ARRAY WITH UNIQUE KEYS "arr= ay w. UK?",
=C2=A0 js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/= o UK?"
FROM (VALUES
= =C2=A0 ('[{"a":1},{"b":2,&= quot;b":3}]'), =C2=A0 =C2=A0 =C2=A0 -- expect t for array, array w= /o UK
=C2=A0 ('[{"a":1},{"b":2,"c":3}]= 9;), =C2=A0 =C2=A0 =C2=A0 -- expect t for ALL array tests
=C2=A0 ('{&qu= ot;b":2,"b":3}'), =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 -- expect t for object, object w/o UK
<= div class=3D"gmail_quote">
=C2=A0 ('{"= ;c":2,"d":3}'), =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 -- expect t for ALL object tests
=C2=A0 ('{"c&qu= ot;:2,"d":{ "e": 0, "e": 1}}'), -- WITH U= NIQUE is recursive for nested objects
=C2=A0 ('{"c":2,"d= ":{ "e": 0, "f": {"g":1,"g":2}= }}'), -- no matter how deep
=C2=A0 ('[{"a":1},{"b&qu= ot;:2,"c":{"d":1, "d":2}}]') -- and also = tests arrays recursively for embedded objecs
) foo(js);

A couple of side notes:

1. Your first data examp= le is not JSON at all.=C2=A0 It's helpful for this kind of test to incl= ude a plain IS JSON column, since any of the IS JSON X tests can fail for t= wo reasons: (a) it's not JSON, or (b) it is JSON but it's not an X.=

2. Curiously, the JSON spec itself is comple= tely silent on the meaning of objects with duplicate=C2=A0keys.=C2=A0=C2=A0= PostgreSQL is more helpful in this regard--the d= ocs explicitly state that the last value is the one that is retained by JSO= NB and used in processing functions.

=C2=A0
To improve the documentation=C2=A0here,= I would suggest simply adding the word "recursively" after "= ;tested":

=C2=A0 =C2=A0 If=C2=A0<= code style=3D"box-sizing:border-box;font-family:monospace,monospace;font-si= ze:14.4px;color:rgb(33,37,41);border-radius:0.25rem;margin:0px;padding:0px;= word-break:unset">WITH UNIQUE KEYS=C2=A0is sp= ecified, then any object in the=C2=A0expression= =C2=A0is also tested recursively to see if it has duplicate keys


I think= the existing word "any" sufficiently implies "recursively&q= uot;.=C2=A0 It also doesn't really address the complaint here.=C2=A0 I&= #39;m thinking something more like:

(this is changed i= ntentionally, see below)

expression IS [ NOT ] JSON [ = { SCALAR | ARRAY | OBJECT } ] [ WITH UNIQUE ] -> boolean

This predicate tests whether=C2=A0expression can be parsed as JSON.= =C2=A0 Two additional properties can be tested at the same time: the type o= f the JSON value, and whether it passes the unique object keys constraint.= =C2=A0 Enable the first test by specifying one of SCALAR, ARRAY, or OBJECT.= =C2=A0 Enable the second test by specifying WITH UNIQUE: This test is appli= ed to all objects contained within the JSON value.=C2=A0 The return value i= s true only if expression can be parsed as JSON and all enabled tests pass.= =C2=A0 The return value is inverted if NOT is specified.

=
The test label "array w/o UK?" has to go.=C2=A0 Coupling with = the "additional tests" idea introduced above, and the recommended= syntax, we should do something like:

SELECT js,
=
=C2=A0 js IS JSON "parses ok, no tests",
=C2=A0 js IS JSON = OBJECT "object test only",
=C2=A0 js IS JSON ARRAY "array= test only",
=C2=A0 js IS JSON WITH UNIQUE "unique test o= nly",
=C2=A0 js IS JSON ARRAY WITH UNIQUE "array and uniq= ue tests"


Then, to keep the technica= l reference thorough, re-add the full syntax at the end.

=

This is the full syntax accepted for this predicate.=C2=A0 = Both VALUE and WITHOUT, the default explicit keywords to disable=C2=A0the t= wo additional tests, as well as KEYS, are omitted above for clarity.
<= div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif= ">expression IS [ NOT ] JSON [ { VALUE | SCALAR | ARRAY | OBJECT } ] [ { WI= TH | WITHOUT } UNIQUE [ KEYS ] ]

David J.

=
--000000000000f993240643dd2255-- --000000000000f993250643dd2257 Content-Type: application/octet-stream; name="0001-doc-Clarify-IS-JSON-UNIQUE-KEYS-behavior.patch" Content-Disposition: attachment; filename="0001-doc-Clarify-IS-JSON-UNIQUE-KEYS-behavior.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mi4ijyfi0 RnJvbSBjZTA2ODk5NDE2NzljNTViYjIyYzRhOTIwNmZiNzkyZmEyZGQ5MDllIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBpbG1hciB5dW51c292IDx0YW5zd2lzNDJAZ21haWwuY29tPgpE YXRlOiBUdWUsIDE4IE5vdiAyMDI1IDE2OjMwOjIyICswNTAwClN1YmplY3Q6IFtQQVRDSF0gZG9j OiBDbGFyaWZ5IElTIEpTT04gVU5JUVVFIEtFWVMgYmVoYXZpb3IKCi0tLQogZG9jL3NyYy9zZ21s L2Z1bmMvZnVuYy1qc29uLnNnbWwgfCAxMyArKysrKysrKystLS0tCiAxIGZpbGUgY2hhbmdlZCwg OSBpbnNlcnRpb25zKCspLCA0IGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2RvYy9zcmMvc2dt bC9mdW5jL2Z1bmMtanNvbi5zZ21sIGIvZG9jL3NyYy9zZ21sL2Z1bmMvZnVuYy1qc29uLnNnbWwK aW5kZXggMWVjNzNjZmY0NjQuLmNjYjIzZGNkY2IyIDEwMDY0NAotLS0gYS9kb2Mvc3JjL3NnbWwv ZnVuYy9mdW5jLWpzb24uc2dtbAorKysgYi9kb2Mvc3JjL3NnbWwvZnVuYy9mdW5jLWpzb24uc2dt bApAQCAtODkzLDEwICs4OTMsMTUgQEAKICAgICAgICAgcGFyc2VkIGFzIEpTT04sIHBvc3NpYmx5 IG9mIGEgc3BlY2lmaWVkIHR5cGUuCiAgICAgICAgIElmIDxsaXRlcmFsPlNDQUxBUjwvbGl0ZXJh bD4gb3IgPGxpdGVyYWw+QVJSQVk8L2xpdGVyYWw+IG9yCiAgICAgICAgIDxsaXRlcmFsPk9CSkVD VDwvbGl0ZXJhbD4gaXMgc3BlY2lmaWVkLCB0aGUKLSAgICAgICAgdGVzdCBpcyB3aGV0aGVyIG9y IG5vdCB0aGUgSlNPTiBpcyBvZiB0aGF0IHBhcnRpY3VsYXIgdHlwZS4gSWYKLSAgICAgICAgPGxp dGVyYWw+V0lUSCBVTklRVUUgS0VZUzwvbGl0ZXJhbD4gaXMgc3BlY2lmaWVkLCB0aGVuIGFueSBv YmplY3QgaW4gdGhlCi0gICAgICAgIDxyZXBsYWNlYWJsZT5leHByZXNzaW9uPC9yZXBsYWNlYWJs ZT4gaXMgYWxzbyB0ZXN0ZWQgdG8gc2VlIGlmIGl0Ci0gICAgICAgIGhhcyBkdXBsaWNhdGUga2V5 cy4KKyAgICAgICAgdGVzdCBpcyB3aGV0aGVyIG9yIG5vdCB0aGUgSlNPTiBpcyBvZiB0aGF0IHBh cnRpY3VsYXIgdHlwZS4KKyAgICAgICAgVGhlIG9wdGlvbmFsIDxsaXRlcmFsPldJVEg8L2xpdGVy YWw+IG9yIDxsaXRlcmFsPldJVEhPVVQ8L2xpdGVyYWw+CisgICAgICAgIDxsaXRlcmFsPlVOSVFV RSBLRVlTPC9saXRlcmFsPiBjbGF1c2UgY29udHJvbHMgYW4gYWRkaXRpb25hbCB0ZXN0CisgICAg ICAgIG9uIGR1cGxpY2F0ZSBvYmplY3Qga2V5cy4gIFNwZWNpZnlpbmcgPGxpdGVyYWw+V0lUSCBV TklRVUUgS0VZUzwvbGl0ZXJhbD4KKyAgICAgICAgcmVxdWlyZXMgdGhhdCBubyBvYmplY3QgY29u dGFpbmVkIGluIHRoZQorICAgICAgICA8cmVwbGFjZWFibGU+ZXhwcmVzc2lvbjwvcmVwbGFjZWFi bGU+IChyZWN1cnNpdmVseSkgaGF2ZSBkdXBsaWNhdGUga2V5cy4KKyAgICAgICAgU3BlY2lmeWlu ZyA8bGl0ZXJhbD5XSVRIT1VUIFVOSVFVRSBLRVlTPC9saXRlcmFsPiwgd2hpY2ggaXMgYWxzbyB0 aGUKKyAgICAgICAgZGVmYXVsdCwgZGlzYWJsZXMgdGhpcyBhZGRpdGlvbmFsIHRlc3Q7IGl0IGRv ZXMgbm90IHJlcXVpcmUgZHVwbGljYXRlCisgICAgICAgIGtleXMgdG8gYmUgcHJlc2VudC4KICAg ICAgICA8L3BhcmE+CiAgICAgICAgPHBhcmE+CiA8cHJvZ3JhbWxpc3Rpbmc+Ci0tIAoyLjUyLjAK Cg== --000000000000f993250643dd2257--