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 1wEkZo-004MLB-1C for pgsql-bugs@arkaria.postgresql.org; Mon, 20 Apr 2026 09:05:56 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wEkZn-001kmW-1C for pgsql-bugs@arkaria.postgresql.org; Mon, 20 Apr 2026 09:05:55 +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 1wEkZn-001kmN-0M for pgsql-bugs@lists.postgresql.org; Mon, 20 Apr 2026 09:05:55 +0000 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wEkZl-000000026e9-0Dss for pgsql-bugs@lists.postgresql.org; Mon, 20 Apr 2026 09:05:54 +0000 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-2b24fcc2b5dso17528675ad.1 for ; Mon, 20 Apr 2026 02:05:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1776675951; cv=none; d=google.com; s=arc-20240605; b=E6xZgSLG5d5YQEAsN+TR8lKTnl5T5i38zBUiIQeleiMYTtvG7VvMIiAz56CAaFEaJO R4jKScvgLKeVOJdNNcTBupKoWYLS53Eos96wkX3/LxVXNy1mRN7zg0dyEY80kWUfkKsP zR8Lyhzb47t8XU3eBc7t9Xjb17p2pl9lZIBU/Cf6ROW/mT9kfZnHJZRY9Qyi5O08XRGN hqUUeHXH9T9g1VGlR03JNc5J13XPLNjHLqtomAcURSEwVwNGSclUMjjOqN+YSZ552cX0 bM/Q/OuY53UVehkRweiifZkzD2WNpMm7zWhH0K5ahD4ibHiPOlpE0xnZR3Cz1Ctk4nhG IHJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=MqaOMJywNHIpsqQ+iDZOhR+aYX+FY2lge3ooP0Ka6yg=; fh=HImoKn+YSHm8+Mju0eJ9hAkHqJhn9FcIV7/wY+ng7M0=; b=f4zIbPmBa7MSfkhQsTWVfHdE3vLWRIErhiyIHTdDfkqQG2fgDy9cP1y0gglX79BAlo 8ZGxbyUckQbg9nFhVIBP53hO6FUEW/+34k5Jn/MRnbyyVTLvth9hDjOvJUoHSWzsiuFH F0DefvJ9PipVom6PEDLRq0qKpqeSMr8yc2hJ5Ns3bxGyfdI7xqIhxowJteSp36ghuJU8 bDapHKNZQ4e7gV+SRrpdWHiIEStlaHwMXaCOadfBe8RoXYtjyMJQuUVDUMCHsQO+Qlu8 KMqpVIf8AFxpvn94lc+e1/dePggSU4zZIUd2Q+Q6jADQLxi3eCiiBUQsdZ6p2Us+lvEV abcA==; 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=20251104; t=1776675951; x=1777280751; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=MqaOMJywNHIpsqQ+iDZOhR+aYX+FY2lge3ooP0Ka6yg=; b=KSWepRd68+pmMp1BpqpujjJrPOg/voknYWLkKABuSiBUAc9TALfS2Q29Lov1kY+r4R xUTp5+lszB1cV57Wij+89jGwCSB1foRAJVamDzHxBHNmWEP+RuN438Dip6LdcsmNwnhw E6OxY7kJW920JDvvfkuz1J76VHNaYOBTk3AT1q/ynsJnmfEOngQNL3txL6biZZDF6ibH 5uYnKgudX2Yj9RtiTDQC6eoE6epN3HfrH60xYpiNT58Xf+xD9CWlyVTncyQcJ674CvG/ a5TzZIbR26DdlKj8kybuf3Zwqj9zehrKjMosyBznIDbllY4YPqhtwvCg7gdP1w+mzqKN YzOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776675951; x=1777280751; h=content-transfer-encoding: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=MqaOMJywNHIpsqQ+iDZOhR+aYX+FY2lge3ooP0Ka6yg=; b=CKZRy7/YwUTXISLqYuMGGdX2nkDQjjxM/qALVPe+aJ0G8d/AGPqarD112MCUP7F6xA Jcouxw8iVdNWPy8BLKCkLgrgqOzSzkma9WOIu0uc9lpvkdH8OTOhfWFAAsJymBzEO56n ps5Vmm/5P2ZQf1ec5OmkJJ5gUFSTEXwy4R6xS60G8EnDNPYH2yuOm4r5Ma+ygVm8Lz4l utKfEguHZaEwzOV4tQplJEQ1s515WeOHlu7o1cVuNZEZbtpbdDDeGg+YQi8rIxS0p0Qh bxcc9Ew61+OLQ79SMpI8bhlU73ftj7yNXUZn7DPRnXKcs7YnA7Nw4oHBULXtM9Pc+kqd E4Yw== X-Forwarded-Encrypted: i=1; AFNElJ+A453NhJNp46gz88ZDZM5MKHrVFtHhESE7E0XlB5e+jkWZwie3Rd2mFHnZNh4qEq7kJIdv+YJWiBXn@lists.postgresql.org X-Gm-Message-State: AOJu0Yxj35IFnXylfyNr8TUCxTV35h9Cs/J/40aCyv2gkDVZblM5FIDE itFVlI0AXDHpepsk7z/SGrngIUgg5F/87SUHDWFTakwgJ9lqVX3Y+ospOPlNkekCYs5rZnPxV6B y+JEf+cqpWU5gcGoJn7EwRIJ/OXzN32JqQrrF X-Gm-Gg: AeBDiet1uY2Y4a/AjKbBZWAjtyx+/WtakQSqeRXLvOzsAk5L/1PQOzBwAAJChTboOkI CGFta3N455tXOEFzZv9NhgGjpERrDZ7SV8csj/ScOy0sttPfxxZHxfkH+4BCrs5+5oxQCU0n85X Jdzi0fT8U7eXkr+LnhYRESR0xwmfnFjjMwhfuoYsUkryFSDdybNuMtym9PjdwrzAdg8DWjb5Lxl yaceOl2IBP+pvICp3BdQvP6+AoYpuxHNAN2k9G2smA5KvHq/ram6eE4BMCEQ+z/lUMlN5qGBZ3R YBcv39By1wdv82LvAk/TXJvwGFOo0zcsWr+U5nvT9m4CdCKSGLiP5KsQoXsdyZ9oufEJkDlGD9A = X-Received: by 2002:a17:903:3905:b0:2b0:7e4d:f43f with SMTP id d9443c01a7336-2b5f9ffe73amr122128655ad.41.1776675950936; Mon, 20 Apr 2026 02:05:50 -0700 (PDT) MIME-Version: 1.0 References: <19418-591ba1f29862ef5b@postgresql.org> <2abdb464-27f5-4759-bb0b-f09ab5b5ceab@postgresfriends.org> <501040.1772433449@sss.pgh.pa.us> In-Reply-To: From: Amit Langote Date: Mon, 20 Apr 2026 18:05:33 +0900 X-Gm-Features: AQROBzDxHOnyFtl-pX_bRFQbhJ0hGqqG6-qKne7-eeuCu59qMuHMTXlnDJeKzoo Message-ID: Subject: Re: BUG #19418: SQL/JSON JSON_VALUE() does not conform to ISO/IEC 9075-2:2023(E) 6.34 To: Richard Guo Cc: Tom Lane , Vik Fearing , lukas.eder@gmail.com, pgsql-bugs@lists.postgresql.org, =?UTF-8?Q?=C3=81lvaro_Herrera?= Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Richard, On Thu, Apr 16, 2026 at 3:05=E2=80=AFPM Richard Guo wrote: > On Tue, Mar 3, 2026 at 11:32=E2=80=AFPM Richard Guo wrote: > > On Tue, Mar 3, 2026 at 10:03=E2=80=AFAM Richard Guo wrote: > > > That is a good point I hadn't considered. So I think the ideal fix i= s > > > to have the parser preserve the user's original JSON_ARRAY(query) > > > syntax as much as possible, and then defer the JSON_ARRAYAGG rewrite > > > trick to the planner, perhaps during expression preprocessing. > > > I tried hacking on this idea to see how it would look in practice, and > > here is what I got. > > After a second look at this approach, I don't like it very much. It > manually constructed the new querytree, including Aggref, > RangeTblEntry, and JsonConstructorExpr nodes, during planning, > bypassing parse analysis entirely. This is essentially repeating the > parser's work by hand in the planner, which is fragile and prone to > failing to handle all cases correctly. > > Maybe a simpler way is to keep the JSON_ARRAYAGG rewrite trick in the > parser, as the current master does, but wrap the result in a COALESCE > to handle the empty-set case. We can preserve a copy of the user's > original subquery in a new field of JsonConstructorExpr, and then > ruleutils.c can use this field to deparse the original > JSON_ARRAY(SELECT ...) syntax for view definitions. You may think > this would introduce extra transform work, but it wouldn't: the > current master already transforms the original subquery to validate > the single-column constraint, then throws the result away. We simply > keep it instead. > > I tried this idea and ended up with the attached. Agreed that v4 is the better direction. A couple of minor nits. The comment on orig_query could say "not walked" a bit more helpfully, e.g. Node *orig_query; /* for deparse only; not walked (func is) */ I also noticed that the comment for 'func' is incomplete as it is and this change warrants an update. Maybe a bit long, but how about: Expr *func; /* expression producing the result: * Aggref/WindowFunc for *AGG, * CoalesceExpr for ARRAY_QUERY, * json[b]_xxx() call for remaining types *= / --=20 Thanks, Amit Langote