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 1vh30t-008ma6-1N for pgsql-hackers@arkaria.postgresql.org; Sat, 17 Jan 2026 09:54:37 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vh30s-007Fyh-0U for pgsql-hackers@arkaria.postgresql.org; Sat, 17 Jan 2026 09:54:34 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vh30r-007FyQ-2V for pgsql-hackers@lists.postgresql.org; Sat, 17 Jan 2026 09:54:34 +0000 Received: from mail-lj1-x235.google.com ([2a00:1450:4864:20::235]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vh30o-000u5g-2F for pgsql-hackers@lists.postgresql.org; Sat, 17 Jan 2026 09:54:33 +0000 Received: by mail-lj1-x235.google.com with SMTP id 38308e7fff4ca-38320cd563aso36545301fa.0 for ; Sat, 17 Jan 2026 01:54:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jeltef.nl; s=google; t=1768643668; x=1769248468; 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=OA1oAvSvhBFY0P9yPeYacDbgHhpYsRIUd+BZu080k5U=; b=IdtFW15pe3hmLp4gaTq1I3pqtADsEG1GAP7y3DdQZG0YhKvMwiudxo5+3+Rkwc7uYO zMfQNZf2EmH469rGuZzoVXRIXi8i6N633st4JJ2ZF4qDfJA/vxt7rpsWz3AcUgKVghBG GGKgXOI1ZjxVlqgz3fgPX52O04VwQdzHlVhWgyRpeYSjlbjjTn/Oj5zr9Ojim9XRdThw jZFB12NSGT8FXnYzsId4fj3/FJCR7sUjDVA9OwB3qFnhsyqpuO0/z3rjufyJnLbJEbu1 Tve8qgj0kQXW/bX3YQlVpBOpn+k/y+NLS8LIWm+98ZkMZgi93wBWIpeiZA0dll+tbB00 22VA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768643668; x=1769248468; 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=OA1oAvSvhBFY0P9yPeYacDbgHhpYsRIUd+BZu080k5U=; b=SCs1U1zctJ86ykSaMaYpmxptV7JGfFt24aOarfNpKLesBcpgJ/+HQZW8rX7cCeyYEz FjSo8s9CfVNrcf3c1rl7u/DBhh6u0+gxMsnmb/ugR/diJAWpEGhqTi8XYl24lFkUQuTW 03HmZAcf+OibNZudlAQzjoVGlVveX+xvXfdPqEM4Wm+0+0ECbGA49KMpWfMx1lRgHS+I f8SVqztlzYm82pLP6ZkrD0bI2r4/tzDjS1Xj/xZwSnS9TSgIWKZcg6AuQ99aH0E49kIK q6ilNBfuI/hiN0f2PGl+x+eBdd445G4a47GJHKNhroPTcwhVAmn8ckmsZTPSfcbIoh20 z9tw== X-Gm-Message-State: AOJu0YyKkipb6kLqKr3gCEnpzO/E41z+v8laT04PhLAg+K90O+RbdgeV rNWEzFkZDSm/MHFLdS0GFsSqkMNx+dzSwCfPgXGa06s9ZvtHBParJ/+XY6aV62IyGFa5/SE7y0E W/8E+YrPfvMRPKq4TfHgACansKXfvgOKHmkcNAWnD4Q== X-Gm-Gg: AY/fxX7Z0QNuuzTQ+eyCYEINmvtaff271gHl2UBM0I6dpoyjrhQNg4eRsapwlFLDQkv 5N4tBQmC6KBQpwZbIAjWX0kgZxhg8cESKvE0/KkKQ1x+rlK8I9WfJ8kZVCkUHFTrJALqbMM2awW aYq0yRhLVqQ8YOdndEmbJAYHvW3kYbjQmAGVdcRBbotpBxD0h2dQH+Q4RT8p+rr5S0YrXUlrooK 7WA8OuCzudXSfdM3rQCWUHSYhG88GXLHNEkIDn9m6lj/toL9FHSU9hw7FNhpQnvG+CatwlUT3Bg f47rzeHEqId16VwbL7v4SmoCow== X-Received: by 2002:a05:6512:1315:b0:598:8f92:c33e with SMTP id 2adb3069b0e04-59baeeeec45mr1887648e87.50.1768643667233; Sat, 17 Jan 2026 01:54:27 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Jelte Fennema-Nio Date: Sat, 17 Jan 2026 10:54:15 +0100 X-Gm-Features: AZwV_Qh3scMm5ewU9jfIDubhEqqQS1Slw6cc4Jux_uWFlH5RHyAIDCxmiWCgFQo Message-ID: Subject: Re: jsonb subscripting vs SQL/JSON array accessor semantics (SQL:2023) To: Alexandra Wang Cc: PostgreSQL Hackers , Peter Eisentraut Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk 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)