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 1vh3SB-008ra7-1s for pgsql-hackers@arkaria.postgresql.org; Sat, 17 Jan 2026 10:22:48 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vh3S9-007Q1T-2l for pgsql-hackers@arkaria.postgresql.org; Sat, 17 Jan 2026 10:22:46 +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 1vh3S9-007Q1D-1S for pgsql-hackers@lists.postgresql.org; Sat, 17 Jan 2026 10:22:45 +0000 Received: from mail-yw1-x1134.google.com ([2607:f8b0:4864:20::1134]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vh3S7-000yXI-26 for pgsql-hackers@lists.postgresql.org; Sat, 17 Jan 2026 10:22:45 +0000 Received: by mail-yw1-x1134.google.com with SMTP id 00721157ae682-78fc3572431so30283767b3.0 for ; Sat, 17 Jan 2026 02:22:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1768645361; cv=none; d=google.com; s=arc-20240605; b=Jdu3wNdvS5KHacOclVjFb+12dT0oUqIfvmUKcagIZMOKdjxSiMnHP82t+5QKvs37N0 LGefajnSqtqMjEGRhNPMSiunDLLyY7kGUAgIAY6pG41Enav4o7w+m5BlKx2O177+2FjG y+BvYydlTxaPMqtCUpFnmPh9R4C2gnlZAxu9gxChq9/GjBkgu751cKYX4fSYlTlcmxiA Qp4QgMNhyh1/BIuanOvciu3Z2On18nLS5TVldWUM/0dykDdL+SBwSaMNZahzYtTz32zx 1cJ2UrZJ8TxcO64WglWbXvFein8jcOX83vCU9X3BO9/GVChTpVTfKHwQZp50wmjg8k07 Czbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=ilxXAY8CFm3z693XDFaaIGqasvraZVonTATWG9yueeY=; fh=p1AxSSALdG0nzc6EzCSjsiQbgDU8h3S3l+0eCXavfN8=; b=IuhX8ObodOnIn1AMTxOs3kZB/nkU3I6sX/ie2ryoB8lPU2/z3dpf62Pu3uexrJh3RL VBQBNVbcm0wXf4wLCSUFogfWxvU6RDE/wiHMPEt4AF7LdrDHVliWlOW/udMKtfCSNLm1 u+YKXENUOoWt9J0lPOUWclGgMcuJyHTYYMlcwa1QUK1RjpDJT9sr8fwx0H04946U0t+i mspqOWnWoWRDndvk1v8clUpVh41OeyQbTjeFUbJmbBUXLQ74cp1PMFqRDvmgahdHrAoL /5r6n+ECGQANwKfjDlBU1WAItC6zBHw0IP/TEJqWHL1zibukOjBUg72wLSlTqFBxB7Ln 4YUg==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768645361; x=1769250161; 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=ilxXAY8CFm3z693XDFaaIGqasvraZVonTATWG9yueeY=; b=hTzeYv4RBtZ1c9Is3CPLN2lL+HHIQKp+u25gFNyqlyFWOsMrN6zshIfB/aWEOVVhI7 HoHagF7GULAKJwGA7hAxq5k2xcPIEUYJGtrcFjBsIPOmDiE66Ak/+MaVrP2hEtZeNR+P fUCDBAjTPD9/QJ5bC/1I6PiUPpnHSe5QPWDNQgbyFKzRyNHXSerzAub7Tf2as9hM3ytP oEW6Xw8pb/15FBxnxQCZoNG/UyQdQfz/8Qqc22wz6DeyV3iQKjk02ZzHDe8kuIMgqnEm qpcDOW3mvKPiisKqhKBGdV6veSVrxFrhQJwOUb5adjJ4qJBR5BryrqvN6upEHLFcE9/3 Q92g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768645361; x=1769250161; 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=ilxXAY8CFm3z693XDFaaIGqasvraZVonTATWG9yueeY=; b=GS2eSHZ5BPd7rJ9gQ7QoBFYXM+NouS1zdUREaaqEIuRSSM5ILKPL0/mtZDdTgTtzs4 cAQWPiSZxkzAvM1c7pF0gShJNh5zA8WdVwsnhklyxgVuSadJ418JGuBD/e1wQazJD6uc vKWkV4q6oMDrUlEfMNPONsn88w/LZLwth9/2In624AgWgEbri8mRw3vMjj+Bn5qtw5Rv 298H0315L545jtAT0m7swdgsXReVOs4dM39ZkY3aK2dyfNkBPLSlE35ZSmU8T7yGlDqj eEXprdwB7rgb8yX121UoWKyI2W9NIWLPRwcIm/0WKQbhQc0/+H61y9sZr+5O6kv+K/O1 /WIQ== X-Forwarded-Encrypted: i=1; AJvYcCVtX8eW9tA/yCIzFcbgn508mdPeHSDCC6SaVTeTuZQyuVXiV44cYWZi+oWL0FPzJONw1rKQAfYWWUX/EjBx@lists.postgresql.org X-Gm-Message-State: AOJu0YzxAgV4sbPARxoaKG49iEQFksy6tPQypDc+2BovMM+Iuvee/GlT Uwvkys1fECyfWAxBy0ULaDK2382yf8G6SdqrEa5lolInK3plXsTXQfl3H67LUo/MMi5JxGb3wam sCjMhr1oGspZPLI+wqO4FlIJJLTUSifo= X-Gm-Gg: AY/fxX5ZevPRN3xni1i04q106w38s+QiznR0jIpjoFA9S4ED8ECI4e88mO+S2tBcsP5 DEILrxv7c3aOtUhxtiz0CUvaHXJEOBezcn2sOOL1RWiZBOLuR89sQNTsz28e8wiMq6DZI55vF1o TrPODG7eGz8XGL/v++jObP7zxFvWRAH1C776QCaRHedwr4/r2vJtXfLFiFYfxisruCTU3dSVRNG 4XQvC+pbqVTbS8J4mXpfkz77N+T009JqqvKLxrbueIM/MGZDDw35ZmHCSc2phpmvjpU7ZRbf3m/ f0QgEQhTBQOWdj+pb+zH4ERUpJcjLnhTWhjABnZEYnH3tG6968icGtmOWAoTfmBLtRdRmMycwtj OsJG3sWA4CpR7MDpA1LIeOjC2qib/iTx1NkXXrAioWE6VCg== X-Received: by 2002:a05:690c:82:b0:792:7236:9731 with SMTP id 00721157ae682-793c5333169mr47844257b3.16.1768645360736; Sat, 17 Jan 2026 02:22:40 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Pavel Stehule Date: Sat, 17 Jan 2026 11:22:04 +0100 X-Gm-Features: AZwV_Qhj6Jj3ib4y5r7RLBVz0UUk8fhvZZxNJnLn2S0DhVCYkMIZurr5tEHiVmk Message-ID: Subject: Re: jsonb subscripting vs SQL/JSON array accessor semantics (SQL:2023) To: Jelte Fennema-Nio Cc: Alexandra Wang , PostgreSQL Hackers , Peter Eisentraut Content-Type: multipart/alternative; boundary="00000000000075dbc3064892d68d" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000075dbc3064892d68d Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable so 17. 1. 2026 v 10:54 odes=C3=ADlatel Jelte Fennema-Nio napsal: > On Fri, 16 Jan 2026 at 22:27, Alexandra Wang > wrote: > > In all cases above, json_query() follows the SQL/JSON standard > > specification. jsonb subscripting, which predates the standard, > > differs in several ways: > > My thoughts on changing these 3 behaviours: > > > 1. Array access on non-arrays (scalars or objects) does not use 'lax' > > mode wrapping. As a result, "[0]" does not return the original value. > > I think it's unlikely anyone cares about the exact behaviour here in > practice. But changing the behaviour could corrupt expression indexes > that use this syntax. > > > 2. Non-integer subscripts are not supported. > > Changing this to not throw an error seems fine to me. Making something > that throw an error, now not throw an error should not cause breakage > for people. The new behaviour would be of arguable usefulness though. > > > 3. Negative subscripts use a PostgreSQL-specific extension. > > I think there are probably people relying on it. And postgres > behaviour actually seems way more useful than the SQL Standard > behaviour. > > You said DuckDB does the same as Postgres. That doesn't surprise me > much, since DuckDB usually defaults to Postgres behaviour. They don't > care much about being strictly sql standard compliant, if that means > more sensible/useful SQL for their users. And since many of their > users are used to Postgres, they try to stay PostgreSQL compatible in > their SQL (unless they think the postgres behaviour is really > weird/confusing). > > I do wonder what other databases do though. Does Oracle, MySQL or > MSSQL actually follow the standard here? i.e how incompatible is this > behaviour in practice with other databases? > > > I would very much appreciate any thoughts or guidance on this. > > If change 3 would not have been there, I would have probably been okay > with changing Postgres to behave like the SQL standard and telling > people to re-index their indexes that use this syntax in that major > release. But I think we should keep our current behaviour for option > 3. > > An approach that I think would be viable to do that is: > 1. Define a new sqlpath mode (e.g. with the name lax_postgres or > something). And define that as our current behaviour (possibly with 2 > changed to behave like lax). > 2. Document that our SQL/JSON simplified accessors diverge slightly > from the SQL standard because they use lax_postgres instead of lax. > > That would mean there's still an easy 1-to-1 translation between the > simplified accessor string and and JSON_QUERY (all that would be > different is the change from lax to lax_postgres in the string) > I am not sure if the implementation of the third method is the best we can do. Described handling of corner cases in SQL/JSON has some logic and consistency, but it is not compatible with the generic philosophy of PostgreSQL arrays. If I know ANSI/SQL doesn't know arrays, so this inconsistency is just a PostgreSQL problem, and because we don't like feature flags, I don't see any solution to how this situation can be solved. Any solution will be ugly. In this situation I prefer current behavior - (inconsistency between array access and JSON_QUERY) with good description in documentation. Theoretically it can be introduced lax_postgres like you propose. But I don't see how it can help with possible compatibility issues when somebody will migrate from other databases. So anything inside JSON_XXXX functions can be rigidly consistent with standard SQL/JSON. Outside should not be true - and it is better to say it explicitly. I don't think introducing some JavaScripts concepts to Postgres (although just for some corner cases) is a good idea (when we have some specific handling of some corner cases too). Regards Pavel --00000000000075dbc3064892d68d Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


so 17. 1. 2026 = v=C2=A010:54 odes=C3=ADlatel Jelte Fennema-Nio <postgres@jeltef.nl> napsal:
On Fri, 16 Jan 2026 at 22:27, Alexandra Wa= ng
<alexa= ndra.wang.oss@gmail.com> wrote:
> In all cases above, json_query() follows the SQL/JSON standard
> specification. jsonb subscripting, which predates the standard,
> differs in several ways:

My thoughts on changing these 3 behaviours:

> 1. Array access on non-arrays (scalars or objects) does not use 'l= ax'
> mode wrapping. As a result, "[0]" does not return the origin= al value.

I think it's unlikely anyone cares about the exact behaviour here in practice. But changing the behaviour could corrupt expression indexes
that use this syntax.

> 2. Non-integer subscripts are not supported.

Changing this to not throw an error seems fine to me. Making something
that throw an error, now not throw an error should not cause breakage
for people. The new behaviour would be of arguable usefulness though.

> 3. Negative subscripts use a PostgreSQL-specific extension.

I think there are probably people relying on it. And postgres
behaviour actually seems way more useful than the SQL Standard
behaviour.

You said DuckDB does the same as Postgres. That doesn't surprise me
much, since DuckDB usually defaults to Postgres behaviour. They don't care much about being strictly sql standard compliant, if that means
more sensible/useful SQL for their users. And since many of their
users are used to Postgres, they try to stay PostgreSQL compatible in
their SQL (unless they think the postgres behaviour is really
weird/confusing).

I do wonder what other databases do though. Does Oracle, MySQL or
MSSQL actually follow the standard here? i.e how incompatible is this
behaviour in practice with other databases?

> I would very much appreciate any thoughts or guidance on this.

If change 3 would not have been there, I would have probably been okay
with changing Postgres to behave like the SQL standard and telling
people to re-index their indexes that use this syntax in that major
release. But I think we should keep our current behaviour for option
3.

An approach that I think would be viable to do that is:
1. Define a new sqlpath mode (e.g. with the name lax_postgres or
something). And define that as our current behaviour (possibly with 2
changed to behave like lax).
2. Document that our SQL/JSON simplified accessors diverge slightly
from the SQL standard because they use lax_postgres instead of lax.

That would mean there's still an easy 1-to-1 translation between the simplified accessor string and and JSON_QUERY (all that would be
different is the change from lax to lax_postgres in the string)

I am not sure if the implementation of the third m= ethod is the best we can do.

Described handling of= corner cases in SQL/JSON has some logic and consistency, but it is not com= patible with the generic philosophy=C2=A0of PostgreSQL arrays. If I know AN= SI/SQL doesn't know arrays, so this inconsistency is just a PostgreSQL = problem, and because we don't like feature flags, I don't see any s= olution to how this situation can be solved.=C2=A0

Any solution will be ugly. In=C2=A0 this situation I prefer current behavi= or - (inconsistency between array access and JSON_QUERY) with good descript= ion in documentation.=C2=A0

Theoretically it can b= e introduced=C2=A0lax_postgres like you propose. But I don't see how it= can help with possible compatibility issues when somebody will migrate fro= m other databases.

So anything inside JSON_XXXX fu= nctions can be rigidly consistent with standard SQL/JSON. Outside should no= t be true - and it is better to say it explicitly. I don't think introd= ucing some JavaScripts concepts to Postgres (although just for some corner = cases) is a good idea (when we have some specific handling of some corner c= ases too).

Regards

Pavel<= /div>

=C2=A0
--00000000000075dbc3064892d68d--